diff options
author | Ian Munsie <imunsie@au1.ibm.com> | 2015-01-07 16:33:04 +1100 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2015-01-12 16:40:02 +1100 |
commit | 0712dc7e73e59d79bcead5d5520acf4e9e917e87 (patch) | |
tree | 21268708a21b85d54a9752c27575d473f78c3329 /drivers/misc/cxl/file.c | |
parent | bfe5fda8e7ced129716f5741cf7ed2592a338824 (diff) | |
download | lwn-0712dc7e73e59d79bcead5d5520acf4e9e917e87.tar.gz lwn-0712dc7e73e59d79bcead5d5520acf4e9e917e87.zip |
cxl: Fix issues when unmapping contexts
An issue was introduced with "cxl: Unmap MMIO regions when detaching a
context" (b123429e6a9e8d03aacf888d23262835f0081448) where closing a
context normally could also unmap the problem state area of other
contexts currently using the AFU.
It was also discovered that after a context's MMIO space had been
unmapped it would read 0s when accessing it, whereas the expected
behaviour was for the access to fail altogether.
In order to address these issues, this patch does two things:
- Forced mmap unmapping is only done when we are forcefully detaching
all contexts, and not in the normal detach path. Since the normal
context close path is tied to the file release any mmaps must have
already been released so we don't need to worry in that case.
- The mmap path now uses a vm_operations_struct with a fault handler.
The fault handler ensures that the context is in started state,
otherwise it fails the access attempt with a SIGBUS.
Fixes: b123429e6a9e ("cxl: Unmap MMIO regions when detaching a context")
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'drivers/misc/cxl/file.c')
-rw-r--r-- | drivers/misc/cxl/file.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index e9f2f10dbb37..b15d8113877c 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -140,18 +140,20 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, pr_devel("%s: pe: %i\n", __func__, ctx->pe); - mutex_lock(&ctx->status_mutex); - if (ctx->status != OPENED) { - rc = -EIO; - goto out; - } - + /* Do this outside the status_mutex to avoid a circular dependency with + * the locking in cxl_mmap_fault() */ if (copy_from_user(&work, uwork, sizeof(struct cxl_ioctl_start_work))) { rc = -EFAULT; goto out; } + mutex_lock(&ctx->status_mutex); + if (ctx->status != OPENED) { + rc = -EIO; + goto out; + } + /* * if any of the reserved fields are set or any of the unused * flags are set it's invalid |