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();
 }
 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)
 {
 
        bool pe_inserted;
        bool master;
        bool kernel;
+       bool real_mode;
        bool pending_irq;
        bool pending_fault;
        bool pending_afu_err;
 
 {
        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);
 
        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);
 
  */
 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.