cxl: fix setting of _PAGE_USER bit when handling page faults
Michael Ellerman
mpe at ellerman.id.au
Fri Mar 25 21:01:38 AEDT 2016
On Fri, 2016-18-03 at 04:01:21 UTC, Andrew Donnellan wrote:
> When handling page faults, cxl_handle_page_fault() checks whether the page
> should be accessible by userspace and have its _PAGE_USER access bit set.
> _PAGE_USER should be set if the context's kernel flag isn't set, or if the
> page falls outside of kernel memory.
>
> However, the check currently uses the wrong operator, causing it to always
> evalute to true. As such, we always set the _PAGE_USER bit, even when it
> should be restricted to the kernel.
>
> Fix the check so that the _PAGE_USER bit is set only as intended.
>
..
> diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
> index 9a8650b..a76cb8a 100644
> --- a/drivers/misc/cxl/fault.c
> +++ b/drivers/misc/cxl/fault.c
> @@ -152,7 +152,7 @@ static void cxl_handle_page_fault(struct cxl_context *ctx,
> access = _PAGE_PRESENT;
> if (dsisr & CXL_PSL_DSISR_An_S)
> access |= _PAGE_RW;
> - if ((!ctx->kernel) || ~(dar & (1ULL << 63)))
> + if ((!ctx->kernel) || !(dar & (1ULL << 63)))
> access |= _PAGE_USER;
I think you can (should) use is_kernel_addr() for the DAR check.
I'm also slightly worried by that logic in the case of a non-kernel context.
ie. if ctx->kernel is false, we get:
if (true || !is_kernel_addr(dar))
access |= _PAGE_USER;
Which means we just add _PAGE_USER for any address. What am I missing here?
cheers
More information about the Linuxppc-dev
mailing list