aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Munsie <imunsie@au1.ibm.com>2016-05-06 03:46:36 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2016-05-11 07:54:10 -0400
commit7a0d85d313c2066712e530e668bc02bb741a685c (patch)
treeb097194d6a8a1b8144efe32dc2222558dd64626f
parent3c206fa77aaaac8cd7d4cfcd840c82495b01b288 (diff)
cxl: Add kernel API to allow a context to operate with relocate disabled
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>
-rw-r--r--drivers/misc/cxl/api.c19
-rw-r--r--drivers/misc/cxl/cxl.h1
-rw-r--r--drivers/misc/cxl/guest.c3
-rw-r--r--drivers/misc/cxl/native.c5
-rw-r--r--include/misc/cxl.h8
5 files changed, 34 insertions, 2 deletions
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
index 807582335a98..6d228ccd884d 100644
--- a/drivers/misc/cxl/api.c
+++ b/drivers/misc/cxl/api.c
@@ -183,6 +183,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
183 ctx->pid = get_task_pid(task, PIDTYPE_PID); 183 ctx->pid = get_task_pid(task, PIDTYPE_PID);
184 ctx->glpid = get_task_pid(task->group_leader, PIDTYPE_PID); 184 ctx->glpid = get_task_pid(task->group_leader, PIDTYPE_PID);
185 kernel = false; 185 kernel = false;
186 ctx->real_mode = false;
186 } 187 }
187 188
188 cxl_ctx_get(); 189 cxl_ctx_get();
@@ -219,6 +220,24 @@ void cxl_set_master(struct cxl_context *ctx)
219} 220}
220EXPORT_SYMBOL_GPL(cxl_set_master); 221EXPORT_SYMBOL_GPL(cxl_set_master);
221 222
223int cxl_set_translation_mode(struct cxl_context *ctx, bool real_mode)
224{
225 if (ctx->status == STARTED) {
226 /*
227 * We could potentially update the PE and issue an update LLCMD
228 * to support this, but it doesn't seem to have a good use case
229 * since it's trivial to just create a second kernel context
230 * with different translation modes, so until someone convinces
231 * me otherwise:
232 */
233 return -EBUSY;
234 }
235
236 ctx->real_mode = real_mode;
237 return 0;
238}
239EXPORT_SYMBOL_GPL(cxl_set_translation_mode);
240
222/* wrappers around afu_* file ops which are EXPORTED */ 241/* wrappers around afu_* file ops which are EXPORTED */
223int cxl_fd_open(struct inode *inode, struct file *file) 242int cxl_fd_open(struct inode *inode, struct file *file)
224{ 243{
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 2823fb32fcf6..9dd3a0e7917f 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -514,6 +514,7 @@ struct cxl_context {
514 bool pe_inserted; 514 bool pe_inserted;
515 bool master; 515 bool master;
516 bool kernel; 516 bool kernel;
517 bool real_mode;
517 bool pending_irq; 518 bool pending_irq;
518 bool pending_fault; 519 bool pending_fault;
519 bool pending_afu_err; 520 bool pending_afu_err;
diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
index 769971c065b4..c2815b97de2e 100644
--- a/drivers/misc/cxl/guest.c
+++ b/drivers/misc/cxl/guest.c
@@ -617,6 +617,9 @@ static int guest_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u
617{ 617{
618 pr_devel("in %s\n", __func__); 618 pr_devel("in %s\n", __func__);
619 619
620 if (ctx->real_mode)
621 return -EPERM;
622
620 ctx->kernel = kernel; 623 ctx->kernel = kernel;
621 if (ctx->afu->current_mode == CXL_MODE_DIRECTED) 624 if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
622 return attach_afu_directed(ctx, wed, amr); 625 return attach_afu_directed(ctx, wed, amr);
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 5d4fb9fd84bc..98f2cac45162 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -494,8 +494,9 @@ static u64 calculate_sr(struct cxl_context *ctx)
494 if (mfspr(SPRN_LPCR) & LPCR_TC) 494 if (mfspr(SPRN_LPCR) & LPCR_TC)
495 sr |= CXL_PSL_SR_An_TC; 495 sr |= CXL_PSL_SR_An_TC;
496 if (ctx->kernel) { 496 if (ctx->kernel) {
497 sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF); 497 if (!ctx->real_mode)
498 sr |= CXL_PSL_SR_An_HV; 498 sr |= CXL_PSL_SR_An_R;
499 sr |= (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV;
499 } else { 500 } else {
500 sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R; 501 sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
501 sr &= ~(CXL_PSL_SR_An_HV); 502 sr &= ~(CXL_PSL_SR_An_HV);
diff --git a/include/misc/cxl.h b/include/misc/cxl.h
index 7d5e2613c7b8..56560c5781b4 100644
--- a/include/misc/cxl.h
+++ b/include/misc/cxl.h
@@ -127,6 +127,14 @@ int cxl_afu_reset(struct cxl_context *ctx);
127void cxl_set_master(struct cxl_context *ctx); 127void cxl_set_master(struct cxl_context *ctx);
128 128
129/* 129/*
130 * Sets the context to use real mode memory accesses to operate with
131 * translation disabled. Note that this only makes sense for kernel contexts
132 * under bare metal, and will not work with virtualisation. May only be
133 * performed on stopped contexts.
134 */
135int cxl_set_translation_mode(struct cxl_context *ctx, bool real_mode);
136
137/*
130 * Map and unmap the AFU Problem Space area. The amount and location mapped 138 * Map and unmap the AFU Problem Space area. The amount and location mapped
131 * depends on if this context is a master or slave. 139 * depends on if this context is a master or slave.
132 */ 140 */