qemu-ppc
[Top][All Lists]
Advanced

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

[Qemu-ppc] [PATCH 5/5] target-ppc: Handle cases when multi-processors ge


From: Aravinda Prasad
Subject: [Qemu-ppc] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check
Date: Mon, 25 Aug 2014 19:15:54 +0530
User-agent: StGit/0.15

It is possible for multi-processors to experience machine
check at or about the same time. As per PAPR, subsequent
processors serialize waiting for the first processor to
issue the ibm,nmi-interlock call.

The second processor retries if the first processor which
received a machine check is still reading the error log
and is yet to issue ibm,nmi-interlock call.

This patch implements this functionality.

Signed-off-by: Aravinda Prasad <address@hidden>
---
 hw/ppc/spapr_hcall.c |   13 +++++++++++++
 hw/ppc/spapr_rtas.c  |    8 +++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index be063f4..542d0b7 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -94,6 +94,9 @@ struct rtas_mc_log {
     struct rtas_error_log err_log;
 };
 
+/* Whether machine check handling is in progress by any CPU */
+bool mc_in_progress;
+
 static void do_spr_sync(void *arg)
 {
     struct SPRSyncState *s = arg;
@@ -674,6 +677,16 @@ static target_ulong h_report_mc_err(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
 
     /*
+     * No need for lock. Only one thread can be executing
+     * inside an hcall
+     */
+    if (mc_in_progress == 1) {
+        return 0;
+    }
+
+    mc_in_progress = 1;
+
+    /*
      * We save the original r3 register in SPRG2 in 0x200 vector,
      * which is patched during call to ibm.nmi-register. Original
      * r3 is required to be included in error log
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 1135d2b..8fe4db2 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -36,6 +36,8 @@
 
 #include <libfdt.h>
 
+extern bool mc_in_progress;
+
 static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                    uint32_t token, uint32_t nargs,
                                    target_ulong args,
@@ -303,6 +305,9 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
         0x6063f004,    /* ori     r3,r3,f004  */
         /* Issue H_CALL */
         0x44000022,    /*  sc      1     */
+        0x2fa30000,    /* cmplwi r3,0 */
+        0x409e0008,    /* bne continue */
+        0x4800020a,    /* retry KVMPPC_H_REPORT_ERR */
         0x7c9243a6,    /* mtspr r4 sprg2 */
         0xe8830000,    /* ld r4, 0(r3) */
         0x7c9a03a6,    /* mtspr r4, srr0 */
@@ -333,7 +338,7 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
      * machine check address requested by OS
      */
     branch_inst |= guest_machine_check_addr;
-    memcpy(&trampoline[11], &branch_inst, sizeof(branch_inst));
+    memcpy(&trampoline[14], &branch_inst, sizeof(branch_inst));
 
     /* Handle all Host/Guest LE/BE combinations */
     if ((*pcc->interrupts_big_endian)(cpu)) {
@@ -359,6 +364,7 @@ static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
                                    target_ulong args,
                                    uint32_t nret, target_ulong rets)
 {
+    mc_in_progress = 0;
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 




reply via email to

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