Skip to content

Commit

Permalink
cxl: Fix force unmapping mmaps of contexts allocated through the kern…
Browse files Browse the repository at this point in the history
…el 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 <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
  • Loading branch information
Ian Munsie authored and mpe committed Aug 30, 2015
1 parent af2a50b commit 55e0766
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
33 changes: 30 additions & 3 deletions drivers/misc/cxl/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
#include <linux/anon_inodes.h>
#include <linux/file.h>
#include <misc/cxl.h>
#include <linux/fs.h>

#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;
Expand All @@ -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:
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions drivers/misc/cxl/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions drivers/misc/cxl/cxl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 55e0766

Please sign in to comment.