]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
cxl: Add kernel API to allow a context to operate with relocate disabled
authorIan Munsie <imunsie@au1.ibm.com>
Fri, 6 May 2016 07:46:36 +0000 (17:46 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 11 May 2016 11:54:10 +0000 (21:54 +1000)
cxl devices typically access memory using an MMU in much the same way as
the CPU, and each context includes a state register much like the MSR in
the CPU. Like the CPU, the state register includes a bit to enable
relocation, which we currently always enable.

In some cases, it may be desirable to allow a device to access memory
using real addresses instead of effective addresses, so this adds a new
API, cxl_set_translation_mode, that can be used to disable relocation
on a given kernel context. This can allow for the creation of a special
privileged context that the device can use if it needs relocation
disabled, and can use regular contexts at times when it needs relocation
enabled.

This interface is only available to users of the kernel API for obvious
reasons, and will never be supported in a virtualised environment.

This will be used by the upcoming cxl support in the mlx5 driver.

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
drivers/misc/cxl/api.c
drivers/misc/cxl/cxl.h
drivers/misc/cxl/guest.c
drivers/misc/cxl/native.c
include/misc/cxl.h

index 807582335a9848e2dc8c9f0eedb80105b5dc6fae..6d228ccd884d14d1eebb46ba5a02c3830ea787bd 100644 (file)
@@ -183,6 +183,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
                ctx->pid = get_task_pid(task, PIDTYPE_PID);
                ctx->glpid = get_task_pid(task->group_leader, PIDTYPE_PID);
                kernel = false;
+               ctx->real_mode = false;
        }
 
        cxl_ctx_get();
@@ -219,6 +220,24 @@ void cxl_set_master(struct cxl_context *ctx)
 }
 EXPORT_SYMBOL_GPL(cxl_set_master);
 
+int cxl_set_translation_mode(struct cxl_context *ctx, bool real_mode)
+{
+       if (ctx->status == STARTED) {
+               /*
+                * We could potentially update the PE and issue an update LLCMD
+                * to support this, but it doesn't seem to have a good use case
+                * since it's trivial to just create a second kernel context
+                * with different translation modes, so until someone convinces
+                * me otherwise:
+                */
+               return -EBUSY;
+       }
+
+       ctx->real_mode = real_mode;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(cxl_set_translation_mode);
+
 /* wrappers around afu_* file ops which are EXPORTED */
 int cxl_fd_open(struct inode *inode, struct file *file)
 {
index 2823fb32fcf61c4e04cde66a93dbb0ee1d2a8ba4..9dd3a0e7917f5fbb590856a2a4996ff4bc739e57 100644 (file)
@@ -514,6 +514,7 @@ struct cxl_context {
        bool pe_inserted;
        bool master;
        bool kernel;
+       bool real_mode;
        bool pending_irq;
        bool pending_fault;
        bool pending_afu_err;
index 769971c065b4cdb3ba9945647b092841a7d83346..c2815b97de2eef4d5d0089a4c7f1990f3fb38ee2 100644 (file)
@@ -617,6 +617,9 @@ static int guest_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u
 {
        pr_devel("in %s\n", __func__);
 
+       if (ctx->real_mode)
+               return -EPERM;
+
        ctx->kernel = kernel;
        if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
                return attach_afu_directed(ctx, wed, amr);
index 5d4fb9fd84bce85e5e5ae3f4da9af16961ad648f..98f2cac45162548d3ed8a7245055c1e90a8cb089 100644 (file)
@@ -494,8 +494,9 @@ static u64 calculate_sr(struct cxl_context *ctx)
        if (mfspr(SPRN_LPCR) & LPCR_TC)
                sr |= CXL_PSL_SR_An_TC;
        if (ctx->kernel) {
-               sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF);
-               sr |= CXL_PSL_SR_An_HV;
+               if (!ctx->real_mode)
+                       sr |= CXL_PSL_SR_An_R;
+               sr |= (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV;
        } else {
                sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
                sr &= ~(CXL_PSL_SR_An_HV);
index 7d5e2613c7b803932f9a9f587d46b83690550ef8..56560c5781b466cd676ad9a8ea1a65a1a16afb7c 100644 (file)
@@ -126,6 +126,14 @@ int cxl_afu_reset(struct cxl_context *ctx);
  */
 void cxl_set_master(struct cxl_context *ctx);
 
+/*
+ * Sets the context to use real mode memory accesses to operate with
+ * translation disabled. Note that this only makes sense for kernel contexts
+ * under bare metal, and will not work with virtualisation. May only be
+ * performed on stopped contexts.
+ */
+int cxl_set_translation_mode(struct cxl_context *ctx, bool real_mode);
+
 /*
  * Map and unmap the AFU Problem Space area. The amount and location mapped
  * depends on if this context is a master or slave.