qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-ppc] [RFC NO-MERGE 07/12] target/ppc: Implement H_REGISTER_PROCESS


From: Suraj Jitindar Singh
Subject: [Qemu-ppc] [RFC NO-MERGE 07/12] target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL for tcg guests
Date: Fri, 17 Feb 2017 16:08:07 +1100

The H_REGISTER_PROCESS_TABLE H_CALL is used by a guest to indicate to the
hypervisor where in memory its process table is and how translation should
be performed using this process table.

Provide the implementation of this H_CALL for a tcg guest. If called by a
KVM guest it will return H_FUNCTION for now with //TODO markers where code
should be added to implement the required functionality.

We first check for invalid flags, then parse the flags to determine the
operation, and then check the other parameters for valid values based on
the operation (register new table/deregister table/maintain registration).
The process table is then stored in the appropriate location, and the
LPCR_[UPRT/GTSE] bits are updated as required.

Signed-off-by: Suraj Jitindar Singh <address@hidden>
---
 hw/ppc/spapr_hcall.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 61 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 7afedbd..bf80543 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -12,6 +12,7 @@
 #include "trace.h"
 #include "kvm_ppc.h"
 #include "hw/ppc/spapr_ovec.h"
+#include "mmu.h"
 
 struct SPRSyncState {
     int spr;
@@ -902,9 +903,66 @@ static target_ulong h_register_process_table(PowerPCCPU 
*cpu,
                                              target_ulong opcode,
                                              target_ulong *args)
 {
-    qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x" TARGET_FMT_lx 
"%s\n",
-                  opcode, " (H_REGISTER_PROC_TBL)");
-    return H_FUNCTION;
+    CPUPPCState *env = &cpu->env;
+    target_ulong flags = args[0];
+    target_ulong proc_tbl = args[1];
+    target_ulong page_size = args[2];
+    target_ulong table_size = args[3];
+    uint64_t cproc = spapr->patb_entry; /* Get the current table */
+
+    if (flags & ~0x1fULL) { /* Check no reserved bits are set */
+        return H_PARAMETER;
+    } else if (!(flags & 0x10)) { /* Maintain current registration */
+        if (!!(flags & 0x4) ^ !!(cproc & PATBE1_GR)) {
+            return H_PARAMETER; /* Existing Process Table Mismatch */
+       }
+    } else if (!(flags & 0x8)) { /* Deregister current process table */
+        if (kvm_enabled()) {
+            // TODO - how does kvm handle deregistration?
+           return H_FUNCTION;
+        } else {
+            cproc = 0x0ULL; /* Set to benign value - 0 works */
+        }
+    } else if (flags & 0x4) { /* Register new RADIX process table */
+        if (proc_tbl & 0xfff || proc_tbl >> 60) {
+            return H_P2;
+        } else if (page_size) {
+            return H_P3;
+        } else if (table_size > 24) {
+            return H_P4;
+        }
+        cproc = PATBE1_GR | proc_tbl | table_size;
+       // TODO
+       // Free HTAB if non-null
+    } else { /* Register new HPT process table */
+        if (proc_tbl >> 38) {
+            return H_P2;
+        } else if (page_size & ~0x7) {
+             return H_P3;
+        } else if (table_size > 24) {
+            return H_P4;
+        }
+        cproc = (proc_tbl << 25) | page_size << 5 | table_size;
+    }
+
+    if (kvm_enabled()) {
+        // TODO - kvmppc_configure_v3_mmu()
+       return H_FUNCTION;
+    } else {
+        spapr->patb_entry = cproc; /* Save new process table */
+        if (flags & 0x6) { /* Partition Uses Process Tables */
+            env->spr[SPR_LPCR] |= LPCR_UPRT;
+       } else {
+            env->spr[SPR_LPCR] &= ~LPCR_UPRT;
+       }
+       if (flags & 0x1) { /* Partition Uses Guest Translation Shootdown */
+            env->spr[SPR_LPCR] |= LPCR_GTSE;
+        } else {
+            env->spr[SPR_LPCR] &= ~LPCR_GTSE;
+        }
+    }
+
+    return H_SUCCESS;
 }
 
 #define H_SIGNAL_SYS_RESET_ALL         -1
-- 
2.5.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]