qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 3/3] ppc/spapr: implement H_SIGNAL_SYS_RESET


From: Nicholas Piggin
Subject: [Qemu-devel] [PATCH 3/3] ppc/spapr: implement H_SIGNAL_SYS_RESET
Date: Thu, 20 Oct 2016 17:59:12 +1100

The H_SIGNAL_SYS_RESET hcall allows a guest CPU to raise a system
reset exception on other CPUs in the same guest.

Signed-off-by: Nicholas Piggin <address@hidden>
---
 hw/ppc/spapr_hcall.c   | 42 ++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h |  8 +++++++-
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index c5e7e8c..5ae84f0 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -880,6 +880,47 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
     return ret;
 }
 
+static void do_sys_reset(CPUState *cs, void *arg)
+{
+    cpu_synchronize_state(cs);
+    ppc_cpu_do_system_reset(cs);
+}
+
+static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
+                                       sPAPRMachineState *spapr,
+                                       target_ulong opcode, target_ulong *args)
+{
+    target_long target = args[0];
+    CPUState *cs;
+
+    if (target < H_SIGNAL_SYS_RESET_ALLBUTSELF) {
+        return H_PARAMETER;
+    }
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *c = POWERPC_CPU(cs);
+
+        if (cpu->cpu_dt_id == target) {
+            run_on_cpu(cs, do_sys_reset, NULL);
+            return H_SUCCESS;
+        }
+
+        if (target == H_SIGNAL_SYS_RESET_ALLBUTSELF) {
+            if (c == cpu) {
+                continue;
+            }
+        }
+
+        run_on_cpu(cs, do_sys_reset, NULL);
+    }
+
+    if (target >= 0) {
+        return H_PARAMETER;
+    }
+
+    return H_SUCCESS;
+}
+
 /*
  * Return the offset to the requested option vector @vector in the
  * option vector table @table.
@@ -1113,6 +1154,7 @@ static void hypercall_register_types(void)
     /* hcall-splpar */
     spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa);
     spapr_register_hypercall(H_CEDE, h_cede);
+    spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset);
 
     /* processor register resource access h-calls */
     spapr_register_hypercall(H_SET_SPRG0, h_set_sprg0);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index aeaba3e..a28538b 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -339,7 +339,13 @@ struct sPAPRMachineState {
 #define H_XIRR_X                0x2FC
 #define H_RANDOM                0x300
 #define H_SET_MODE              0x31C
-#define MAX_HCALL_OPCODE        H_SET_MODE
+#define H_SIGNAL_SYS_RESET      0x380
+#define MAX_HCALL_OPCODE        H_SIGNAL_SYS_RESET
+
+/* Parameters to H_SIGNAL_SYS_RESET */
+#define H_SIGNAL_SYS_RESET_ALL         -1
+#define H_SIGNAL_SYS_RESET_ALLBUTSELF  -2
+
 
 /* The hcalls above are standardized in PAPR and implemented by pHyp
  * as well.
-- 
2.9.3




reply via email to

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