From 13e68d8bd05c998cae452a4f3400af1e8edd852e Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Fri, 14 Aug 2015 17:41:25 +1000 Subject: cxl: Allow the kernel to trust that an image won't change on PERST. Provide a kernel API and a sysfs entry which allow a user to specify that when a card is PERSTed, it's image will stay the same, allowing it to participate in EEH. cxl_reset is used to reflash the card. In that case, we cannot safely assert that the image will not change. Therefore, disallow cxl_reset if the flag is set. Signed-off-by: Daniel Axtens Signed-off-by: Michael Ellerman --- drivers/misc/cxl/api.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/misc/cxl/api.c') diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index 729e0851167d..6a768a9ad22f 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c @@ -327,3 +327,10 @@ int cxl_afu_reset(struct cxl_context *ctx) return cxl_afu_check_and_enable(afu); } EXPORT_SYMBOL_GPL(cxl_afu_reset); + +void cxl_perst_reloads_same_image(struct cxl_afu *afu, + bool perst_reloads_same_image) +{ + afu->adapter->perst_same_image = perst_reloads_same_image; +} +EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image); -- cgit v1.2.3 From 7c26b9cf5347c24272152438cdd9675183804425 Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Wed, 19 Aug 2015 09:27:18 +1000 Subject: cxl: Allow release of contexts which have been OPENED but not STARTED If we open a context but do not start it (either because we do not attempt to start it, or because it fails to start for some reason), we are left with a context in state OPENED. Previously, cxl_release_context() only allowed releasing contexts in state CLOSED, so attempting to release an OPENED context would fail. In particular, this bug causes available contexts to run out after some EEH failures, where drivers attempt to release contexts that have failed to start. Allow releasing contexts in any state with a value lower than STARTED, i.e. OPENED or CLOSED (we can't release a STARTED context as it's currently using the hardware, and we assume that contexts in any new states which may be added in future with a value higher than STARTED are also unsafe to release). Cc: stable@vger.kernel.org Fixes: 6f7f0b3df6d4 ("cxl: Add AFU virtual PHB and kernel API") Signed-off-by: Andrew Donnellan Signed-off-by: Daniel Axtens Acked-by: Ian Munsie Signed-off-by: Michael Ellerman --- drivers/misc/cxl/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc/cxl/api.c') diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index 6a768a9ad22f..f49e3e5db58d 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c @@ -59,7 +59,7 @@ EXPORT_SYMBOL_GPL(cxl_get_phys_dev); int cxl_release_context(struct cxl_context *ctx) { - if (ctx->status != CLOSED) + if (ctx->status >= STARTED) return -EBUSY; put_device(&ctx->afu->dev); -- cgit v1.2.3 From af2a50bb0ce1ca7a9c4784813419c922bf2285df Mon Sep 17 00:00:00 2001 From: Ian Munsie Date: Thu, 27 Aug 2015 19:50:18 +1000 Subject: cxl: Fix + cleanup error paths in cxl_dev_context_init If the cxl_context_alloc() call fails, we return immediately without releasing the reference on the AFU device, allowing it to leak. This patch switches to using goto style error handling so that the device is released in common code for both error paths, and will also simplify things if we add additional initialisation in this function in the future. Signed-off-by: Ian Munsie Signed-off-by: Michael Ellerman --- drivers/misc/cxl/api.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers/misc/cxl/api.c') diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index f49e3e5db58d..005adc7d33a2 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c @@ -25,19 +25,24 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev) get_device(&afu->dev); ctx = cxl_context_alloc(); - if (IS_ERR(ctx)) - return ctx; + if (IS_ERR(ctx)) { + rc = PTR_ERR(ctx); + goto err_dev; + } /* Make it a slave context. We can promote it later? */ rc = cxl_context_init(ctx, afu, false, NULL); - if (rc) { - kfree(ctx); - put_device(&afu->dev); - return ERR_PTR(-ENOMEM); - } + if (rc) + goto err_ctx; cxl_assign_psn_space(ctx); return ctx; + +err_ctx: + kfree(ctx); +err_dev: + put_device(&afu->dev); + return ERR_PTR(rc); } EXPORT_SYMBOL_GPL(cxl_dev_context_init); -- cgit v1.2.3 From 55e07668fbba9466e6a9ef7650718356cda38406 Mon Sep 17 00:00:00 2001 From: Ian Munsie Date: Thu, 27 Aug 2015 19:50:19 +1000 Subject: cxl: Fix force unmapping mmaps of contexts allocated through the kernel api The cxl user api uses the address_space associated with the file when we need to force unmap all cxl mmap regions (e.g. on eeh, driver detach, etc). Currently, contexts allocated through the kernel api do not do this and instead skip the mmap invalidation, potentially allowing them to poke at the hardware after such an event, which may cause all sorts of trouble. This patch allocates an address_space for cxl contexts allocated through the kernel api so that the same invalidate path will for these contexts as well. We don't use the anonymous inode's address_space, as doing so could invalidate any mmaps of completely unrelated drivers using anonymous file descriptors. This patch also introduces a kernelapi flag, so we know when freeing the context if the address_space was allocated by us and needs to be freed. Signed-off-by: Ian Munsie Signed-off-by: Michael Ellerman --- drivers/misc/cxl/api.c | 33 ++++++++++++++++++++++++++++++--- drivers/misc/cxl/context.c | 2 ++ drivers/misc/cxl/cxl.h | 1 + 3 files changed, 33 insertions(+), 3 deletions(-) (limited to 'drivers/misc/cxl/api.c') diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index 005adc7d33a2..8af12c884b04 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c @@ -12,11 +12,13 @@ #include #include #include +#include #include "cxl.h" struct cxl_context *cxl_dev_context_init(struct pci_dev *dev) { + struct address_space *mapping; struct cxl_afu *afu; struct cxl_context *ctx; int rc; @@ -30,14 +32,32 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev) goto err_dev; } + ctx->kernelapi = true; + + /* + * Make our own address space since we won't have one from the + * filesystem like the user api has, and even if we do associate a file + * with this context we don't want to use the global anonymous inode's + * address space as that can invalidate unrelated users: + */ + mapping = kmalloc(sizeof(struct address_space), GFP_KERNEL); + if (!mapping) { + rc = -ENOMEM; + goto err_ctx; + } + address_space_init_once(mapping); + /* Make it a slave context. We can promote it later? */ - rc = cxl_context_init(ctx, afu, false, NULL); + rc = cxl_context_init(ctx, afu, false, mapping); if (rc) - goto err_ctx; + goto err_mapping; + cxl_assign_psn_space(ctx); return ctx; +err_mapping: + kfree(mapping); err_ctx: kfree(ctx); err_dev: @@ -260,9 +280,16 @@ struct file *cxl_get_fd(struct cxl_context *ctx, struct file_operations *fops, file = anon_inode_getfile("cxl", fops, ctx, flags); if (IS_ERR(file)) - put_unused_fd(fdtmp); + goto err_fd; + + file->f_mapping = ctx->mapping; + *fd = fdtmp; return file; + +err_fd: + put_unused_fd(fdtmp); + return NULL; } EXPORT_SYMBOL_GPL(cxl_get_fd); diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 941fda04aa9a..e762f85ee233 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c @@ -272,6 +272,8 @@ static void reclaim_ctx(struct rcu_head *rcu) if (ctx->ff_page) __free_page(ctx->ff_page); ctx->sstp = NULL; + if (ctx->kernelapi) + kfree(ctx->mapping); kfree(ctx); } diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index e7af256f60c5..d6566c60bcb0 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -420,6 +420,7 @@ struct cxl_context { struct mutex mapping_lock; struct page *ff_page; bool mmio_err_ff; + bool kernelapi; spinlock_t sste_lock; /* Protects segment table entries */ struct cxl_sste *sstp; -- cgit v1.2.3