All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/5] target-ppc: Add FWNMI support in QEMU for powerKVM guests
@ 2014-08-25 13:45 Aravinda Prasad
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob Aravinda Prasad
                   ` (4 more replies)
  0 siblings, 5 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-25 13:45 UTC (permalink / raw)
  To: aik, qemu-ppc, qemu-devel; +Cc: benh, paulus

This series of patches add support for fwnmi in powerKVM guests.

Currently upon machine check exception, if the address in
error belongs to guest then KVM invokes guest's NMI interrupt
vector 0x200.

This patch series adds functionality where the guest's 0x200
interrupt vector is patched such that QEMU gets control. QEMU
then builds error log and reports the error to OS registered
machine check handlers through RTAS space.

Apart from this, the patch series also takes care of synchronization
when multiple processors encounter machine check at or about the
same time.

The patch set was tested by simulating a machine check error in
the guest.

---

Aravinda Prasad (5):
      target-ppc: Extend rtas-blob
      target-ppc: Register and handle HCALL to receive updated RTAS region
      target-ppc: Build error log
      target-ppc: Handle ibm,nmi-register RTAS call
      target-ppc: Handle cases when multi-processors get machine-check


 hw/ppc/spapr.c                  |   13 ++-
 hw/ppc/spapr_hcall.c            |  168 +++++++++++++++++++++++++++++++++++++++
 hw/ppc/spapr_rtas.c             |  101 +++++++++++++++++++++++
 include/hw/ppc/spapr.h          |   15 +++
 pc-bios/spapr-rtas/spapr-rtas.S |   12 +++
 5 files changed, 301 insertions(+), 8 deletions(-)

-- 
Aravinda Prasad

^ permalink raw reply	[flat|nested] 73+ messages in thread

* [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-25 13:45 [Qemu-devel] [PATCH 0/5] target-ppc: Add FWNMI support in QEMU for powerKVM guests Aravinda Prasad
@ 2014-08-25 13:45 ` Aravinda Prasad
  2014-08-26  5:38   ` David Gibson
                     ` (2 more replies)
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 2/5] target-ppc: Register and handle HCALL to receive updated RTAS region Aravinda Prasad
                   ` (3 subsequent siblings)
  4 siblings, 3 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-25 13:45 UTC (permalink / raw)
  To: aik, qemu-ppc, qemu-devel; +Cc: benh, paulus

Extend rtas-blob to accommodate error log. Error log
structure is saved in rtas space upon a machine check
exception.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c                  |   13 ++++++++++---
 hw/ppc/spapr_rtas.c             |    4 ++--
 include/hw/ppc/spapr.h          |    2 +-
 pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
 4 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d01978f..1120988 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -85,6 +85,12 @@
 
 #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
 
+/*
+ * The rtas-entry-offset should match the value specified in
+ * spapr-rtas.S
+ */
+#define RTAS_ENTRY_OFFSET       0x1000
+
 typedef struct sPAPRMachineState sPAPRMachineState;
 
 #define TYPE_SPAPR_MACHINE      "spapr-machine"
@@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
 static void spapr_finalize_fdt(sPAPREnvironment *spapr,
                                hwaddr fdt_addr,
                                hwaddr rtas_addr,
-                               hwaddr rtas_size)
+                               hwaddr rtas_size,
+                               hwaddr rtas_entry)
 {
     int ret, i;
     size_t cb = 0;
@@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
     }
 
     /* RTAS */
-    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
+    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
     if (ret < 0) {
         fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
     }
@@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
 
     /* Load the fdt */
     spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
-                       spapr->rtas_size);
+                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
 
     /* Set up the entry state */
     first_ppc_cpu = POWERPC_CPU(first_cpu);
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 9ba1ba6..02ddbf9 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
 }
 
 int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
-                                 hwaddr rtas_size)
+                                 hwaddr rtas_size, hwaddr rtas_entry)
 {
     int ret;
     int i;
@@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
     }
 
     ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
-                                rtas_addr);
+                                rtas_entry);
     if (ret < 0) {
         fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
                 fdt_strerror(ret));
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index bbba51a..dedfa67 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                              uint32_t token, uint32_t nargs, target_ulong args,
                              uint32_t nret, target_ulong rets);
 int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
-                                 hwaddr rtas_size);
+                                 hwaddr rtas_size, hwaddr rtas_entry);
 
 #define SPAPR_TCE_PAGE_SHIFT   12
 #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
index 903bec2..8c9b17e 100644
--- a/pc-bios/spapr-rtas/spapr-rtas.S
+++ b/pc-bios/spapr-rtas/spapr-rtas.S
@@ -30,6 +30,18 @@
 
 .globl	_start
 _start:
+	/*
+	 * Reserve space for error log in RTAS blob.
+	 *
+	 * Either we can reserve initial bytes for error log followed by
+	 * rtas-entry or space can be reserved after rtas-entry. I prefer
+	 * former, as we already have rtas-base and rtas-entry (currently
+	 * both pointing to rtas-base) defined in qemu and we can update
+	 * rtas-entry to point to an offset from rtas-base. This avoids
+	 * unnecessary definition of rtas-error-offset while keeping
+	 * rtas-entry redundant.
+	 */
+	. = 0x1000
 	mr	4,3
 	lis	3,KVMPPC_H_RTAS@h
 	ori	3,3,KVMPPC_H_RTAS@l

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [Qemu-devel] [PATCH 2/5] target-ppc: Register and handle HCALL to receive updated RTAS region
  2014-08-25 13:45 [Qemu-devel] [PATCH 0/5] target-ppc: Add FWNMI support in QEMU for powerKVM guests Aravinda Prasad
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob Aravinda Prasad
@ 2014-08-25 13:45 ` Aravinda Prasad
  2014-08-26  5:39   ` David Gibson
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 3/5] target-ppc: Build error log Aravinda Prasad
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-25 13:45 UTC (permalink / raw)
  To: aik, qemu-ppc, qemu-devel; +Cc: benh, paulus

Receive updates from SLOF about the updated rtas-base.
A separate patch for SLOF [1] adds functionality to invoke a
a private HCALL whenever OS issues instantiate-rtas with
a new rtas-base.

This is required as qemu needs to know the updated rtas-base
as it allocates error reporting structure in RTAS space upon
a machine check exception.

[1] https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-August/120386.html

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 hw/ppc/spapr_hcall.c   |    8 ++++++++
 include/hw/ppc/spapr.h |    3 ++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 467858c..118ee77 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -579,6 +579,13 @@ static target_ulong h_rtas(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                            nret, rtas_r3 + 12 + 4*nargs);
 }
 
+static target_ulong h_rtas_update(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+                                  target_ulong opcode, target_ulong *args)
+{
+    spapr->rtas_addr = args[0];
+    return 0;
+}
+
 static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                    target_ulong opcode, target_ulong *args)
 {
@@ -1003,6 +1010,7 @@ static void hypercall_register_types(void)
 
     /* qemu/KVM-PPC specific hcalls */
     spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
+    spapr_register_hypercall(KVMPPC_H_RTAS_UPDATE, h_rtas_update);
 
     spapr_register_hypercall(H_SET_MODE, h_set_mode);
 
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index dedfa67..fb8cc63 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -309,7 +309,8 @@ typedef struct sPAPREnvironment {
 #define KVMPPC_H_LOGICAL_MEMOP  (KVMPPC_HCALL_BASE + 0x1)
 /* Client Architecture support */
 #define KVMPPC_H_CAS            (KVMPPC_HCALL_BASE + 0x2)
-#define KVMPPC_HCALL_MAX        KVMPPC_H_CAS
+#define KVMPPC_H_RTAS_UPDATE    (KVMPPC_HCALL_BASE + 0x3)
+#define KVMPPC_HCALL_MAX        KVMPPC_H_RTAS_UPDATE
 
 extern sPAPREnvironment *spapr;
 

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [Qemu-devel] [PATCH 3/5] target-ppc: Build error log
  2014-08-25 13:45 [Qemu-devel] [PATCH 0/5] target-ppc: Add FWNMI support in QEMU for powerKVM guests Aravinda Prasad
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob Aravinda Prasad
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 2/5] target-ppc: Register and handle HCALL to receive updated RTAS region Aravinda Prasad
@ 2014-08-25 13:45 ` Aravinda Prasad
  2014-08-26  5:47   ` David Gibson
  2014-08-27  9:50   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call Aravinda Prasad
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check Aravinda Prasad
  4 siblings, 2 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-25 13:45 UTC (permalink / raw)
  To: aik, qemu-ppc, qemu-devel; +Cc: benh, paulus

Whenever there is a physical memory error due to bit
flips, which cannot be corrected by hardware, the error
is passed on to the kernel. If the memory address in
error belongs to guest address space then guest kernel
is responsible to take action. Hence the error is passed
on to guest via KVM by invoking 0x200 NMI vector.

However, guest OS, as per PAPR, expects an error log
upon such error. This patch registers a new hcall
which is issued from 0x200 interrupt vector and builds
the error log, copies the error log to rtas space and
passes the address of the error log to guest

Enhancement to KVM to perform above functionality is
already in upstream kernel.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 hw/ppc/spapr_hcall.c   |  147 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h |    4 +
 2 files changed, 150 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 118ee77..be063f4 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -14,6 +14,86 @@ struct SPRSyncState {
     target_ulong mask;
 };
 
+#define SEVERITY_SHIFT         0x5
+#define DISPOSITION_SHIFT      0x3
+#define INITIATOR_SHIFT        0x4
+
+/*
+ * Only required RTAS event severity, disposition, initiator
+ * target and type are copied from arch/powerpc/include/asm/rtas.h
+ */
+
+/* RTAS event severity */
+#define RTAS_SEVERITY_ERROR_SYNC    0x3
+
+/* RTAS event disposition */
+#define RTAS_DISP_NOT_RECOVERED     0x2
+
+/* RTAS event initiator */
+#define RTAS_INITIATOR_MEMORY       0x4
+
+/* RTAS event target */
+#define RTAS_TARGET_MEMORY          0x4
+
+/* RTAS event type */
+#define RTAS_TYPE_ECC_UNCORR        0x09
+
+/*
+ * Currently KVM only passes on the uncorrected machine
+ * check memory error to guest. Other machine check errors
+ * such as SLB multi-hit and TLB multi-hit are recovered
+ * in KVM and are not passed on to guest.
+ *
+ * DSISR Bit for uncorrected machine check error. Copied
+ * from arch/powerpc/include/asm/mce.h
+ */
+#define PPC_BITLSHIFT(be)           (64 - 1 - (be))
+#define PPC_BIT(bit)                (1UL << PPC_BITLSHIFT(bit))
+#define P7_DSISR_MC_UE              (PPC_BIT(48))  /* P8 too */
+
+/* Adopted from kernel source arch/powerpc/include/asm/rtas.h */
+struct rtas_error_log {
+    /* Byte 0 */
+    uint8_t     byte0;          /* Architectural version */
+
+    /* Byte 1 */
+    uint8_t     byte1;
+    /* XXXXXXXX
+     * XXX      3: Severity level of error
+     *    XX    2: Degree of recovery
+     *      X   1: Extended log present?
+     *       XX 2: Reserved
+     */
+
+    /* Byte 2 */
+    uint8_t     byte2;
+    /* XXXXXXXX
+     * XXXX     4: Initiator of event
+     *     XXXX 4: Target of failed operation
+     */
+    uint8_t     byte3;          /* General event or error*/
+};
+
+/*
+ * Data format in RTAS-Blob
+ *
+ * This structure contains error information related to Machine
+ * Check exception. This is filled up and copied to rtas-blob
+ * upon machine check exception.
+ */
+struct rtas_mc_log {
+    target_ulong srr0;
+    target_ulong srr1;
+    /*
+     * Beginning of error log address. This is properly
+     * populated and passed on to OS registered machine
+     * check notification routine upon machine check
+     * exception
+     */
+    target_ulong r3;
+    struct rtas_error_log err_log;
+};
+
 static void do_spr_sync(void *arg)
 {
     struct SPRSyncState *s = arg;
@@ -586,6 +666,72 @@ static target_ulong h_rtas_update(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return 0;
 }
 
+static target_ulong h_report_mc_err(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+                                 target_ulong opcode, target_ulong *args)
+{
+    struct rtas_mc_log mc_log;
+    CPUPPCState *env = &cpu->env;
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+
+    /*
+     * 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
+     */
+    mc_log.r3 = env->spr[SPR_SPRG2];
+
+    /*
+     * SRR0 and SRR1 contains nip and msr at the time of exception
+     * and are clobbered when we return from this hcall
+     * and hence need to be properly restored. We save srr0
+     * and srr1 in rtas blob and restore it in 0x200 vector
+     * before branching to OS registered machine check handler
+     */
+    mc_log.srr0 = env->spr[SPR_SRR0];
+    mc_log.srr1 = env->spr[SPR_SRR1];
+
+    /* Set error log fields */
+    mc_log.err_log.byte0 = 0x00;
+    mc_log.err_log.byte1 = (RTAS_SEVERITY_ERROR_SYNC << SEVERITY_SHIFT);
+    mc_log.err_log.byte1 |= (RTAS_DISP_NOT_RECOVERED << DISPOSITION_SHIFT);
+    mc_log.err_log.byte2 = (RTAS_INITIATOR_MEMORY << INITIATOR_SHIFT);
+    mc_log.err_log.byte2 |= RTAS_TARGET_MEMORY;
+
+    if (env->spr[SPR_DSISR] & P7_DSISR_MC_UE) {
+        mc_log.err_log.byte3 = RTAS_TYPE_ECC_UNCORR;
+    } else {
+        mc_log.err_log.byte3 = 0x0;
+    }
+
+    /* Handle all Host/Guest LE/BE combinations */
+    if ((*pcc->interrupts_big_endian)(cpu)) {
+        mc_log.srr0 = cpu_to_be64(mc_log.srr0);
+        mc_log.srr1 = cpu_to_be64(mc_log.srr1);
+        mc_log.r3 = cpu_to_be64(mc_log.r3);
+    } else {
+        mc_log.srr0 = cpu_to_le64(mc_log.srr0);
+        mc_log.srr1 = cpu_to_le64(mc_log.srr1);
+        mc_log.r3 = cpu_to_le64(mc_log.r3);
+    }
+
+    cpu_physical_memory_write(spapr->rtas_addr, &mc_log,
+                              sizeof(mc_log));
+
+    /*
+     * spapr->rtas_addr now contains srr0, srr1, original r3, followed
+     * by the error log structure. The address of the error log
+     * should be passed on to guest's machine check notification
+     * routine. As this hcall is directly called from 0x200 interrupt
+     * vector and returns to assembly routine, we return spapr->rtas_addr
+     * instead of H_SUCCESS. Upon return, We restore srr0 and srr1, increment
+     * r3 to point to the error log and branch to machine check notification
+     * routine in 0x200. r3 containing the error address is now argument
+     * to OS registered machine check notification routine. This way we
+     * also avoids clobbering additional registers in 0x200 vector.
+     */
+    return spapr->rtas_addr;
+}
+
 static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                    target_ulong opcode, target_ulong *args)
 {
@@ -1011,6 +1157,7 @@ static void hypercall_register_types(void)
     /* qemu/KVM-PPC specific hcalls */
     spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
     spapr_register_hypercall(KVMPPC_H_RTAS_UPDATE, h_rtas_update);
+    spapr_register_hypercall(KVMPPC_H_REPORT_MC_ERR, h_report_mc_err);
 
     spapr_register_hypercall(H_SET_MODE, h_set_mode);
 
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index fb8cc63..57199f5 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -310,7 +310,9 @@ typedef struct sPAPREnvironment {
 /* Client Architecture support */
 #define KVMPPC_H_CAS            (KVMPPC_HCALL_BASE + 0x2)
 #define KVMPPC_H_RTAS_UPDATE    (KVMPPC_HCALL_BASE + 0x3)
-#define KVMPPC_HCALL_MAX        KVMPPC_H_RTAS_UPDATE
+/* Report Machine Check error */
+#define KVMPPC_H_REPORT_MC_ERR  (KVMPPC_HCALL_BASE + 0x4)
+#define KVMPPC_HCALL_MAX        KVMPPC_H_REPORT_MC_ERR
 
 extern sPAPREnvironment *spapr;
 

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [Qemu-devel] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-25 13:45 [Qemu-devel] [PATCH 0/5] target-ppc: Add FWNMI support in QEMU for powerKVM guests Aravinda Prasad
                   ` (2 preceding siblings ...)
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 3/5] target-ppc: Build error log Aravinda Prasad
@ 2014-08-25 13:45 ` Aravinda Prasad
  2014-08-26  6:02   ` David Gibson
                     ` (2 more replies)
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check Aravinda Prasad
  4 siblings, 3 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-25 13:45 UTC (permalink / raw)
  To: aik, qemu-ppc, qemu-devel; +Cc: benh, paulus

This patch adds FWNMI support in qemu for powerKVM
guests by handling the ibm,nmi-register rtas call.
Whenever OS issues ibm,nmi-register RTAS call, the
machine check notification address is saved and the
machine check interrupt vector 0x200 is patched to
issue a private hcall.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h |    8 ++++
 2 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 02ddbf9..1135d2b 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
     rtas_st(rets, 0, ret);
 }
 
+static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
+                                  sPAPREnvironment *spapr,
+                                  uint32_t token, uint32_t nargs,
+                                  target_ulong args,
+                                  uint32_t nret, target_ulong rets)
+{
+    int i;
+    uint32_t branch_inst = 0x48000002;
+    target_ulong guest_machine_check_addr;
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+    /*
+     * Trampoline saves r3 in sprg2 and issues private hcall
+     * to request qemu to build error log. QEMU builds the
+     * error log, copies to rtas-blob and returns the address.
+     * The initial 16 bytes in rtas-blob consists of saved srr0
+     * and srr1 which we restore and pass on the actual error
+     * log address to OS handled mcachine check notification
+     * routine
+     */
+    uint32_t trampoline[] = {
+        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
+        0x38600000,    /* li      r3,0   */
+        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
+        0x6063f004,    /* ori     r3,r3,f004  */
+        /* Issue H_CALL */
+        0x44000022,    /*  sc      1     */
+        0x7c9243a6,    /* mtspr r4 sprg2 */
+        0xe8830000,    /* ld r4, 0(r3) */
+        0x7c9a03a6,    /* mtspr r4, srr0 */
+        0xe8830008,    /* ld r4, 8(r3) */
+        0x7c9b03a6,    /* mtspr r4, srr1 */
+        0x38630010,    /* addi r3,r3,16 */
+        0x7c9242a6,    /* mfspr r4 sprg2 */
+        0x48000002,    /* Branch to address registered
+                        * by OS. The branch address is
+                        * patched below */
+        0x48000000,    /* b . */
+    };
+    int total_inst = sizeof(trampoline) / sizeof(uint32_t);
+
+    /* Store the system reset and machine check address */
+    guest_machine_check_addr = rtas_ld(args, 1);
+
+    /* Safety Check */
+    if (sizeof(trampoline) >= MC_INTERRUPT_VECTOR_SIZE) {
+        fprintf(stderr, "Unable to register ibm,nmi_register: "
+                "Trampoline size exceeded\n");
+        rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
+        return;
+    }
+
+    /*
+     * Update the branch instruction in trampoline with the absolute
+     * machine check address requested by OS
+     */
+    branch_inst |= guest_machine_check_addr;
+    memcpy(&trampoline[11], &branch_inst, sizeof(branch_inst));
+
+    /* Handle all Host/Guest LE/BE combinations */
+    if ((*pcc->interrupts_big_endian)(cpu)) {
+        for (i = 0; i < total_inst; i++) {
+            trampoline[i] = cpu_to_be32(trampoline[i]);
+        }
+    } else {
+        for (i = 0; i < total_inst; i++) {
+            trampoline[i] = cpu_to_le32(trampoline[i]);
+        }
+    }
+
+    /* Patch 0x200 NMI interrupt vector memory area of guest */
+    cpu_physical_memory_write(MC_INTERRUPT_VECTOR, trampoline,
+                              sizeof(trampoline));
+
+    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
+static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
+                                   sPAPREnvironment *spapr,
+                                   uint32_t token, uint32_t nargs,
+                                   target_ulong args,
+                                   uint32_t nret, target_ulong rets)
+{
+    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
 static struct rtas_call {
     const char *name;
     spapr_rtas_fn fn;
@@ -404,6 +489,12 @@ static void core_rtas_register_types(void)
     spapr_rtas_register(RTAS_IBM_SET_SYSTEM_PARAMETER,
                         "ibm,set-system-parameter",
                         rtas_ibm_set_system_parameter);
+    spapr_rtas_register(RTAS_IBM_NMI_REGISTER,
+                        "ibm,nmi-register",
+                        rtas_ibm_nmi_register);
+    spapr_rtas_register(RTAS_IBM_NMI_INTERLOCK,
+                        "ibm,nmi-interlock",
+                        rtas_ibm_nmi_interlock);
 }
 
 type_init(core_rtas_register_types)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 57199f5..8c854ca 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -386,8 +386,10 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
 #define RTAS_IBM_CONFIGURE_CONNECTOR            (RTAS_TOKEN_BASE + 0x1E)
 #define RTAS_IBM_OS_TERM                        (RTAS_TOKEN_BASE + 0x1F)
 #define RTAS_IBM_EXTENDED_OS_TERM               (RTAS_TOKEN_BASE + 0x20)
+#define RTAS_IBM_NMI_REGISTER                   (RTAS_TOKEN_BASE + 0x21)
+#define RTAS_IBM_NMI_INTERLOCK                  (RTAS_TOKEN_BASE + 0x22)
 
-#define RTAS_TOKEN_MAX                          (RTAS_TOKEN_BASE + 0x21)
+#define RTAS_TOKEN_MAX                          (RTAS_TOKEN_BASE + 0x23)
 
 /* RTAS ibm,get-system-parameter token values */
 #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS      20
@@ -485,4 +487,8 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname,
 int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
                       sPAPRTCETable *tcet);
 
+/* Machine Check Interrupt related macros */
+#define MC_INTERRUPT_VECTOR           0x200
+#define MC_INTERRUPT_VECTOR_SIZE      0x100
+
 #endif /* !defined (__HW_SPAPR_H__) */

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [Qemu-devel] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check
  2014-08-25 13:45 [Qemu-devel] [PATCH 0/5] target-ppc: Add FWNMI support in QEMU for powerKVM guests Aravinda Prasad
                   ` (3 preceding siblings ...)
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call Aravinda Prasad
@ 2014-08-25 13:45 ` Aravinda Prasad
  2014-08-26  6:04   ` David Gibson
  2014-08-27 10:40   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
  4 siblings, 2 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-25 13:45 UTC (permalink / raw)
  To: aik, qemu-ppc, qemu-devel; +Cc: benh, paulus

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 <aravinda@linux.vnet.ibm.com>
---
 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);
 }
 

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob Aravinda Prasad
@ 2014-08-26  5:38   ` David Gibson
  2014-08-26  6:34     ` Aravinda Prasad
  2014-08-28 10:40   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
  2014-09-01  7:46   ` [Qemu-devel] " Alexey Kardashevskiy
  2 siblings, 1 reply; 73+ messages in thread
From: David Gibson @ 2014-08-26  5:38 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus

[-- Attachment #1: Type: text/plain, Size: 608 bytes --]

On Mon, Aug 25, 2014 at 07:15:16PM +0530, Aravinda Prasad wrote:
> Extend rtas-blob to accommodate error log. Error log
> structure is saved in rtas space upon a machine check
> exception.

Hrm.  Putting the reserved space into the actual firmware image file
seems really clumsy to me.  Wouldn't it be better to reserve the space
directly from qemu, then just paste the 20 bytes of code into that
area.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 2/5] target-ppc: Register and handle HCALL to receive updated RTAS region
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 2/5] target-ppc: Register and handle HCALL to receive updated RTAS region Aravinda Prasad
@ 2014-08-26  5:39   ` David Gibson
  2014-08-26  6:15     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 73+ messages in thread
From: David Gibson @ 2014-08-26  5:39 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus

[-- Attachment #1: Type: text/plain, Size: 958 bytes --]

On Mon, Aug 25, 2014 at 07:15:26PM +0530, Aravinda Prasad wrote:
> Receive updates from SLOF about the updated rtas-base.
> A separate patch for SLOF [1] adds functionality to invoke a
> a private HCALL whenever OS issues instantiate-rtas with
> a new rtas-base.
> 
> This is required as qemu needs to know the updated rtas-base
> as it allocates error reporting structure in RTAS space upon
> a machine check exception.

This also seems really awkward.  Specifically it seems like a rather
arbitrary and complex division of what qemu's responsible for and what
SLOF is responsible for.

Instead I'd suggest that we add an H_INSTANTIATE_RTAS hcall, and we
move the loading of the spapr-rtas blob from normal reset to when that
hcall is invoked.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 3/5] target-ppc: Build error log
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 3/5] target-ppc: Build error log Aravinda Prasad
@ 2014-08-26  5:47   ` David Gibson
  2014-08-26  6:40     ` Aravinda Prasad
  2014-08-27  9:50   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
  1 sibling, 1 reply; 73+ messages in thread
From: David Gibson @ 2014-08-26  5:47 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus

[-- Attachment #1: Type: text/plain, Size: 8513 bytes --]

On Mon, Aug 25, 2014 at 07:15:35PM +0530, Aravinda Prasad wrote:
> Whenever there is a physical memory error due to bit
> flips, which cannot be corrected by hardware, the error
> is passed on to the kernel. If the memory address in
> error belongs to guest address space then guest kernel
> is responsible to take action. Hence the error is passed
> on to guest via KVM by invoking 0x200 NMI vector.
> 
> However, guest OS, as per PAPR, expects an error log
> upon such error. This patch registers a new hcall
> which is issued from 0x200 interrupt vector and builds
> the error log, copies the error log to rtas space and
> passes the address of the error log to guest
> 
> Enhancement to KVM to perform above functionality is
> already in upstream kernel.
> 
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> ---
>  hw/ppc/spapr_hcall.c   |  147 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr.h |    4 +
>  2 files changed, 150 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 118ee77..be063f4 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -14,6 +14,86 @@ struct SPRSyncState {
>      target_ulong mask;
>  };
>  
> +#define SEVERITY_SHIFT         0x5
> +#define DISPOSITION_SHIFT      0x3
> +#define INITIATOR_SHIFT        0x4
> +
> +/*
> + * Only required RTAS event severity, disposition, initiator
> + * target and type are copied from arch/powerpc/include/asm/rtas.h
> + */
> +
> +/* RTAS event severity */
> +#define RTAS_SEVERITY_ERROR_SYNC    0x3
> +
> +/* RTAS event disposition */
> +#define RTAS_DISP_NOT_RECOVERED     0x2
> +
> +/* RTAS event initiator */
> +#define RTAS_INITIATOR_MEMORY       0x4
> +
> +/* RTAS event target */
> +#define RTAS_TARGET_MEMORY          0x4
> +
> +/* RTAS event type */
> +#define RTAS_TYPE_ECC_UNCORR        0x09
> +
> +/*
> + * Currently KVM only passes on the uncorrected machine
> + * check memory error to guest. Other machine check errors
> + * such as SLB multi-hit and TLB multi-hit are recovered
> + * in KVM and are not passed on to guest.
> + *
> + * DSISR Bit for uncorrected machine check error. Copied
> + * from arch/powerpc/include/asm/mce.h
> + */
> +#define PPC_BITLSHIFT(be)           (64 - 1 - (be))
> +#define PPC_BIT(bit)                (1UL << PPC_BITLSHIFT(bit))

Just opencode the BITLSHIFT macro into the BIT macro, it doesn't
improve either brevity or clarity as it is.

Or alternatively define PPC_BIT as (0x8000000000000000ULL >> bit)
which might be clearer.

> +#define P7_DSISR_MC_UE              (PPC_BIT(48))  /* P8 too */
> +
> +/* Adopted from kernel source arch/powerpc/include/asm/rtas.h */
> +struct rtas_error_log {
> +    /* Byte 0 */
> +    uint8_t     byte0;          /* Architectural version */
> +
> +    /* Byte 1 */
> +    uint8_t     byte1;
> +    /* XXXXXXXX
> +     * XXX      3: Severity level of error
> +     *    XX    2: Degree of recovery
> +     *      X   1: Extended log present?
> +     *       XX 2: Reserved
> +     */
> +
> +    /* Byte 2 */
> +    uint8_t     byte2;
> +    /* XXXXXXXX
> +     * XXXX     4: Initiator of event
> +     *     XXXX 4: Target of failed operation
> +     */
> +    uint8_t     byte3;          /* General event or error*/
> +};
> +
> +/*
> + * Data format in RTAS-Blob
> + *
> + * This structure contains error information related to Machine
> + * Check exception. This is filled up and copied to rtas-blob
> + * upon machine check exception.
> + */
> +struct rtas_mc_log {
> +    target_ulong srr0;
> +    target_ulong srr1;
> +    /*
> +     * Beginning of error log address. This is properly
> +     * populated and passed on to OS registered machine
> +     * check notification routine upon machine check
> +     * exception
> +     */
> +    target_ulong r3;
> +    struct rtas_error_log err_log;
> +};
> +
>  static void do_spr_sync(void *arg)
>  {
>      struct SPRSyncState *s = arg;
> @@ -586,6 +666,72 @@ static target_ulong h_rtas_update(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>      return 0;
>  }
>  
> +static target_ulong h_report_mc_err(PowerPCCPU *cpu, sPAPREnvironment *spapr,
> +                                 target_ulong opcode, target_ulong *args)
> +{
> +    struct rtas_mc_log mc_log;
> +    CPUPPCState *env = &cpu->env;
> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
> +
> +    /*
> +     * 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
> +     */
> +    mc_log.r3 = env->spr[SPR_SPRG2];
> +
> +    /*
> +     * SRR0 and SRR1 contains nip and msr at the time of exception
> +     * and are clobbered when we return from this hcall
> +     * and hence need to be properly restored. We save srr0
> +     * and srr1 in rtas blob and restore it in 0x200 vector
> +     * before branching to OS registered machine check handler
> +     */
> +    mc_log.srr0 = env->spr[SPR_SRR0];
> +    mc_log.srr1 = env->spr[SPR_SRR1];
> +
> +    /* Set error log fields */
> +    mc_log.err_log.byte0 = 0x00;
> +    mc_log.err_log.byte1 = (RTAS_SEVERITY_ERROR_SYNC << SEVERITY_SHIFT);
> +    mc_log.err_log.byte1 |= (RTAS_DISP_NOT_RECOVERED << DISPOSITION_SHIFT);
> +    mc_log.err_log.byte2 = (RTAS_INITIATOR_MEMORY << INITIATOR_SHIFT);
> +    mc_log.err_log.byte2 |= RTAS_TARGET_MEMORY;
> +
> +    if (env->spr[SPR_DSISR] & P7_DSISR_MC_UE) {
> +        mc_log.err_log.byte3 = RTAS_TYPE_ECC_UNCORR;
> +    } else {
> +        mc_log.err_log.byte3 = 0x0;
> +    }
> +
> +    /* Handle all Host/Guest LE/BE combinations */
> +    if ((*pcc->interrupts_big_endian)(cpu)) {
> +        mc_log.srr0 = cpu_to_be64(mc_log.srr0);
> +        mc_log.srr1 = cpu_to_be64(mc_log.srr1);
> +        mc_log.r3 = cpu_to_be64(mc_log.r3);
> +    } else {
> +        mc_log.srr0 = cpu_to_le64(mc_log.srr0);
> +        mc_log.srr1 = cpu_to_le64(mc_log.srr1);
> +        mc_log.r3 = cpu_to_le64(mc_log.r3);
> +    }
> +
> +    cpu_physical_memory_write(spapr->rtas_addr, &mc_log,
> +                              sizeof(mc_log));
> +
> +    /*
> +     * spapr->rtas_addr now contains srr0, srr1, original r3, followed
> +     * by the error log structure. The address of the error log
> +     * should be passed on to guest's machine check notification
> +     * routine. As this hcall is directly called from 0x200 interrupt
> +     * vector and returns to assembly routine, we return spapr->rtas_addr
> +     * instead of H_SUCCESS. Upon return, We restore srr0 and srr1, increment
> +     * r3 to point to the error log and branch to machine check notification
> +     * routine in 0x200. r3 containing the error address is now argument
> +     * to OS registered machine check notification routine. This way we
> +     * also avoids clobbering additional registers in 0x200 vector.
> +     */
> +    return spapr->rtas_addr;
> +}
> +
>  static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>                                     target_ulong opcode, target_ulong *args)
>  {
> @@ -1011,6 +1157,7 @@ static void hypercall_register_types(void)
>      /* qemu/KVM-PPC specific hcalls */
>      spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
>      spapr_register_hypercall(KVMPPC_H_RTAS_UPDATE, h_rtas_update);
> +    spapr_register_hypercall(KVMPPC_H_REPORT_MC_ERR, h_report_mc_err);
>  
>      spapr_register_hypercall(H_SET_MODE, h_set_mode);
>  
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index fb8cc63..57199f5 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -310,7 +310,9 @@ typedef struct sPAPREnvironment {
>  /* Client Architecture support */
>  #define KVMPPC_H_CAS            (KVMPPC_HCALL_BASE + 0x2)
>  #define KVMPPC_H_RTAS_UPDATE    (KVMPPC_HCALL_BASE + 0x3)
> -#define KVMPPC_HCALL_MAX        KVMPPC_H_RTAS_UPDATE
> +/* Report Machine Check error */
> +#define KVMPPC_H_REPORT_MC_ERR  (KVMPPC_HCALL_BASE + 0x4)
> +#define KVMPPC_HCALL_MAX        KVMPPC_H_REPORT_MC_ERR
>  
>  extern sPAPREnvironment *spapr;
>  
> 
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call Aravinda Prasad
@ 2014-08-26  6:02   ` David Gibson
  2014-08-26  6:57     ` Aravinda Prasad
  2014-08-27 10:37   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
  2014-09-07 20:47   ` Alexander Graf
  2 siblings, 1 reply; 73+ messages in thread
From: David Gibson @ 2014-08-26  6:02 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus

[-- Attachment #1: Type: text/plain, Size: 5233 bytes --]

On Mon, Aug 25, 2014 at 07:15:45PM +0530, Aravinda Prasad wrote:
> This patch adds FWNMI support in qemu for powerKVM
> guests by handling the ibm,nmi-register rtas call.
> Whenever OS issues ibm,nmi-register RTAS call, the
> machine check notification address is saved and the
> machine check interrupt vector 0x200 is patched to
> issue a private hcall.
> 
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> ---
>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr.h |    8 ++++
>  2 files changed, 98 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index 02ddbf9..1135d2b 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>      rtas_st(rets, 0, ret);
>  }
>  
> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
> +                                  sPAPREnvironment *spapr,
> +                                  uint32_t token, uint32_t nargs,
> +                                  target_ulong args,
> +                                  uint32_t nret, target_ulong rets)
> +{
> +    int i;
> +    uint32_t branch_inst = 0x48000002;
> +    target_ulong guest_machine_check_addr;
> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
> +    /*
> +     * Trampoline saves r3 in sprg2 and issues private hcall
> +     * to request qemu to build error log. QEMU builds the
> +     * error log, copies to rtas-blob and returns the address.
> +     * The initial 16 bytes in rtas-blob consists of saved srr0
> +     * and srr1 which we restore and pass on the actual error
> +     * log address to OS handled mcachine check notification
> +     * routine
> +     */
> +    uint32_t trampoline[] = {
> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
> +        0x38600000,    /* li      r3,0   */
> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */

You should construct the instruction from the KVMPPC_H_REPORT_ERR
constant, otherwise it's an undocumented magic dependency between
parts of the code.

> +        0x6063f004,    /* ori     r3,r3,f004  */
> +        /* Issue H_CALL */
> +        0x44000022,    /*  sc      1     */
> +        0x7c9243a6,    /* mtspr r4 sprg2 */
> +        0xe8830000,    /* ld r4, 0(r3) */
> +        0x7c9a03a6,    /* mtspr r4, srr0 */
> +        0xe8830008,    /* ld r4, 8(r3) */
> +        0x7c9b03a6,    /* mtspr r4, srr1 */
> +        0x38630010,    /* addi r3,r3,16 */
> +        0x7c9242a6,    /* mfspr r4 sprg2 */
> +        0x48000002,    /* Branch to address registered
> +                        * by OS. The branch address is
> +                        * patched below */
> +        0x48000000,    /* b . */
> +    };
> +    int total_inst = sizeof(trampoline) / sizeof(uint32_t);
> +
> +    /* Store the system reset and machine check address */
> +    guest_machine_check_addr = rtas_ld(args, 1);
> +
> +    /* Safety Check */
> +    if (sizeof(trampoline) >= MC_INTERRUPT_VECTOR_SIZE) {
> +        fprintf(stderr, "Unable to register ibm,nmi_register: "
> +                "Trampoline size exceeded\n");
> +        rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> +        return;

The guest has absolutely no influence over this, so this should be an
assert() rather than returning an rtas error.  Or better yet, detect
the failure at compile time, since it doesn't depend on anything
runtime either.

> +    }
> +
> +    /*
> +     * Update the branch instruction in trampoline with the absolute
> +     * machine check address requested by OS
> +     */
> +    branch_inst |= guest_machine_check_addr;

Surely there should be some sanity checking of the address here, or it
can clobber any part of that branch instruction.

> +    memcpy(&trampoline[11], &branch_inst, sizeof(branch_inst));
> +
> +    /* Handle all Host/Guest LE/BE combinations */
> +    if ((*pcc->interrupts_big_endian)(cpu)) {
> +        for (i = 0; i < total_inst; i++) {
> +            trampoline[i] = cpu_to_be32(trampoline[i]);
> +        }
> +    } else {
> +        for (i = 0; i < total_inst; i++) {
> +            trampoline[i] = cpu_to_le32(trampoline[i]);
> +        }
> +    }
> +
> +    /* Patch 0x200 NMI interrupt vector memory area of guest */
> +    cpu_physical_memory_write(MC_INTERRUPT_VECTOR, trampoline,
> +                              sizeof(trampoline));
> +
> +    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> +}
> +
> +static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
> +                                   sPAPREnvironment *spapr,
> +                                   uint32_t token, uint32_t nargs,
> +                                   target_ulong args,
> +                                   uint32_t nret, target_ulong rets)
> +{
> +    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> +}
> +

This nmi_interlock call isn't described in the commit message.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check Aravinda Prasad
@ 2014-08-26  6:04   ` David Gibson
  2014-08-26  7:04     ` Aravinda Prasad
  2014-08-27 10:40   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
  1 sibling, 1 reply; 73+ messages in thread
From: David Gibson @ 2014-08-26  6:04 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus

[-- Attachment #1: Type: text/plain, Size: 777 bytes --]

On Mon, Aug 25, 2014 at 07:15:54PM +0530, Aravinda Prasad wrote:
> 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.

The previous patch is broken without this, so just fold the two
together.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 2/5] target-ppc: Register and handle HCALL to receive updated RTAS region
  2014-08-26  5:39   ` David Gibson
@ 2014-08-26  6:15     ` Benjamin Herrenschmidt
  2014-08-26  7:24       ` David Gibson
  0 siblings, 1 reply; 73+ messages in thread
From: Benjamin Herrenschmidt @ 2014-08-26  6:15 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, Aravinda Prasad, aik, qemu-devel, paulus

On Tue, 2014-08-26 at 15:39 +1000, David Gibson wrote:
> On Mon, Aug 25, 2014 at 07:15:26PM +0530, Aravinda Prasad wrote:
> > Receive updates from SLOF about the updated rtas-base.
> > A separate patch for SLOF [1] adds functionality to invoke a
> > a private HCALL whenever OS issues instantiate-rtas with
> > a new rtas-base.
> > 
> > This is required as qemu needs to know the updated rtas-base
> > as it allocates error reporting structure in RTAS space upon
> > a machine check exception.
> 
> This also seems really awkward.  Specifically it seems like a rather
> arbitrary and complex division of what qemu's responsible for and what
> SLOF is responsible for.
> 
> Instead I'd suggest that we add an H_INSTANTIATE_RTAS hcall, and we
> move the loading of the spapr-rtas blob from normal reset to when that
> hcall is invoked.

Beware that SLOF needs to call RTAS for its own reasons...

So it would be instanciated twice.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-26  5:38   ` David Gibson
@ 2014-08-26  6:34     ` Aravinda Prasad
  2014-08-26  7:24       ` David Gibson
  0 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-26  6:34 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On Tuesday 26 August 2014 11:08 AM, David Gibson wrote:
> On Mon, Aug 25, 2014 at 07:15:16PM +0530, Aravinda Prasad wrote:
>> Extend rtas-blob to accommodate error log. Error log
>> structure is saved in rtas space upon a machine check
>> exception.
> 
> Hrm.  Putting the reserved space into the actual firmware image file
> seems really clumsy to me.  Wouldn't it be better to reserve the space
> directly from qemu, then just paste the 20 bytes of code into that
> area.

Hmm. It is possible to it from qemu. In that case we can get rid of
spapr-rtas.S. Let me think about that.

Regards,
Aravinda

> 

-- 

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 3/5] target-ppc: Build error log
  2014-08-26  5:47   ` David Gibson
@ 2014-08-26  6:40     ` Aravinda Prasad
  0 siblings, 0 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-26  6:40 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On Tuesday 26 August 2014 11:17 AM, David Gibson wrote:
> On Mon, Aug 25, 2014 at 07:15:35PM +0530, Aravinda Prasad wrote:
>> Whenever there is a physical memory error due to bit
>> flips, which cannot be corrected by hardware, the error
>> is passed on to the kernel. If the memory address in
>> error belongs to guest address space then guest kernel
>> is responsible to take action. Hence the error is passed
>> on to guest via KVM by invoking 0x200 NMI vector.
>>
>> However, guest OS, as per PAPR, expects an error log
>> upon such error. This patch registers a new hcall
>> which is issued from 0x200 interrupt vector and builds
>> the error log, copies the error log to rtas space and
>> passes the address of the error log to guest
>>
>> Enhancement to KVM to perform above functionality is
>> already in upstream kernel.
>>
>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>> ---
>>  hw/ppc/spapr_hcall.c   |  147 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/hw/ppc/spapr.h |    4 +
>>  2 files changed, 150 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
>> index 118ee77..be063f4 100644
>> --- a/hw/ppc/spapr_hcall.c
>> +++ b/hw/ppc/spapr_hcall.c
>> @@ -14,6 +14,86 @@ struct SPRSyncState {
>>      target_ulong mask;
>>  };
>>  
>> +#define SEVERITY_SHIFT         0x5
>> +#define DISPOSITION_SHIFT      0x3
>> +#define INITIATOR_SHIFT        0x4
>> +
>> +/*
>> + * Only required RTAS event severity, disposition, initiator
>> + * target and type are copied from arch/powerpc/include/asm/rtas.h
>> + */
>> +
>> +/* RTAS event severity */
>> +#define RTAS_SEVERITY_ERROR_SYNC    0x3
>> +
>> +/* RTAS event disposition */
>> +#define RTAS_DISP_NOT_RECOVERED     0x2
>> +
>> +/* RTAS event initiator */
>> +#define RTAS_INITIATOR_MEMORY       0x4
>> +
>> +/* RTAS event target */
>> +#define RTAS_TARGET_MEMORY          0x4
>> +
>> +/* RTAS event type */
>> +#define RTAS_TYPE_ECC_UNCORR        0x09
>> +
>> +/*
>> + * Currently KVM only passes on the uncorrected machine
>> + * check memory error to guest. Other machine check errors
>> + * such as SLB multi-hit and TLB multi-hit are recovered
>> + * in KVM and are not passed on to guest.
>> + *
>> + * DSISR Bit for uncorrected machine check error. Copied
>> + * from arch/powerpc/include/asm/mce.h
>> + */
>> +#define PPC_BITLSHIFT(be)           (64 - 1 - (be))
>> +#define PPC_BIT(bit)                (1UL << PPC_BITLSHIFT(bit))
> 
> Just opencode the BITLSHIFT macro into the BIT macro, it doesn't
> improve either brevity or clarity as it is.
> 
> Or alternatively define PPC_BIT as (0x8000000000000000ULL >> bit)
> which might be clearer.

sure.

Regards,
Aravinda

> 
>> +#define P7_DSISR_MC_UE              (PPC_BIT(48))  /* P8 too */
>> +
>> +/* Adopted from kernel source arch/powerpc/include/asm/rtas.h */
>> +struct rtas_error_log {
>> +    /* Byte 0 */
>> +    uint8_t     byte0;          /* Architectural version */
>> +
>> +    /* Byte 1 */
>> +    uint8_t     byte1;
>> +    /* XXXXXXXX
>> +     * XXX      3: Severity level of error
>> +     *    XX    2: Degree of recovery
>> +     *      X   1: Extended log present?
>> +     *       XX 2: Reserved
>> +     */
>> +
>> +    /* Byte 2 */
>> +    uint8_t     byte2;
>> +    /* XXXXXXXX
>> +     * XXXX     4: Initiator of event
>> +     *     XXXX 4: Target of failed operation
>> +     */
>> +    uint8_t     byte3;          /* General event or error*/
>> +};
>> +
>> +/*
>> + * Data format in RTAS-Blob
>> + *
>> + * This structure contains error information related to Machine
>> + * Check exception. This is filled up and copied to rtas-blob
>> + * upon machine check exception.
>> + */
>> +struct rtas_mc_log {
>> +    target_ulong srr0;
>> +    target_ulong srr1;
>> +    /*
>> +     * Beginning of error log address. This is properly
>> +     * populated and passed on to OS registered machine
>> +     * check notification routine upon machine check
>> +     * exception
>> +     */
>> +    target_ulong r3;
>> +    struct rtas_error_log err_log;
>> +};
>> +
>>  static void do_spr_sync(void *arg)
>>  {
>>      struct SPRSyncState *s = arg;
>> @@ -586,6 +666,72 @@ static target_ulong h_rtas_update(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>      return 0;
>>  }
>>  
>> +static target_ulong h_report_mc_err(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>> +                                 target_ulong opcode, target_ulong *args)
>> +{
>> +    struct rtas_mc_log mc_log;
>> +    CPUPPCState *env = &cpu->env;
>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>> +
>> +    /*
>> +     * 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
>> +     */
>> +    mc_log.r3 = env->spr[SPR_SPRG2];
>> +
>> +    /*
>> +     * SRR0 and SRR1 contains nip and msr at the time of exception
>> +     * and are clobbered when we return from this hcall
>> +     * and hence need to be properly restored. We save srr0
>> +     * and srr1 in rtas blob and restore it in 0x200 vector
>> +     * before branching to OS registered machine check handler
>> +     */
>> +    mc_log.srr0 = env->spr[SPR_SRR0];
>> +    mc_log.srr1 = env->spr[SPR_SRR1];
>> +
>> +    /* Set error log fields */
>> +    mc_log.err_log.byte0 = 0x00;
>> +    mc_log.err_log.byte1 = (RTAS_SEVERITY_ERROR_SYNC << SEVERITY_SHIFT);
>> +    mc_log.err_log.byte1 |= (RTAS_DISP_NOT_RECOVERED << DISPOSITION_SHIFT);
>> +    mc_log.err_log.byte2 = (RTAS_INITIATOR_MEMORY << INITIATOR_SHIFT);
>> +    mc_log.err_log.byte2 |= RTAS_TARGET_MEMORY;
>> +
>> +    if (env->spr[SPR_DSISR] & P7_DSISR_MC_UE) {
>> +        mc_log.err_log.byte3 = RTAS_TYPE_ECC_UNCORR;
>> +    } else {
>> +        mc_log.err_log.byte3 = 0x0;
>> +    }
>> +
>> +    /* Handle all Host/Guest LE/BE combinations */
>> +    if ((*pcc->interrupts_big_endian)(cpu)) {
>> +        mc_log.srr0 = cpu_to_be64(mc_log.srr0);
>> +        mc_log.srr1 = cpu_to_be64(mc_log.srr1);
>> +        mc_log.r3 = cpu_to_be64(mc_log.r3);
>> +    } else {
>> +        mc_log.srr0 = cpu_to_le64(mc_log.srr0);
>> +        mc_log.srr1 = cpu_to_le64(mc_log.srr1);
>> +        mc_log.r3 = cpu_to_le64(mc_log.r3);
>> +    }
>> +
>> +    cpu_physical_memory_write(spapr->rtas_addr, &mc_log,
>> +                              sizeof(mc_log));
>> +
>> +    /*
>> +     * spapr->rtas_addr now contains srr0, srr1, original r3, followed
>> +     * by the error log structure. The address of the error log
>> +     * should be passed on to guest's machine check notification
>> +     * routine. As this hcall is directly called from 0x200 interrupt
>> +     * vector and returns to assembly routine, we return spapr->rtas_addr
>> +     * instead of H_SUCCESS. Upon return, We restore srr0 and srr1, increment
>> +     * r3 to point to the error log and branch to machine check notification
>> +     * routine in 0x200. r3 containing the error address is now argument
>> +     * to OS registered machine check notification routine. This way we
>> +     * also avoids clobbering additional registers in 0x200 vector.
>> +     */
>> +    return spapr->rtas_addr;
>> +}
>> +
>>  static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>                                     target_ulong opcode, target_ulong *args)
>>  {
>> @@ -1011,6 +1157,7 @@ static void hypercall_register_types(void)
>>      /* qemu/KVM-PPC specific hcalls */
>>      spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
>>      spapr_register_hypercall(KVMPPC_H_RTAS_UPDATE, h_rtas_update);
>> +    spapr_register_hypercall(KVMPPC_H_REPORT_MC_ERR, h_report_mc_err);
>>  
>>      spapr_register_hypercall(H_SET_MODE, h_set_mode);
>>  
>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>> index fb8cc63..57199f5 100644
>> --- a/include/hw/ppc/spapr.h
>> +++ b/include/hw/ppc/spapr.h
>> @@ -310,7 +310,9 @@ typedef struct sPAPREnvironment {
>>  /* Client Architecture support */
>>  #define KVMPPC_H_CAS            (KVMPPC_HCALL_BASE + 0x2)
>>  #define KVMPPC_H_RTAS_UPDATE    (KVMPPC_HCALL_BASE + 0x3)
>> -#define KVMPPC_HCALL_MAX        KVMPPC_H_RTAS_UPDATE
>> +/* Report Machine Check error */
>> +#define KVMPPC_H_REPORT_MC_ERR  (KVMPPC_HCALL_BASE + 0x4)
>> +#define KVMPPC_HCALL_MAX        KVMPPC_H_REPORT_MC_ERR
>>  
>>  extern sPAPREnvironment *spapr;
>>  
>>
>>
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-26  6:02   ` David Gibson
@ 2014-08-26  6:57     ` Aravinda Prasad
  0 siblings, 0 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-26  6:57 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On Tuesday 26 August 2014 11:32 AM, David Gibson wrote:
> On Mon, Aug 25, 2014 at 07:15:45PM +0530, Aravinda Prasad wrote:
>> This patch adds FWNMI support in qemu for powerKVM
>> guests by handling the ibm,nmi-register rtas call.
>> Whenever OS issues ibm,nmi-register RTAS call, the
>> machine check notification address is saved and the
>> machine check interrupt vector 0x200 is patched to
>> issue a private hcall.
>>
>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>> ---
>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/hw/ppc/spapr.h |    8 ++++
>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>> index 02ddbf9..1135d2b 100644
>> --- a/hw/ppc/spapr_rtas.c
>> +++ b/hw/ppc/spapr_rtas.c
>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>      rtas_st(rets, 0, ret);
>>  }
>>  
>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>> +                                  sPAPREnvironment *spapr,
>> +                                  uint32_t token, uint32_t nargs,
>> +                                  target_ulong args,
>> +                                  uint32_t nret, target_ulong rets)
>> +{
>> +    int i;
>> +    uint32_t branch_inst = 0x48000002;
>> +    target_ulong guest_machine_check_addr;
>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>> +    /*
>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>> +     * to request qemu to build error log. QEMU builds the
>> +     * error log, copies to rtas-blob and returns the address.
>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>> +     * and srr1 which we restore and pass on the actual error
>> +     * log address to OS handled mcachine check notification
>> +     * routine
>> +     */
>> +    uint32_t trampoline[] = {
>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>> +        0x38600000,    /* li      r3,0   */
>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
> 
> You should construct the instruction from the KVMPPC_H_REPORT_ERR
> constant, otherwise it's an undocumented magic dependency between
> parts of the code.

hmm.. yes. will do

> 
>> +        0x6063f004,    /* ori     r3,r3,f004  */
>> +        /* Issue H_CALL */
>> +        0x44000022,    /*  sc      1     */
>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>> +        0xe8830000,    /* ld r4, 0(r3) */
>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>> +        0xe8830008,    /* ld r4, 8(r3) */
>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>> +        0x38630010,    /* addi r3,r3,16 */
>> +        0x7c9242a6,    /* mfspr r4 sprg2 */
>> +        0x48000002,    /* Branch to address registered
>> +                        * by OS. The branch address is
>> +                        * patched below */
>> +        0x48000000,    /* b . */
>> +    };
>> +    int total_inst = sizeof(trampoline) / sizeof(uint32_t);
>> +
>> +    /* Store the system reset and machine check address */
>> +    guest_machine_check_addr = rtas_ld(args, 1);
>> +
>> +    /* Safety Check */
>> +    if (sizeof(trampoline) >= MC_INTERRUPT_VECTOR_SIZE) {
>> +        fprintf(stderr, "Unable to register ibm,nmi_register: "
>> +                "Trampoline size exceeded\n");
>> +        rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
>> +        return;
> 
> The guest has absolutely no influence over this, so this should be an
> assert() rather than returning an rtas error.  Or better yet, detect
> the failure at compile time, since it doesn't depend on anything
> runtime either.

yes better to detect at compile time.

> 
>> +    }
>> +
>> +    /*
>> +     * Update the branch instruction in trampoline with the absolute
>> +     * machine check address requested by OS
>> +     */
>> +    branch_inst |= guest_machine_check_addr;
> 
> Surely there should be some sanity checking of the address here, or it
> can clobber any part of that branch instruction.

Will include a check to make sure instruction opcode is not clobbered.

> 
>> +    memcpy(&trampoline[11], &branch_inst, sizeof(branch_inst));
>> +
>> +    /* Handle all Host/Guest LE/BE combinations */
>> +    if ((*pcc->interrupts_big_endian)(cpu)) {
>> +        for (i = 0; i < total_inst; i++) {
>> +            trampoline[i] = cpu_to_be32(trampoline[i]);
>> +        }
>> +    } else {
>> +        for (i = 0; i < total_inst; i++) {
>> +            trampoline[i] = cpu_to_le32(trampoline[i]);
>> +        }
>> +    }
>> +
>> +    /* Patch 0x200 NMI interrupt vector memory area of guest */
>> +    cpu_physical_memory_write(MC_INTERRUPT_VECTOR, trampoline,
>> +                              sizeof(trampoline));
>> +
>> +    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>> +}
>> +
>> +static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
>> +                                   sPAPREnvironment *spapr,
>> +                                   uint32_t token, uint32_t nargs,
>> +                                   target_ulong args,
>> +                                   uint32_t nret, target_ulong rets)
>> +{
>> +    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>> +}
>> +
> 
> This nmi_interlock call isn't described in the commit message.

Yes. will include

Regards,
Aravinda

> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check
  2014-08-26  6:04   ` David Gibson
@ 2014-08-26  7:04     ` Aravinda Prasad
  0 siblings, 0 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-26  7:04 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On Tuesday 26 August 2014 11:34 AM, David Gibson wrote:
> On Mon, Aug 25, 2014 at 07:15:54PM +0530, Aravinda Prasad wrote:
>> 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.
> 
> The previous patch is broken without this, so just fold the two
> together.

sure.

Thanks for the review.

Regards,
Aravinda

> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-26  6:34     ` Aravinda Prasad
@ 2014-08-26  7:24       ` David Gibson
  0 siblings, 0 replies; 73+ messages in thread
From: David Gibson @ 2014-08-26  7:24 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus

[-- Attachment #1: Type: text/plain, Size: 1157 bytes --]

On Tue, Aug 26, 2014 at 12:04:27PM +0530, Aravinda Prasad wrote:
> 
> 
> On Tuesday 26 August 2014 11:08 AM, David Gibson wrote:
> > On Mon, Aug 25, 2014 at 07:15:16PM +0530, Aravinda Prasad wrote:
> >> Extend rtas-blob to accommodate error log. Error log
> >> structure is saved in rtas space upon a machine check
> >> exception.
> > 
> > Hrm.  Putting the reserved space into the actual firmware image file
> > seems really clumsy to me.  Wouldn't it be better to reserve the space
> > directly from qemu, then just paste the 20 bytes of code into that
> > area.
> 
> Hmm. It is possible to it from qemu. In that case we can get rid of
> spapr-rtas.S. Let me think about that.

I think getting rid of spapr-rtas.S is probably a good idea.  It
complicates building things for the sake of 5 instructions.
Especially since in your new code you construct the vector
instructions directly, it makes sense to do the same thing for
spapr-rtas.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 2/5] target-ppc: Register and handle HCALL to receive updated RTAS region
  2014-08-26  6:15     ` Benjamin Herrenschmidt
@ 2014-08-26  7:24       ` David Gibson
  2014-08-26 20:05         ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 73+ messages in thread
From: David Gibson @ 2014-08-26  7:24 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: qemu-ppc, Aravinda Prasad, aik, qemu-devel, paulus

[-- Attachment #1: Type: text/plain, Size: 1345 bytes --]

On Tue, Aug 26, 2014 at 04:15:40PM +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2014-08-26 at 15:39 +1000, David Gibson wrote:
> > On Mon, Aug 25, 2014 at 07:15:26PM +0530, Aravinda Prasad wrote:
> > > Receive updates from SLOF about the updated rtas-base.
> > > A separate patch for SLOF [1] adds functionality to invoke a
> > > a private HCALL whenever OS issues instantiate-rtas with
> > > a new rtas-base.
> > > 
> > > This is required as qemu needs to know the updated rtas-base
> > > as it allocates error reporting structure in RTAS space upon
> > > a machine check exception.
> > 
> > This also seems really awkward.  Specifically it seems like a rather
> > arbitrary and complex division of what qemu's responsible for and what
> > SLOF is responsible for.
> > 
> > Instead I'd suggest that we add an H_INSTANTIATE_RTAS hcall, and we
> > move the loading of the spapr-rtas blob from normal reset to when that
> > hcall is invoked.
> 
> Beware that SLOF needs to call RTAS for its own reasons...
> 
> So it would be instanciated twice.

I don't see that that would cause a big problem, or am I missing
something?

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 2/5] target-ppc: Register and handle HCALL to receive updated RTAS region
  2014-08-26  7:24       ` David Gibson
@ 2014-08-26 20:05         ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 73+ messages in thread
From: Benjamin Herrenschmidt @ 2014-08-26 20:05 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, Aravinda Prasad, aik, qemu-devel, paulus

On Tue, 2014-08-26 at 17:24 +1000, David Gibson wrote:
> > Beware that SLOF needs to call RTAS for its own reasons...
> > 
> > So it would be instanciated twice.
> 
> I don't see that that would cause a big problem, or am I missing
> something?

Well, not necessarily, just pointing out that SLOF will need more
adjustments.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/5] target-ppc: Build error log
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 3/5] target-ppc: Build error log Aravinda Prasad
  2014-08-26  5:47   ` David Gibson
@ 2014-08-27  9:50   ` Alexander Graf
  2014-08-28  6:12     ` Aravinda Prasad
  1 sibling, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-08-27  9:50 UTC (permalink / raw)
  To: Aravinda Prasad, aik, qemu-ppc, qemu-devel; +Cc: benh, paulus



On 25.08.14 15:45, Aravinda Prasad wrote:
> Whenever there is a physical memory error due to bit
> flips, which cannot be corrected by hardware, the error
> is passed on to the kernel. If the memory address in
> error belongs to guest address space then guest kernel
> is responsible to take action. Hence the error is passed
> on to guest via KVM by invoking 0x200 NMI vector.
> 
> However, guest OS, as per PAPR, expects an error log
> upon such error. This patch registers a new hcall
> which is issued from 0x200 interrupt vector and builds
> the error log, copies the error log to rtas space and
> passes the address of the error log to guest
> 
> Enhancement to KVM to perform above functionality is
> already in upstream kernel.
> 
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>

Why do we have to maintain the error log inside the rtas blob? Can't we
just create a fixed MMIO region that is backed by an error log device in
QEMU?

Then this call would just always return that specific address and we'd
also have a single file that deals with all of the error reporting.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call Aravinda Prasad
  2014-08-26  6:02   ` David Gibson
@ 2014-08-27 10:37   ` Alexander Graf
  2014-08-28  6:38     ` Aravinda Prasad
  2014-09-07 20:47   ` Alexander Graf
  2 siblings, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-08-27 10:37 UTC (permalink / raw)
  To: Aravinda Prasad, aik, qemu-ppc, qemu-devel; +Cc: benh, paulus



On 25.08.14 15:45, Aravinda Prasad wrote:
> This patch adds FWNMI support in qemu for powerKVM
> guests by handling the ibm,nmi-register rtas call.
> Whenever OS issues ibm,nmi-register RTAS call, the
> machine check notification address is saved and the
> machine check interrupt vector 0x200 is patched to
> issue a private hcall.
> 
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> ---
>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr.h |    8 ++++
>  2 files changed, 98 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index 02ddbf9..1135d2b 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>      rtas_st(rets, 0, ret);
>  }
>  
> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
> +                                  sPAPREnvironment *spapr,
> +                                  uint32_t token, uint32_t nargs,
> +                                  target_ulong args,
> +                                  uint32_t nret, target_ulong rets)
> +{
> +    int i;
> +    uint32_t branch_inst = 0x48000002;
> +    target_ulong guest_machine_check_addr;
> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
> +    /*
> +     * Trampoline saves r3 in sprg2 and issues private hcall
> +     * to request qemu to build error log. QEMU builds the
> +     * error log, copies to rtas-blob and returns the address.
> +     * The initial 16 bytes in rtas-blob consists of saved srr0
> +     * and srr1 which we restore and pass on the actual error
> +     * log address to OS handled mcachine check notification
> +     * routine
> +     */
> +    uint32_t trampoline[] = {
> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
> +        0x38600000,    /* li      r3,0   */
> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
> +        0x6063f004,    /* ori     r3,r3,f004  */
> +        /* Issue H_CALL */
> +        0x44000022,    /*  sc      1     */

So up to here we're saving r3 in SPRG2 (how do we know that we can
clobber it?) and call our special hypercall.

But what does all the cruft below here do?

> +        0x7c9243a6,    /* mtspr r4 sprg2 */

Apart from th fact that your order is wrong, this destroys the value of
r3 that we saved above again.

> +        0xe8830000,    /* ld r4, 0(r3) */
> +        0x7c9a03a6,    /* mtspr r4, srr0 */
> +        0xe8830008,    /* ld r4, 8(r3) */
> +        0x7c9b03a6,    /* mtspr r4, srr1 */

Can't we just set srr0 and srr1 directly?

> +        0x38630010,    /* addi r3,r3,16 */
> +        0x7c9242a6,    /* mfspr r4 sprg2 */


> +        0x48000002,    /* Branch to address registered
> +                        * by OS. The branch address is
> +                        * patched below */
> +        0x48000000,    /* b . */
> +    };
> +    int total_inst = sizeof(trampoline) / sizeof(uint32_t);
> +
> +    /* Store the system reset and machine check address */
> +    guest_machine_check_addr = rtas_ld(args, 1);
> +
> +    /* Safety Check */
> +    if (sizeof(trampoline) >= MC_INTERRUPT_VECTOR_SIZE) {
> +        fprintf(stderr, "Unable to register ibm,nmi_register: "
> +                "Trampoline size exceeded\n");
> +        rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> +        return;
> +    }
> +
> +    /*
> +     * Update the branch instruction in trampoline with the absolute
> +     * machine check address requested by OS
> +     */
> +    branch_inst |= guest_machine_check_addr;

Does this even work? You're creating a relative branch here.


Alex

> +    memcpy(&trampoline[11], &branch_inst, sizeof(branch_inst));
> +
> +    /* Handle all Host/Guest LE/BE combinations */
> +    if ((*pcc->interrupts_big_endian)(cpu)) {
> +        for (i = 0; i < total_inst; i++) {
> +            trampoline[i] = cpu_to_be32(trampoline[i]);
> +        }
> +    } else {
> +        for (i = 0; i < total_inst; i++) {
> +            trampoline[i] = cpu_to_le32(trampoline[i]);
> +        }
> +    }
> +
> +    /* Patch 0x200 NMI interrupt vector memory area of guest */
> +    cpu_physical_memory_write(MC_INTERRUPT_VECTOR, trampoline,
> +                              sizeof(trampoline));
> +
> +    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> +}
> +
> +static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
> +                                   sPAPREnvironment *spapr,
> +                                   uint32_t token, uint32_t nargs,
> +                                   target_ulong args,
> +                                   uint32_t nret, target_ulong rets)
> +{
> +    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> +}
> +
>  static struct rtas_call {
>      const char *name;
>      spapr_rtas_fn fn;
> @@ -404,6 +489,12 @@ static void core_rtas_register_types(void)
>      spapr_rtas_register(RTAS_IBM_SET_SYSTEM_PARAMETER,
>                          "ibm,set-system-parameter",
>                          rtas_ibm_set_system_parameter);
> +    spapr_rtas_register(RTAS_IBM_NMI_REGISTER,
> +                        "ibm,nmi-register",
> +                        rtas_ibm_nmi_register);
> +    spapr_rtas_register(RTAS_IBM_NMI_INTERLOCK,
> +                        "ibm,nmi-interlock",
> +                        rtas_ibm_nmi_interlock);
>  }
>  
>  type_init(core_rtas_register_types)
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 57199f5..8c854ca 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -386,8 +386,10 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
>  #define RTAS_IBM_CONFIGURE_CONNECTOR            (RTAS_TOKEN_BASE + 0x1E)
>  #define RTAS_IBM_OS_TERM                        (RTAS_TOKEN_BASE + 0x1F)
>  #define RTAS_IBM_EXTENDED_OS_TERM               (RTAS_TOKEN_BASE + 0x20)
> +#define RTAS_IBM_NMI_REGISTER                   (RTAS_TOKEN_BASE + 0x21)
> +#define RTAS_IBM_NMI_INTERLOCK                  (RTAS_TOKEN_BASE + 0x22)
>  
> -#define RTAS_TOKEN_MAX                          (RTAS_TOKEN_BASE + 0x21)
> +#define RTAS_TOKEN_MAX                          (RTAS_TOKEN_BASE + 0x23)
>  
>  /* RTAS ibm,get-system-parameter token values */
>  #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS      20
> @@ -485,4 +487,8 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname,
>  int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
>                        sPAPRTCETable *tcet);
>  
> +/* Machine Check Interrupt related macros */
> +#define MC_INTERRUPT_VECTOR           0x200
> +#define MC_INTERRUPT_VECTOR_SIZE      0x100
> +
>  #endif /* !defined (__HW_SPAPR_H__) */
> 
> 

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check Aravinda Prasad
  2014-08-26  6:04   ` David Gibson
@ 2014-08-27 10:40   ` Alexander Graf
  2014-08-28  6:56     ` Aravinda Prasad
  1 sibling, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-08-27 10:40 UTC (permalink / raw)
  To: Aravinda Prasad, aik, qemu-ppc, qemu-devel; +Cc: benh, paulus



On 25.08.14 15:45, Aravinda Prasad wrote:
> 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 <aravinda@linux.vnet.ibm.com>

This patch doesn't make any sense. Both threads will issue an HCALL
which will get locked inside of QEMU, so we'll never see the case where
both hypercalls get processed at the same time.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/5] target-ppc: Build error log
  2014-08-27  9:50   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
@ 2014-08-28  6:12     ` Aravinda Prasad
  2014-08-28  8:36       ` Alexander Graf
  0 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-28  6:12 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On Wednesday 27 August 2014 03:20 PM, Alexander Graf wrote:
> 
> 
> On 25.08.14 15:45, Aravinda Prasad wrote:
>> Whenever there is a physical memory error due to bit
>> flips, which cannot be corrected by hardware, the error
>> is passed on to the kernel. If the memory address in
>> error belongs to guest address space then guest kernel
>> is responsible to take action. Hence the error is passed
>> on to guest via KVM by invoking 0x200 NMI vector.
>>
>> However, guest OS, as per PAPR, expects an error log
>> upon such error. This patch registers a new hcall
>> which is issued from 0x200 interrupt vector and builds
>> the error log, copies the error log to rtas space and
>> passes the address of the error log to guest
>>
>> Enhancement to KVM to perform above functionality is
>> already in upstream kernel.
>>
>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> 
> Why do we have to maintain the error log inside the rtas blob? Can't we
> just create a fixed MMIO region that is backed by an error log device in
> QEMU?
> 
> Then this call would just always return that specific address and we'd
> also have a single file that deals with all of the error reporting.

PAPR requires error log to be inside rtas space. Hence guest OS
explicitly checks if error log is inside rtas space.

VALID_FWNMI_BUFFER does this check inside fwnmi_get_errinfo() in the kernel.

Regards,
Aravinda

> 
> 
> Alex
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-27 10:37   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
@ 2014-08-28  6:38     ` Aravinda Prasad
  2014-08-28  8:37       ` Alexander Graf
  0 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-28  6:38 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
> 
> 
> On 25.08.14 15:45, Aravinda Prasad wrote:
>> This patch adds FWNMI support in qemu for powerKVM
>> guests by handling the ibm,nmi-register rtas call.
>> Whenever OS issues ibm,nmi-register RTAS call, the
>> machine check notification address is saved and the
>> machine check interrupt vector 0x200 is patched to
>> issue a private hcall.
>>
>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>> ---
>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/hw/ppc/spapr.h |    8 ++++
>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>> index 02ddbf9..1135d2b 100644
>> --- a/hw/ppc/spapr_rtas.c
>> +++ b/hw/ppc/spapr_rtas.c
>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>      rtas_st(rets, 0, ret);
>>  }
>>  
>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>> +                                  sPAPREnvironment *spapr,
>> +                                  uint32_t token, uint32_t nargs,
>> +                                  target_ulong args,
>> +                                  uint32_t nret, target_ulong rets)
>> +{
>> +    int i;
>> +    uint32_t branch_inst = 0x48000002;
>> +    target_ulong guest_machine_check_addr;
>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>> +    /*
>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>> +     * to request qemu to build error log. QEMU builds the
>> +     * error log, copies to rtas-blob and returns the address.
>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>> +     * and srr1 which we restore and pass on the actual error
>> +     * log address to OS handled mcachine check notification
>> +     * routine
>> +     */
>> +    uint32_t trampoline[] = {
>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>> +        0x38600000,    /* li      r3,0   */
>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>> +        0x6063f004,    /* ori     r3,r3,f004  */
>> +        /* Issue H_CALL */
>> +        0x44000022,    /*  sc      1     */
> 
> So up to here we're saving r3 in SPRG2 (how do we know that we can
> clobber it?) and call our special hypercall.
> 
> But what does all the cruft below here do?

The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
can clobber SPRG2 after hcall returns. I have included a comment in
patch 3/5 while building error log. I think better I add one here as well.

> 
>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
> 
> Apart from th fact that your order is wrong, this destroys the value of
> r3 that we saved above again.

SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
KVMPPC_H_REPORT_ERR hcall returns.

> 
>> +        0xe8830000,    /* ld r4, 0(r3) */
>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>> +        0xe8830008,    /* ld r4, 8(r3) */
>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
> 
> Can't we just set srr0 and srr1 directly?

I checked for instructions in ISA which set srr0/1 directly given an
address, but could not find any such instructions.

> 
>> +        0x38630010,    /* addi r3,r3,16 */
>> +        0x7c9242a6,    /* mfspr r4 sprg2 */
> 
> 
>> +        0x48000002,    /* Branch to address registered
>> +                        * by OS. The branch address is
>> +                        * patched below */
>> +        0x48000000,    /* b . */
>> +    };
>> +    int total_inst = sizeof(trampoline) / sizeof(uint32_t);
>> +
>> +    /* Store the system reset and machine check address */
>> +    guest_machine_check_addr = rtas_ld(args, 1);
>> +
>> +    /* Safety Check */
>> +    if (sizeof(trampoline) >= MC_INTERRUPT_VECTOR_SIZE) {
>> +        fprintf(stderr, "Unable to register ibm,nmi_register: "
>> +                "Trampoline size exceeded\n");
>> +        rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
>> +        return;
>> +    }
>> +
>> +    /*
>> +     * Update the branch instruction in trampoline with the absolute
>> +     * machine check address requested by OS
>> +     */
>> +    branch_inst |= guest_machine_check_addr;
> 
> Does this even work? You're creating a relative branch here.

We do an absolute branch here. guest_machine_check_addr contains the
physical address of machine check handler. We update the branch
instruction operand to do an absolute branch to this physical address.
Also when executing 0x200 address translations are off.

During testing I am able to see the machine check handler invoked by
this branch instruction. The disassembly of instructions from gdb at
0x200 correctly reflected the branch target.

Regards,
Aravinda

> 
> 
> Alex
> 
>> +    memcpy(&trampoline[11], &branch_inst, sizeof(branch_inst));
>> +
>> +    /* Handle all Host/Guest LE/BE combinations */
>> +    if ((*pcc->interrupts_big_endian)(cpu)) {
>> +        for (i = 0; i < total_inst; i++) {
>> +            trampoline[i] = cpu_to_be32(trampoline[i]);
>> +        }
>> +    } else {
>> +        for (i = 0; i < total_inst; i++) {
>> +            trampoline[i] = cpu_to_le32(trampoline[i]);
>> +        }
>> +    }
>> +
>> +    /* Patch 0x200 NMI interrupt vector memory area of guest */
>> +    cpu_physical_memory_write(MC_INTERRUPT_VECTOR, trampoline,
>> +                              sizeof(trampoline));
>> +
>> +    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>> +}
>> +
>> +static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
>> +                                   sPAPREnvironment *spapr,
>> +                                   uint32_t token, uint32_t nargs,
>> +                                   target_ulong args,
>> +                                   uint32_t nret, target_ulong rets)
>> +{
>> +    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>> +}
>> +
>>  static struct rtas_call {
>>      const char *name;
>>      spapr_rtas_fn fn;
>> @@ -404,6 +489,12 @@ static void core_rtas_register_types(void)
>>      spapr_rtas_register(RTAS_IBM_SET_SYSTEM_PARAMETER,
>>                          "ibm,set-system-parameter",
>>                          rtas_ibm_set_system_parameter);
>> +    spapr_rtas_register(RTAS_IBM_NMI_REGISTER,
>> +                        "ibm,nmi-register",
>> +                        rtas_ibm_nmi_register);
>> +    spapr_rtas_register(RTAS_IBM_NMI_INTERLOCK,
>> +                        "ibm,nmi-interlock",
>> +                        rtas_ibm_nmi_interlock);
>>  }
>>  
>>  type_init(core_rtas_register_types)
>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>> index 57199f5..8c854ca 100644
>> --- a/include/hw/ppc/spapr.h
>> +++ b/include/hw/ppc/spapr.h
>> @@ -386,8 +386,10 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
>>  #define RTAS_IBM_CONFIGURE_CONNECTOR            (RTAS_TOKEN_BASE + 0x1E)
>>  #define RTAS_IBM_OS_TERM                        (RTAS_TOKEN_BASE + 0x1F)
>>  #define RTAS_IBM_EXTENDED_OS_TERM               (RTAS_TOKEN_BASE + 0x20)
>> +#define RTAS_IBM_NMI_REGISTER                   (RTAS_TOKEN_BASE + 0x21)
>> +#define RTAS_IBM_NMI_INTERLOCK                  (RTAS_TOKEN_BASE + 0x22)
>>  
>> -#define RTAS_TOKEN_MAX                          (RTAS_TOKEN_BASE + 0x21)
>> +#define RTAS_TOKEN_MAX                          (RTAS_TOKEN_BASE + 0x23)
>>  
>>  /* RTAS ibm,get-system-parameter token values */
>>  #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS      20
>> @@ -485,4 +487,8 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname,
>>  int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
>>                        sPAPRTCETable *tcet);
>>  
>> +/* Machine Check Interrupt related macros */
>> +#define MC_INTERRUPT_VECTOR           0x200
>> +#define MC_INTERRUPT_VECTOR_SIZE      0x100
>> +
>>  #endif /* !defined (__HW_SPAPR_H__) */
>>
>>
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check
  2014-08-27 10:40   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
@ 2014-08-28  6:56     ` Aravinda Prasad
  2014-08-28  8:39       ` Alexander Graf
  2014-08-28  8:42       ` Alexander Graf
  0 siblings, 2 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-28  6:56 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On Wednesday 27 August 2014 04:10 PM, Alexander Graf wrote:
> 
> 
> On 25.08.14 15:45, Aravinda Prasad wrote:
>> 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 <aravinda@linux.vnet.ibm.com>
> 
> This patch doesn't make any sense. Both threads will issue an HCALL
> which will get locked inside of QEMU, so we'll never see the case where
> both hypercalls get processed at the same time.

AFAIK, only one thread can succeed entering qemu upon parallel hcall
from different guest CPUs as it is gated by a lock. Hence one hcall is
processed at a time.

As per PAPR, we don't want any other KVMPPC_H_REPORT_ERR hcall to be
processed at the same time and further KVMPPC_H_REPORT_ERR hcall thus
issued should wait until the OS issues ibm,nmi-interlock.

Thanks for the review.

Regards,
Aravinda

> 
> 
> Alex
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/5] target-ppc: Build error log
  2014-08-28  6:12     ` Aravinda Prasad
@ 2014-08-28  8:36       ` Alexander Graf
  2014-08-28 10:21         ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-08-28  8:36 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On 28.08.14 08:12, Aravinda Prasad wrote:
> 
> 
> On Wednesday 27 August 2014 03:20 PM, Alexander Graf wrote:
>>
>>
>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>> Whenever there is a physical memory error due to bit
>>> flips, which cannot be corrected by hardware, the error
>>> is passed on to the kernel. If the memory address in
>>> error belongs to guest address space then guest kernel
>>> is responsible to take action. Hence the error is passed
>>> on to guest via KVM by invoking 0x200 NMI vector.
>>>
>>> However, guest OS, as per PAPR, expects an error log
>>> upon such error. This patch registers a new hcall
>>> which is issued from 0x200 interrupt vector and builds
>>> the error log, copies the error log to rtas space and
>>> passes the address of the error log to guest
>>>
>>> Enhancement to KVM to perform above functionality is
>>> already in upstream kernel.
>>>
>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>
>> Why do we have to maintain the error log inside the rtas blob? Can't we
>> just create a fixed MMIO region that is backed by an error log device in
>> QEMU?
>>
>> Then this call would just always return that specific address and we'd
>> also have a single file that deals with all of the error reporting.
> 
> PAPR requires error log to be inside rtas space. Hence guest OS
> explicitly checks if error log is inside rtas space.
> 
> VALID_FWNMI_BUFFER does this check inside fwnmi_get_errinfo() in the kernel.

So why not put it at 0x7000 then?


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-28  6:38     ` Aravinda Prasad
@ 2014-08-28  8:37       ` Alexander Graf
  2014-08-28 13:06         ` Tom Musta
  2014-08-28 17:42         ` Aravinda Prasad
  0 siblings, 2 replies; 73+ messages in thread
From: Alexander Graf @ 2014-08-28  8:37 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On 28.08.14 08:38, Aravinda Prasad wrote:
> 
> 
> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>
>>
>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>> This patch adds FWNMI support in qemu for powerKVM
>>> guests by handling the ibm,nmi-register rtas call.
>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>> machine check notification address is saved and the
>>> machine check interrupt vector 0x200 is patched to
>>> issue a private hcall.
>>>
>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>> ---
>>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>  include/hw/ppc/spapr.h |    8 ++++
>>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>> index 02ddbf9..1135d2b 100644
>>> --- a/hw/ppc/spapr_rtas.c
>>> +++ b/hw/ppc/spapr_rtas.c
>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>      rtas_st(rets, 0, ret);
>>>  }
>>>  
>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>> +                                  sPAPREnvironment *spapr,
>>> +                                  uint32_t token, uint32_t nargs,
>>> +                                  target_ulong args,
>>> +                                  uint32_t nret, target_ulong rets)
>>> +{
>>> +    int i;
>>> +    uint32_t branch_inst = 0x48000002;
>>> +    target_ulong guest_machine_check_addr;
>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>> +    /*
>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>> +     * to request qemu to build error log. QEMU builds the
>>> +     * error log, copies to rtas-blob and returns the address.
>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>> +     * and srr1 which we restore and pass on the actual error
>>> +     * log address to OS handled mcachine check notification
>>> +     * routine
>>> +     */
>>> +    uint32_t trampoline[] = {
>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>> +        0x38600000,    /* li      r3,0   */
>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>> +        /* Issue H_CALL */
>>> +        0x44000022,    /*  sc      1     */
>>
>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>> clobber it?) and call our special hypercall.
>>
>> But what does all the cruft below here do?
> 
> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
> can clobber SPRG2 after hcall returns. I have included a comment in
> patch 3/5 while building error log. I think better I add one here as well.
> 
>>
>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>
>> Apart from th fact that your order is wrong, this destroys the value of
>> r3 that we saved above again.
> 
> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
> KVMPPC_H_REPORT_ERR hcall returns.
> 
>>
>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>
>> Can't we just set srr0 and srr1 directly?
> 
> I checked for instructions in ISA which set srr0/1 directly given an
> address, but could not find any such instructions.

I mean from QEMU :).

> 
>>
>>> +        0x38630010,    /* addi r3,r3,16 */
>>> +        0x7c9242a6,    /* mfspr r4 sprg2 */
>>
>>
>>> +        0x48000002,    /* Branch to address registered
>>> +                        * by OS. The branch address is
>>> +                        * patched below */
>>> +        0x48000000,    /* b . */
>>> +    };
>>> +    int total_inst = sizeof(trampoline) / sizeof(uint32_t);
>>> +
>>> +    /* Store the system reset and machine check address */
>>> +    guest_machine_check_addr = rtas_ld(args, 1);
>>> +
>>> +    /* Safety Check */
>>> +    if (sizeof(trampoline) >= MC_INTERRUPT_VECTOR_SIZE) {
>>> +        fprintf(stderr, "Unable to register ibm,nmi_register: "
>>> +                "Trampoline size exceeded\n");
>>> +        rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
>>> +        return;
>>> +    }
>>> +
>>> +    /*
>>> +     * Update the branch instruction in trampoline with the absolute
>>> +     * machine check address requested by OS
>>> +     */
>>> +    branch_inst |= guest_machine_check_addr;
>>
>> Does this even work? You're creating a relative branch here.
> 
> We do an absolute branch here. guest_machine_check_addr contains the
> physical address of machine check handler. We update the branch
> instruction operand to do an absolute branch to this physical address.

Where? I don't see the absolute bit anywhere.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check
  2014-08-28  6:56     ` Aravinda Prasad
@ 2014-08-28  8:39       ` Alexander Graf
  2014-08-28  8:42       ` Alexander Graf
  1 sibling, 0 replies; 73+ messages in thread
From: Alexander Graf @ 2014-08-28  8:39 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On 28.08.14 08:56, Aravinda Prasad wrote:
> 
> 
> On Wednesday 27 August 2014 04:10 PM, Alexander Graf wrote:
>>
>>
>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>> 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 <aravinda@linux.vnet.ibm.com>
>>
>> This patch doesn't make any sense. Both threads will issue an HCALL
>> which will get locked inside of QEMU, so we'll never see the case where
>> both hypercalls get processed at the same time.
> 
> AFAIK, only one thread can succeed entering qemu upon parallel hcall
> from different guest CPUs as it is gated by a lock. Hence one hcall is
> processed at a time.

Exactly, so at the point of the if(mc_in_progress == 1), mc_in_progress
will always be 0.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check
  2014-08-28  6:56     ` Aravinda Prasad
  2014-08-28  8:39       ` Alexander Graf
@ 2014-08-28  8:42       ` Alexander Graf
  2014-08-28 17:45         ` Aravinda Prasad
  1 sibling, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-08-28  8:42 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On 28.08.14 08:56, Aravinda Prasad wrote:
> 
> 
> On Wednesday 27 August 2014 04:10 PM, Alexander Graf wrote:
>>
>>
>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>> 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 <aravinda@linux.vnet.ibm.com>
>>
>> This patch doesn't make any sense. Both threads will issue an HCALL
>> which will get locked inside of QEMU, so we'll never see the case where
>> both hypercalls get processed at the same time.
> 
> AFAIK, only one thread can succeed entering qemu upon parallel hcall
> from different guest CPUs as it is gated by a lock. Hence one hcall is
> processed at a time.
> 
> As per PAPR, we don't want any other KVMPPC_H_REPORT_ERR hcall to be
> processed at the same time and further KVMPPC_H_REPORT_ERR hcall thus
> issued should wait until the OS issues ibm,nmi-interlock.

Oh, now I understand. The locking time is from
[h_report_mc_err...rtas_ibm_nmi_interlock].

This should definitely go into the comment on the check in
h_report_mc_err. In fact, remove the fact that only one thread can
execute and instead write where the lock gets unset and that during that
phase only one vcpu may process the NMI.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/5] target-ppc: Build error log
  2014-08-28  8:36       ` Alexander Graf
@ 2014-08-28 10:21         ` Benjamin Herrenschmidt
  2014-08-28 10:29           ` Alexander Graf
  0 siblings, 1 reply; 73+ messages in thread
From: Benjamin Herrenschmidt @ 2014-08-28 10:21 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc, Aravinda Prasad, aik, qemu-devel, paulus

On Thu, 2014-08-28 at 10:36 +0200, Alexander Graf wrote:

> So why not put it at 0x7000 then?

Because PAPR says it has to be inside RTAS iirc

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/5] target-ppc: Build error log
  2014-08-28 10:21         ` Benjamin Herrenschmidt
@ 2014-08-28 10:29           ` Alexander Graf
  2014-08-28 10:33             ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-08-28 10:29 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: qemu-ppc, Aravinda Prasad, aik, qemu-devel, paulus



On 28.08.14 12:21, Benjamin Herrenschmidt wrote:
> On Thu, 2014-08-28 at 10:36 +0200, Alexander Graf wrote:
> 
>> So why not put it at 0x7000 then?
> 
> Because PAPR says it has to be inside RTAS iirc

Please show me the section of PAPR that does say so.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/5] target-ppc: Build error log
  2014-08-28 10:29           ` Alexander Graf
@ 2014-08-28 10:33             ` Benjamin Herrenschmidt
  2014-08-28 10:34               ` Benjamin Herrenschmidt
  2014-08-28 17:17               ` Aravinda Prasad
  0 siblings, 2 replies; 73+ messages in thread
From: Benjamin Herrenschmidt @ 2014-08-28 10:33 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc, Aravinda Prasad, aik, qemu-devel, paulus

On Thu, 2014-08-28 at 12:29 +0200, Alexander Graf wrote:
> 
> On 28.08.14 12:21, Benjamin Herrenschmidt wrote:
> > On Thu, 2014-08-28 at 10:36 +0200, Alexander Graf wrote:
> > 
> >> So why not put it at 0x7000 then?
> > 
> > Because PAPR says it has to be inside RTAS iirc
> 
> Please show me the section of PAPR that does say so.

Actually, we should probably support both options:

PAPR V2.7

7.3.14 Firmware Assisted Non-Maskable Interrupts Option (FWNMI)

<<
The difference between ibm,nmi-register and ibm,nmi-register-2 is that
ibm,nmi-register allocates the error reporting
structure in RTAS space while ibm,nmi-register-2 places the error
reporting structure in real page 7. New OS designs
should use ibm,nmi-register since support for ibm,nmi-register-2 will be
terminated at some future date.
>>

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/5] target-ppc: Build error log
  2014-08-28 10:33             ` Benjamin Herrenschmidt
@ 2014-08-28 10:34               ` Benjamin Herrenschmidt
  2014-08-28 17:17               ` Aravinda Prasad
  1 sibling, 0 replies; 73+ messages in thread
From: Benjamin Herrenschmidt @ 2014-08-28 10:34 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc, Aravinda Prasad, aik, qemu-devel, paulus

On Thu, 2014-08-28 at 20:33 +1000, Benjamin Herrenschmidt wrote:
> On Thu, 2014-08-28 at 12:29 +0200, Alexander Graf wrote:
> > 
> > On 28.08.14 12:21, Benjamin Herrenschmidt wrote:
> > > On Thu, 2014-08-28 at 10:36 +0200, Alexander Graf wrote:
> > > 
> > >> So why not put it at 0x7000 then?
> > > 
> > > Because PAPR says it has to be inside RTAS iirc
> > 
> > Please show me the section of PAPR that does say so.
> 
> Actually, we should probably support both options:
> 
> PAPR V2.7
> 
> 7.3.14 Firmware Assisted Non-Maskable Interrupts Option (FWNMI)
> 
> <<
> The difference between ibm,nmi-register and ibm,nmi-register-2 is that
> ibm,nmi-register allocates the error reporting
> structure in RTAS space while ibm,nmi-register-2 places the error
> reporting structure in real page 7. New OS designs
> should use ibm,nmi-register since support for ibm,nmi-register-2 will be
> terminated at some future date.
> >>

Also of interest:

<<
As with all first level interrupt service routines, the SPRG-2 register
is used to save the state of one general purpose
register while the processor computes the location of its state save
area.
>>

Cheers,
Ben.

> 
> Cheers,
> Ben.
> 

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob Aravinda Prasad
  2014-08-26  5:38   ` David Gibson
@ 2014-08-28 10:40   ` Alexander Graf
  2014-08-28 18:20     ` Aravinda Prasad
  2014-09-01  7:46   ` [Qemu-devel] " Alexey Kardashevskiy
  2 siblings, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-08-28 10:40 UTC (permalink / raw)
  To: Aravinda Prasad, aik, qemu-ppc, qemu-devel; +Cc: benh, paulus



On 25.08.14 15:45, Aravinda Prasad wrote:
> Extend rtas-blob to accommodate error log. Error log
> structure is saved in rtas space upon a machine check
> exception.
> 
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>

I can't say I'm a big fan of this patch. Can we somehow separate that
NMI page from the RTAS blob? Also I'd definitely prefer if we keep
rtas_entry == rtas_addr - if nothing else for the sake of backwards
compatibility.

So how about we lay out the structure in memory like this:

  [ spapr-rtas.bin ]
  [ padding to 4k boundary or whatever sPAPR requires ]
  [ 4k NMI region ]

Then the only thing we'd have to really change internally is the size
information of the rtas blob.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-28  8:37       ` Alexander Graf
@ 2014-08-28 13:06         ` Tom Musta
  2014-08-28 13:11           ` Alexander Graf
  2014-08-28 17:42         ` Aravinda Prasad
  1 sibling, 1 reply; 73+ messages in thread
From: Tom Musta @ 2014-08-28 13:06 UTC (permalink / raw)
  To: Alexander Graf, Aravinda Prasad; +Cc: aik, benh, qemu-ppc, qemu-devel, paulus

On 8/28/2014 3:37 AM, Alexander Graf wrote:
> 
> 
> On 28.08.14 08:38, Aravinda Prasad wrote:
>>
>>
>> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>>
>>>
>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>> This patch adds FWNMI support in qemu for powerKVM
>>>> guests by handling the ibm,nmi-register rtas call.
>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>> machine check notification address is saved and the
>>>> machine check interrupt vector 0x200 is patched to
>>>> issue a private hcall.
>>>>
>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>> ---
>>>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>  include/hw/ppc/spapr.h |    8 ++++
>>>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>> index 02ddbf9..1135d2b 100644
>>>> --- a/hw/ppc/spapr_rtas.c
>>>> +++ b/hw/ppc/spapr_rtas.c
>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>      rtas_st(rets, 0, ret);
>>>>  }
>>>>  
>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>> +                                  sPAPREnvironment *spapr,
>>>> +                                  uint32_t token, uint32_t nargs,
>>>> +                                  target_ulong args,
>>>> +                                  uint32_t nret, target_ulong rets)
>>>> +{
>>>> +    int i;
>>>> +    uint32_t branch_inst = 0x48000002;
>>>> +    target_ulong guest_machine_check_addr;
>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>> +    /*
>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>> +     * to request qemu to build error log. QEMU builds the
>>>> +     * error log, copies to rtas-blob and returns the address.
>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>> +     * and srr1 which we restore and pass on the actual error
>>>> +     * log address to OS handled mcachine check notification
>>>> +     * routine
>>>> +     */
>>>> +    uint32_t trampoline[] = {
>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>> +        0x38600000,    /* li      r3,0   */
>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>> +        /* Issue H_CALL */
>>>> +        0x44000022,    /*  sc      1     */
>>>
>>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>>> clobber it?) and call our special hypercall.
>>>
>>> But what does all the cruft below here do?
>>
>> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
>> can clobber SPRG2 after hcall returns. I have included a comment in
>> patch 3/5 while building error log. I think better I add one here as well.
>>
>>>
>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>
>>> Apart from th fact that your order is wrong, this destroys the value of
>>> r3 that we saved above again.
>>
>> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
>> KVMPPC_H_REPORT_ERR hcall returns.
>>
>>>
>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>
>>> Can't we just set srr0 and srr1 directly?
>>
>> I checked for instructions in ISA which set srr0/1 directly given an
>> address, but could not find any such instructions.
> 
> I mean from QEMU :).
> 
>>
>>>
>>>> +        0x38630010,    /* addi r3,r3,16 */
>>>> +        0x7c9242a6,    /* mfspr r4 sprg2 */
>>>
>>>
>>>> +        0x48000002,    /* Branch to address registered
>>>> +                        * by OS. The branch address is
>>>> +                        * patched below */
>>>> +        0x48000000,    /* b . */
>>>> +    };
>>>> +    int total_inst = sizeof(trampoline) / sizeof(uint32_t);
>>>> +
>>>> +    /* Store the system reset and machine check address */
>>>> +    guest_machine_check_addr = rtas_ld(args, 1);
>>>> +
>>>> +    /* Safety Check */
>>>> +    if (sizeof(trampoline) >= MC_INTERRUPT_VECTOR_SIZE) {
>>>> +        fprintf(stderr, "Unable to register ibm,nmi_register: "
>>>> +                "Trampoline size exceeded\n");
>>>> +        rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
>>>> +        return;
>>>> +    }
>>>> +
>>>> +    /*
>>>> +     * Update the branch instruction in trampoline with the absolute
>>>> +     * machine check address requested by OS
>>>> +     */
>>>> +    branch_inst |= guest_machine_check_addr;
>>>
>>> Does this even work? You're creating a relative branch here.
>>
>> We do an absolute branch here. guest_machine_check_addr contains the
>> physical address of machine check handler. We update the branch
>> instruction operand to do an absolute branch to this physical address.
> 
> Where? I don't see the absolute bit anywhere.
> 

Alex:

It is here:

+static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
+                                  sPAPREnvironment *spapr,
+                                  uint32_t token, uint32_t nargs,
+                                  target_ulong args,
+                                  uint32_t nret, target_ulong rets)
+{
+    int i;
+    uint32_t branch_inst = 0x48000002;
                                     ^
                                     ^

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-28 13:06         ` Tom Musta
@ 2014-08-28 13:11           ` Alexander Graf
  0 siblings, 0 replies; 73+ messages in thread
From: Alexander Graf @ 2014-08-28 13:11 UTC (permalink / raw)
  To: Tom Musta, Aravinda Prasad; +Cc: aik, benh, qemu-ppc, qemu-devel, paulus



On 28.08.14 15:06, Tom Musta wrote:
> On 8/28/2014 3:37 AM, Alexander Graf wrote:
>>
>>
>> On 28.08.14 08:38, Aravinda Prasad wrote:
>>>
>>>
>>> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>>>
>>>>
>>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>>> This patch adds FWNMI support in qemu for powerKVM
>>>>> guests by handling the ibm,nmi-register rtas call.
>>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>>> machine check notification address is saved and the
>>>>> machine check interrupt vector 0x200 is patched to
>>>>> issue a private hcall.
>>>>>
>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>> ---
>>>>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>  include/hw/ppc/spapr.h |    8 ++++
>>>>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>> index 02ddbf9..1135d2b 100644
>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>>      rtas_st(rets, 0, ret);
>>>>>  }
>>>>>  
>>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>>> +                                  sPAPREnvironment *spapr,
>>>>> +                                  uint32_t token, uint32_t nargs,
>>>>> +                                  target_ulong args,
>>>>> +                                  uint32_t nret, target_ulong rets)
>>>>> +{
>>>>> +    int i;
>>>>> +    uint32_t branch_inst = 0x48000002;
>>>>> +    target_ulong guest_machine_check_addr;
>>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>>> +    /*
>>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>>> +     * to request qemu to build error log. QEMU builds the
>>>>> +     * error log, copies to rtas-blob and returns the address.
>>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>>> +     * and srr1 which we restore and pass on the actual error
>>>>> +     * log address to OS handled mcachine check notification
>>>>> +     * routine
>>>>> +     */
>>>>> +    uint32_t trampoline[] = {
>>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>>> +        0x38600000,    /* li      r3,0   */
>>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>>> +        /* Issue H_CALL */
>>>>> +        0x44000022,    /*  sc      1     */
>>>>
>>>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>>>> clobber it?) and call our special hypercall.
>>>>
>>>> But what does all the cruft below here do?
>>>
>>> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
>>> can clobber SPRG2 after hcall returns. I have included a comment in
>>> patch 3/5 while building error log. I think better I add one here as well.
>>>
>>>>
>>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>>
>>>> Apart from th fact that your order is wrong, this destroys the value of
>>>> r3 that we saved above again.
>>>
>>> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
>>> KVMPPC_H_REPORT_ERR hcall returns.
>>>
>>>>
>>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>>
>>>> Can't we just set srr0 and srr1 directly?
>>>
>>> I checked for instructions in ISA which set srr0/1 directly given an
>>> address, but could not find any such instructions.
>>
>> I mean from QEMU :).
>>
>>>
>>>>
>>>>> +        0x38630010,    /* addi r3,r3,16 */
>>>>> +        0x7c9242a6,    /* mfspr r4 sprg2 */
>>>>
>>>>
>>>>> +        0x48000002,    /* Branch to address registered
>>>>> +                        * by OS. The branch address is
>>>>> +                        * patched below */
>>>>> +        0x48000000,    /* b . */
>>>>> +    };
>>>>> +    int total_inst = sizeof(trampoline) / sizeof(uint32_t);
>>>>> +
>>>>> +    /* Store the system reset and machine check address */
>>>>> +    guest_machine_check_addr = rtas_ld(args, 1);
>>>>> +
>>>>> +    /* Safety Check */
>>>>> +    if (sizeof(trampoline) >= MC_INTERRUPT_VECTOR_SIZE) {
>>>>> +        fprintf(stderr, "Unable to register ibm,nmi_register: "
>>>>> +                "Trampoline size exceeded\n");
>>>>> +        rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
>>>>> +        return;
>>>>> +    }
>>>>> +
>>>>> +    /*
>>>>> +     * Update the branch instruction in trampoline with the absolute
>>>>> +     * machine check address requested by OS
>>>>> +     */
>>>>> +    branch_inst |= guest_machine_check_addr;
>>>>
>>>> Does this even work? You're creating a relative branch here.
>>>
>>> We do an absolute branch here. guest_machine_check_addr contains the
>>> physical address of machine check handler. We update the branch
>>> instruction operand to do an absolute branch to this physical address.
>>
>> Where? I don't see the absolute bit anywhere.
>>
> 
> Alex:
> 
> It is here:
> 
> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
> +                                  sPAPREnvironment *spapr,
> +                                  uint32_t token, uint32_t nargs,
> +                                  target_ulong args,
> +                                  uint32_t nret, target_ulong rets)
> +{
> +    int i;
> +    uint32_t branch_inst = 0x48000002;

Ah, I was looking inside of the instruction stream, sorry :).


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/5] target-ppc: Build error log
  2014-08-28 10:33             ` Benjamin Herrenschmidt
  2014-08-28 10:34               ` Benjamin Herrenschmidt
@ 2014-08-28 17:17               ` Aravinda Prasad
  2014-08-28 20:07                 ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-28 17:17 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: aik, qemu-ppc, Alexander Graf, paulus, qemu-devel



On Thursday 28 August 2014 04:03 PM, Benjamin Herrenschmidt wrote:
> On Thu, 2014-08-28 at 12:29 +0200, Alexander Graf wrote:
>>
>> On 28.08.14 12:21, Benjamin Herrenschmidt wrote:
>>> On Thu, 2014-08-28 at 10:36 +0200, Alexander Graf wrote:
>>>
>>>> So why not put it at 0x7000 then?
>>>
>>> Because PAPR says it has to be inside RTAS iirc
>>
>> Please show me the section of PAPR that does say so.
> 
> Actually, we should probably support both options:
> 
> PAPR V2.7
> 
> 7.3.14 Firmware Assisted Non-Maskable Interrupts Option (FWNMI)
> 
> <<
> The difference between ibm,nmi-register and ibm,nmi-register-2 is that
> ibm,nmi-register allocates the error reporting
> structure in RTAS space while ibm,nmi-register-2 places the error
> reporting structure in real page 7. New OS designs
> should use ibm,nmi-register since support for ibm,nmi-register-2 will be
> terminated at some future date.

Should we avoid having error log in 0x7000? As per above only
ibm,nmi-register-2 places error log in 0x7000 which will be terminated
in future?

>>>
> 
> Cheers,
> Ben.
> 
> 
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-28  8:37       ` Alexander Graf
  2014-08-28 13:06         ` Tom Musta
@ 2014-08-28 17:42         ` Aravinda Prasad
  2014-08-28 22:16           ` Alexander Graf
  1 sibling, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-28 17:42 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On Thursday 28 August 2014 02:07 PM, Alexander Graf wrote:
> 
> 
> On 28.08.14 08:38, Aravinda Prasad wrote:
>>
>>
>> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>>
>>>
>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>> This patch adds FWNMI support in qemu for powerKVM
>>>> guests by handling the ibm,nmi-register rtas call.
>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>> machine check notification address is saved and the
>>>> machine check interrupt vector 0x200 is patched to
>>>> issue a private hcall.
>>>>
>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>> ---
>>>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>  include/hw/ppc/spapr.h |    8 ++++
>>>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>> index 02ddbf9..1135d2b 100644
>>>> --- a/hw/ppc/spapr_rtas.c
>>>> +++ b/hw/ppc/spapr_rtas.c
>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>      rtas_st(rets, 0, ret);
>>>>  }
>>>>  
>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>> +                                  sPAPREnvironment *spapr,
>>>> +                                  uint32_t token, uint32_t nargs,
>>>> +                                  target_ulong args,
>>>> +                                  uint32_t nret, target_ulong rets)
>>>> +{
>>>> +    int i;
>>>> +    uint32_t branch_inst = 0x48000002;
>>>> +    target_ulong guest_machine_check_addr;
>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>> +    /*
>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>> +     * to request qemu to build error log. QEMU builds the
>>>> +     * error log, copies to rtas-blob and returns the address.
>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>> +     * and srr1 which we restore and pass on the actual error
>>>> +     * log address to OS handled mcachine check notification
>>>> +     * routine
>>>> +     */
>>>> +    uint32_t trampoline[] = {
>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>> +        0x38600000,    /* li      r3,0   */
>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>> +        /* Issue H_CALL */
>>>> +        0x44000022,    /*  sc      1     */
>>>
>>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>>> clobber it?) and call our special hypercall.
>>>
>>> But what does all the cruft below here do?
>>
>> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
>> can clobber SPRG2 after hcall returns. I have included a comment in
>> patch 3/5 while building error log. I think better I add one here as well.
>>
>>>
>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>
>>> Apart from th fact that your order is wrong, this destroys the value of
>>> r3 that we saved above again.
>>
>> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
>> KVMPPC_H_REPORT_ERR hcall returns.
>>
>>>
>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>
>>> Can't we just set srr0 and srr1 directly?
>>
>> I checked for instructions in ISA which set srr0/1 directly given an
>> address, but could not find any such instructions.
> 
> I mean from QEMU :).

srr0 and srr1, which are properly set when 0x200 is invoked, are
clobbered when we return from KVMPPC_H_REPORT_ERR hcall. I think they
are modified before issuing rfid (I can see them getting clobbered from
QEMU monitor). However when we jump to OS registered machine check
routine srr0 and srr1 should reflect the value they had when 0x200 was
invoked.

Hence srr0 and srr1 are saved in hcall and restored when we return from
hcall. Also we don't have enough scratch registers available to save
these before invoking hcall from 0x200.

Or am I missing other ways to do this from QEMU?

Regards,
Aravinda

> 
>>
>>>
>>>> +        0x38630010,    /* addi r3,r3,16 */
>>>> +        0x7c9242a6,    /* mfspr r4 sprg2 */
>>>
>>>
>>>> +        0x48000002,    /* Branch to address registered
>>>> +                        * by OS. The branch address is
>>>> +                        * patched below */
>>>> +        0x48000000,    /* b . */
>>>> +    };
>>>> +    int total_inst = sizeof(trampoline) / sizeof(uint32_t);
>>>> +
>>>> +    /* Store the system reset and machine check address */
>>>> +    guest_machine_check_addr = rtas_ld(args, 1);
>>>> +
>>>> +    /* Safety Check */
>>>> +    if (sizeof(trampoline) >= MC_INTERRUPT_VECTOR_SIZE) {
>>>> +        fprintf(stderr, "Unable to register ibm,nmi_register: "
>>>> +                "Trampoline size exceeded\n");
>>>> +        rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
>>>> +        return;
>>>> +    }
>>>> +
>>>> +    /*
>>>> +     * Update the branch instruction in trampoline with the absolute
>>>> +     * machine check address requested by OS
>>>> +     */
>>>> +    branch_inst |= guest_machine_check_addr;
>>>
>>> Does this even work? You're creating a relative branch here.
>>
>> We do an absolute branch here. guest_machine_check_addr contains the
>> physical address of machine check handler. We update the branch
>> instruction operand to do an absolute branch to this physical address.
> 
> Where? I don't see the absolute bit anywhere.
> 
> 
> Alex
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check
  2014-08-28  8:42       ` Alexander Graf
@ 2014-08-28 17:45         ` Aravinda Prasad
  0 siblings, 0 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-28 17:45 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On Thursday 28 August 2014 02:12 PM, Alexander Graf wrote:
> 
> 
> On 28.08.14 08:56, Aravinda Prasad wrote:
>>
>>
>> On Wednesday 27 August 2014 04:10 PM, Alexander Graf wrote:
>>>
>>>
>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>> 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 <aravinda@linux.vnet.ibm.com>
>>>
>>> This patch doesn't make any sense. Both threads will issue an HCALL
>>> which will get locked inside of QEMU, so we'll never see the case where
>>> both hypercalls get processed at the same time.
>>
>> AFAIK, only one thread can succeed entering qemu upon parallel hcall
>> from different guest CPUs as it is gated by a lock. Hence one hcall is
>> processed at a time.
>>
>> As per PAPR, we don't want any other KVMPPC_H_REPORT_ERR hcall to be
>> processed at the same time and further KVMPPC_H_REPORT_ERR hcall thus
>> issued should wait until the OS issues ibm,nmi-interlock.
> 
> Oh, now I understand. The locking time is from
> [h_report_mc_err...rtas_ibm_nmi_interlock].
> 
> This should definitely go into the comment on the check in
> h_report_mc_err. In fact, remove the fact that only one thread can
> execute and instead write where the lock gets unset and that during that
> phase only one vcpu may process the NMI.

Sure will add a comment.

Regards,
Aravinda

> 
> 
> Alex
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-28 10:40   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
@ 2014-08-28 18:20     ` Aravinda Prasad
  2014-08-28 22:18       ` Alexander Graf
  0 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-28 18:20 UTC (permalink / raw)
  To: Alexander Graf; +Cc: benh, aik, qemu-devel, qemu-ppc, paulus



On Thursday 28 August 2014 04:10 PM, Alexander Graf wrote:
> 
> 
> On 25.08.14 15:45, Aravinda Prasad wrote:
>> Extend rtas-blob to accommodate error log. Error log
>> structure is saved in rtas space upon a machine check
>> exception.
>>
>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> 
> I can't say I'm a big fan of this patch. Can we somehow separate that
> NMI page from the RTAS blob? Also I'd definitely prefer if we keep
> rtas_entry == rtas_addr - if nothing else for the sake of backwards
> compatibility.
> 
> So how about we lay out the structure in memory like this:
> 
>   [ spapr-rtas.bin ]
>   [ padding to 4k boundary or whatever sPAPR requires ]
>   [ 4k NMI region ]
> 
> Then the only thing we'd have to really change internally is the size
> information of the rtas blob.

Either we can have it like this or completely eliminate spapr-rtas.bin
(and spapr-rtas.S) by simply allocating required space in QEMU and then
patching the 5 instructions at rtas-entry as earlier discussed with David.

http://lists.nongnu.org/archive/html/qemu-ppc/2014-08/msg00251.html

Regards,
Aravinda

> 
> 
> Alex
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/5] target-ppc: Build error log
  2014-08-28 17:17               ` Aravinda Prasad
@ 2014-08-28 20:07                 ` Benjamin Herrenschmidt
  2014-08-30  8:06                   ` Aravinda Prasad
  0 siblings, 1 reply; 73+ messages in thread
From: Benjamin Herrenschmidt @ 2014-08-28 20:07 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: aik, qemu-ppc, Alexander Graf, paulus, qemu-devel

On Thu, 2014-08-28 at 22:47 +0530, Aravinda Prasad wrote:
> Should we avoid having error log in 0x7000? As per above only
> ibm,nmi-register-2 places error log in 0x7000 which will be terminated
> in future?

The question is which variant Linux uses and which variant are other
OSes we might be interested in use ?

We might have to implement both, but I would probably start with just
ibm,nmi-register

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-28 17:42         ` Aravinda Prasad
@ 2014-08-28 22:16           ` Alexander Graf
  2014-08-30  8:08             ` Aravinda Prasad
  2014-09-04  8:25             ` Aravinda Prasad
  0 siblings, 2 replies; 73+ messages in thread
From: Alexander Graf @ 2014-08-28 22:16 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On 28.08.14 19:42, Aravinda Prasad wrote:
> 
> 
> On Thursday 28 August 2014 02:07 PM, Alexander Graf wrote:
>>
>>
>> On 28.08.14 08:38, Aravinda Prasad wrote:
>>>
>>>
>>> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>>>
>>>>
>>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>>> This patch adds FWNMI support in qemu for powerKVM
>>>>> guests by handling the ibm,nmi-register rtas call.
>>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>>> machine check notification address is saved and the
>>>>> machine check interrupt vector 0x200 is patched to
>>>>> issue a private hcall.
>>>>>
>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>> ---
>>>>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>  include/hw/ppc/spapr.h |    8 ++++
>>>>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>> index 02ddbf9..1135d2b 100644
>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>>      rtas_st(rets, 0, ret);
>>>>>  }
>>>>>  
>>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>>> +                                  sPAPREnvironment *spapr,
>>>>> +                                  uint32_t token, uint32_t nargs,
>>>>> +                                  target_ulong args,
>>>>> +                                  uint32_t nret, target_ulong rets)
>>>>> +{
>>>>> +    int i;
>>>>> +    uint32_t branch_inst = 0x48000002;
>>>>> +    target_ulong guest_machine_check_addr;
>>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>>> +    /*
>>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>>> +     * to request qemu to build error log. QEMU builds the
>>>>> +     * error log, copies to rtas-blob and returns the address.
>>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>>> +     * and srr1 which we restore and pass on the actual error
>>>>> +     * log address to OS handled mcachine check notification
>>>>> +     * routine
>>>>> +     */
>>>>> +    uint32_t trampoline[] = {
>>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>>> +        0x38600000,    /* li      r3,0   */
>>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>>> +        /* Issue H_CALL */
>>>>> +        0x44000022,    /*  sc      1     */
>>>>
>>>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>>>> clobber it?) and call our special hypercall.
>>>>
>>>> But what does all the cruft below here do?
>>>
>>> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
>>> can clobber SPRG2 after hcall returns. I have included a comment in
>>> patch 3/5 while building error log. I think better I add one here as well.
>>>
>>>>
>>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>>
>>>> Apart from th fact that your order is wrong, this destroys the value of
>>>> r3 that we saved above again.
>>>
>>> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
>>> KVMPPC_H_REPORT_ERR hcall returns.
>>>
>>>>
>>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>>
>>>> Can't we just set srr0 and srr1 directly?
>>>
>>> I checked for instructions in ISA which set srr0/1 directly given an
>>> address, but could not find any such instructions.
>>
>> I mean from QEMU :).
> 
> srr0 and srr1, which are properly set when 0x200 is invoked, are
> clobbered when we return from KVMPPC_H_REPORT_ERR hcall. I think they
> are modified before issuing rfid (I can see them getting clobbered from
> QEMU monitor). However when we jump to OS registered machine check
> routine srr0 and srr1 should reflect the value they had when 0x200 was
> invoked.
> 
> Hence srr0 and srr1 are saved in hcall and restored when we return from
> hcall. Also we don't have enough scratch registers available to save
> these before invoking hcall from 0x200.
> 
> Or am I missing other ways to do this from QEMU?

If you just do

cpu_synchronize_state() and then change env->spr[SPRN_SRR0/1] inside
your hypercall handler that should also change the value when you return
from the hcall.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-28 18:20     ` Aravinda Prasad
@ 2014-08-28 22:18       ` Alexander Graf
  2014-08-28 22:25         ` Benjamin Herrenschmidt
  2014-08-29  3:47         ` David Gibson
  0 siblings, 2 replies; 73+ messages in thread
From: Alexander Graf @ 2014-08-28 22:18 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: benh, aik, qemu-devel, qemu-ppc, paulus



On 28.08.14 20:20, Aravinda Prasad wrote:
> 
> 
> On Thursday 28 August 2014 04:10 PM, Alexander Graf wrote:
>>
>>
>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>> Extend rtas-blob to accommodate error log. Error log
>>> structure is saved in rtas space upon a machine check
>>> exception.
>>>
>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>
>> I can't say I'm a big fan of this patch. Can we somehow separate that
>> NMI page from the RTAS blob? Also I'd definitely prefer if we keep
>> rtas_entry == rtas_addr - if nothing else for the sake of backwards
>> compatibility.
>>
>> So how about we lay out the structure in memory like this:
>>
>>   [ spapr-rtas.bin ]
>>   [ padding to 4k boundary or whatever sPAPR requires ]
>>   [ 4k NMI region ]
>>
>> Then the only thing we'd have to really change internally is the size
>> information of the rtas blob.
> 
> Either we can have it like this or completely eliminate spapr-rtas.bin
> (and spapr-rtas.S) by simply allocating required space in QEMU and then
> patching the 5 instructions at rtas-entry as earlier discussed with David.
> 
> http://lists.nongnu.org/archive/html/qemu-ppc/2014-08/msg00251.html
> 

I strongly disagree with David. Legally there is no difference between a
.bin file that contains code and an array made of instructions. And the
more target code we can keep outside of QEMU the better.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-28 22:18       ` Alexander Graf
@ 2014-08-28 22:25         ` Benjamin Herrenschmidt
  2014-08-29  0:40           ` Alexander Graf
  2014-08-29  3:47         ` David Gibson
  1 sibling, 1 reply; 73+ messages in thread
From: Benjamin Herrenschmidt @ 2014-08-28 22:25 UTC (permalink / raw)
  To: Alexander Graf; +Cc: aik, qemu-devel, qemu-ppc, Aravinda Prasad, paulus

On Fri, 2014-08-29 at 00:18 +0200, Alexander Graf wrote:
> I strongly disagree with David. Legally there is no difference between a
> .bin file that contains code and an array made of instructions. And the
> more target code we can keep outside of QEMU the better.

Ugh ... having a separate file with it's own build system etc... for 5
instructions is borderline ridiculous too :-)

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-28 22:25         ` Benjamin Herrenschmidt
@ 2014-08-29  0:40           ` Alexander Graf
  2014-08-29  1:06             ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-08-29  0:40 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: aik, qemu-devel, qemu-ppc, Aravinda Prasad, paulus



On 29.08.14 00:25, Benjamin Herrenschmidt wrote:
> On Fri, 2014-08-29 at 00:18 +0200, Alexander Graf wrote:
>> I strongly disagree with David. Legally there is no difference between a
>> .bin file that contains code and an array made of instructions. And the
>> more target code we can keep outside of QEMU the better.
> 
> Ugh ... having a separate file with it's own build system etc... for 5
> instructions is borderline ridiculous too :-)

Then don't use it - nobody's forcing you to do so :). Just use the
provided binary. I fail to see the difference between

  uint32_t rtas_blob[] = { INST_SC1, INST_BLR };

and

  uint32_t *rtas_blob;
  load_file_from_disk(rtas_blob);

except that we're using an actual assembler ;).


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-29  0:40           ` Alexander Graf
@ 2014-08-29  1:06             ` Benjamin Herrenschmidt
  2014-08-29  1:33               ` Alexander Graf
  0 siblings, 1 reply; 73+ messages in thread
From: Benjamin Herrenschmidt @ 2014-08-29  1:06 UTC (permalink / raw)
  To: Alexander Graf; +Cc: aik, qemu-devel, qemu-ppc, Aravinda Prasad, paulus

On Fri, 2014-08-29 at 02:40 +0200, Alexander Graf wrote:
> 
> On 29.08.14 00:25, Benjamin Herrenschmidt wrote:
> > On Fri, 2014-08-29 at 00:18 +0200, Alexander Graf wrote:
> >> I strongly disagree with David. Legally there is no difference between a
> >> .bin file that contains code and an array made of instructions. And the
> >> more target code we can keep outside of QEMU the better.
> > 
> > Ugh ... having a separate file with it's own build system etc... for 5
> > instructions is borderline ridiculous too :-)
> 
> Then don't use it - nobody's forcing you to do so :). Just use the
> provided binary. I fail to see the difference between
> 
>   uint32_t rtas_blob[] = { INST_SC1, INST_BLR };
> 
> and
> 
>   uint32_t *rtas_blob;
>   load_file_from_disk(rtas_blob);
> 
> except that we're using an actual assembler ;).

So you fail to see the difference with an array of 5 words vs. running
through thousands of instructions & syscall to read those same 5 words
from disk ? :-)

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-29  1:06             ` Benjamin Herrenschmidt
@ 2014-08-29  1:33               ` Alexander Graf
  2014-08-29  2:42                 ` Benjamin Herrenschmidt
  2014-08-29  3:46                 ` David Gibson
  0 siblings, 2 replies; 73+ messages in thread
From: Alexander Graf @ 2014-08-29  1:33 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: aik, qemu-devel, qemu-ppc, Aravinda Prasad, paulus



> Am 29.08.2014 um 03:06 schrieb Benjamin Herrenschmidt <benh@au1.ibm.com>:
> 
>> On Fri, 2014-08-29 at 02:40 +0200, Alexander Graf wrote:
>> 
>>> On 29.08.14 00:25, Benjamin Herrenschmidt wrote:
>>>> On Fri, 2014-08-29 at 00:18 +0200, Alexander Graf wrote:
>>>> I strongly disagree with David. Legally there is no difference between a
>>>> .bin file that contains code and an array made of instructions. And the
>>>> more target code we can keep outside of QEMU the better.
>>> 
>>> Ugh ... having a separate file with it's own build system etc... for 5
>>> instructions is borderline ridiculous too :-)
>> 
>> Then don't use it - nobody's forcing you to do so :). Just use the
>> provided binary. I fail to see the difference between
>> 
>>  uint32_t rtas_blob[] = { INST_SC1, INST_BLR };
>> 
>> and
>> 
>>  uint32_t *rtas_blob;
>>  load_file_from_disk(rtas_blob);
>> 
>> except that we're using an actual assembler ;).
> 
> So you fail to see the difference with an array of 5 words vs. running
> through thousands of instructions & syscall to read those same 5 words
> from disk ? :-)

I fail to see a problem, yeah :). Imagine the same thing on x86 with its completely messed up instruction set. Would you still advocate for in-qemu code or would you prefer to have a compiler between you and the ugly opcodes?


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-29  1:33               ` Alexander Graf
@ 2014-08-29  2:42                 ` Benjamin Herrenschmidt
  2014-08-29  3:46                 ` David Gibson
  1 sibling, 0 replies; 73+ messages in thread
From: Benjamin Herrenschmidt @ 2014-08-29  2:42 UTC (permalink / raw)
  To: Alexander Graf; +Cc: aik, qemu-devel, qemu-ppc, Aravinda Prasad, paulus

On Fri, 2014-08-29 at 03:33 +0200, Alexander Graf wrote:
> I fail to see a problem, yeah :). Imagine the same thing on x86 with
> its completely messed up instruction set. Would you still advocate for
> in-qemu code or would you prefer to have a compiler between you and
> the ugly opcodes?

You mean an assembler ? :-)

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-29  1:33               ` Alexander Graf
  2014-08-29  2:42                 ` Benjamin Herrenschmidt
@ 2014-08-29  3:46                 ` David Gibson
  1 sibling, 0 replies; 73+ messages in thread
From: David Gibson @ 2014-08-29  3:46 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Benjamin Herrenschmidt, aik, qemu-devel, qemu-ppc,
	Aravinda Prasad, paulus

[-- Attachment #1: Type: text/plain, Size: 1863 bytes --]

On Fri, Aug 29, 2014 at 03:33:59AM +0200, Alexander Graf wrote:
> 
> 
> > Am 29.08.2014 um 03:06 schrieb Benjamin Herrenschmidt <benh@au1.ibm.com>:
> > 
> >> On Fri, 2014-08-29 at 02:40 +0200, Alexander Graf wrote:
> >> 
> >>> On 29.08.14 00:25, Benjamin Herrenschmidt wrote:
> >>>> On Fri, 2014-08-29 at 00:18 +0200, Alexander Graf wrote:
> >>>> I strongly disagree with David. Legally there is no difference between a
> >>>> .bin file that contains code and an array made of instructions. And the
> >>>> more target code we can keep outside of QEMU the better.
> >>> 
> >>> Ugh ... having a separate file with it's own build system etc... for 5
> >>> instructions is borderline ridiculous too :-)
> >> 
> >> Then don't use it - nobody's forcing you to do so :). Just use the
> >> provided binary. I fail to see the difference between
> >> 
> >>  uint32_t rtas_blob[] = { INST_SC1, INST_BLR };
> >> 
> >> and
> >> 
> >>  uint32_t *rtas_blob;
> >>  load_file_from_disk(rtas_blob);
> >> 
> >> except that we're using an actual assembler ;).
> > 
> > So you fail to see the difference with an array of 5 words vs. running
> > through thousands of instructions & syscall to read those same 5 words
> > from disk ? :-)
> 
> I fail to see a problem, yeah :). Imagine the same thing on x86 with
> its completely messed up instruction set. Would you still advocate
> for in-qemu code or would you prefer to have a compiler between you
> and the ugly opcodes?

If it was only 20 bytes worth, and by it's nature unlikely to need
changing, then, yes, I would, even with the extra x86 ugliness.
Assuming it was well commented, obviously.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-28 22:18       ` Alexander Graf
  2014-08-28 22:25         ` Benjamin Herrenschmidt
@ 2014-08-29  3:47         ` David Gibson
  1 sibling, 0 replies; 73+ messages in thread
From: David Gibson @ 2014-08-29  3:47 UTC (permalink / raw)
  To: Alexander Graf; +Cc: benh, aik, qemu-devel, qemu-ppc, Aravinda Prasad, paulus

[-- Attachment #1: Type: text/plain, Size: 1805 bytes --]

On Fri, Aug 29, 2014 at 12:18:44AM +0200, Alexander Graf wrote:
> 
> 
> On 28.08.14 20:20, Aravinda Prasad wrote:
> > 
> > 
> > On Thursday 28 August 2014 04:10 PM, Alexander Graf wrote:
> >>
> >>
> >> On 25.08.14 15:45, Aravinda Prasad wrote:
> >>> Extend rtas-blob to accommodate error log. Error log
> >>> structure is saved in rtas space upon a machine check
> >>> exception.
> >>>
> >>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> >>
> >> I can't say I'm a big fan of this patch. Can we somehow separate that
> >> NMI page from the RTAS blob? Also I'd definitely prefer if we keep
> >> rtas_entry == rtas_addr - if nothing else for the sake of backwards
> >> compatibility.
> >>
> >> So how about we lay out the structure in memory like this:
> >>
> >>   [ spapr-rtas.bin ]
> >>   [ padding to 4k boundary or whatever sPAPR requires ]
> >>   [ 4k NMI region ]
> >>
> >> Then the only thing we'd have to really change internally is the size
> >> information of the rtas blob.
> > 
> > Either we can have it like this or completely eliminate spapr-rtas.bin
> > (and spapr-rtas.S) by simply allocating required space in QEMU and then
> > patching the 5 instructions at rtas-entry as earlier discussed with David.
> > 
> > http://lists.nongnu.org/archive/html/qemu-ppc/2014-08/msg00251.html
> > 
> 
> I strongly disagree with David. Legally there is no difference between a
> .bin file that contains code and an array made of instructions. And the
> more target code we can keep outside of QEMU the better.

What do legalities have to do with it?

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/5] target-ppc: Build error log
  2014-08-28 20:07                 ` Benjamin Herrenschmidt
@ 2014-08-30  8:06                   ` Aravinda Prasad
  0 siblings, 0 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-30  8:06 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: aik, qemu-ppc, Alexander Graf, paulus, qemu-devel



On Friday 29 August 2014 01:37 AM, Benjamin Herrenschmidt wrote:
> On Thu, 2014-08-28 at 22:47 +0530, Aravinda Prasad wrote:
>> Should we avoid having error log in 0x7000? As per above only
>> ibm,nmi-register-2 places error log in 0x7000 which will be terminated
>> in future?
> 
> The question is which variant Linux uses and which variant are other
> OSes we might be interested in use ?
> 
> We might have to implement both, but I would probably start with just
> ibm,nmi-register

sure.

> 
> Cheers,
> Ben.
> 
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-28 22:16           ` Alexander Graf
@ 2014-08-30  8:08             ` Aravinda Prasad
  2014-09-04  8:25             ` Aravinda Prasad
  1 sibling, 0 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-08-30  8:08 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc, benh, aik, qemu-devel, paulus



On Friday 29 August 2014 03:46 AM, Alexander Graf wrote:
> 
> 
> On 28.08.14 19:42, Aravinda Prasad wrote:
>>
>>
>> On Thursday 28 August 2014 02:07 PM, Alexander Graf wrote:
>>>
>>>
>>> On 28.08.14 08:38, Aravinda Prasad wrote:
>>>>
>>>>
>>>> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>>>>
>>>>>
>>>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>>>> This patch adds FWNMI support in qemu for powerKVM
>>>>>> guests by handling the ibm,nmi-register rtas call.
>>>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>>>> machine check notification address is saved and the
>>>>>> machine check interrupt vector 0x200 is patched to
>>>>>> issue a private hcall.
>>>>>>
>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>> ---
>>>>>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>  include/hw/ppc/spapr.h |    8 ++++
>>>>>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>> index 02ddbf9..1135d2b 100644
>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>>>      rtas_st(rets, 0, ret);
>>>>>>  }
>>>>>>  
>>>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>>>> +                                  sPAPREnvironment *spapr,
>>>>>> +                                  uint32_t token, uint32_t nargs,
>>>>>> +                                  target_ulong args,
>>>>>> +                                  uint32_t nret, target_ulong rets)
>>>>>> +{
>>>>>> +    int i;
>>>>>> +    uint32_t branch_inst = 0x48000002;
>>>>>> +    target_ulong guest_machine_check_addr;
>>>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>>>> +    /*
>>>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>>>> +     * to request qemu to build error log. QEMU builds the
>>>>>> +     * error log, copies to rtas-blob and returns the address.
>>>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>>>> +     * and srr1 which we restore and pass on the actual error
>>>>>> +     * log address to OS handled mcachine check notification
>>>>>> +     * routine
>>>>>> +     */
>>>>>> +    uint32_t trampoline[] = {
>>>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>>>> +        0x38600000,    /* li      r3,0   */
>>>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>>>> +        /* Issue H_CALL */
>>>>>> +        0x44000022,    /*  sc      1     */
>>>>>
>>>>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>>>>> clobber it?) and call our special hypercall.
>>>>>
>>>>> But what does all the cruft below here do?
>>>>
>>>> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
>>>> can clobber SPRG2 after hcall returns. I have included a comment in
>>>> patch 3/5 while building error log. I think better I add one here as well.
>>>>
>>>>>
>>>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>>>
>>>>> Apart from th fact that your order is wrong, this destroys the value of
>>>>> r3 that we saved above again.
>>>>
>>>> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
>>>> KVMPPC_H_REPORT_ERR hcall returns.
>>>>
>>>>>
>>>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>>>
>>>>> Can't we just set srr0 and srr1 directly?
>>>>
>>>> I checked for instructions in ISA which set srr0/1 directly given an
>>>> address, but could not find any such instructions.
>>>
>>> I mean from QEMU :).
>>
>> srr0 and srr1, which are properly set when 0x200 is invoked, are
>> clobbered when we return from KVMPPC_H_REPORT_ERR hcall. I think they
>> are modified before issuing rfid (I can see them getting clobbered from
>> QEMU monitor). However when we jump to OS registered machine check
>> routine srr0 and srr1 should reflect the value they had when 0x200 was
>> invoked.
>>
>> Hence srr0 and srr1 are saved in hcall and restored when we return from
>> hcall. Also we don't have enough scratch registers available to save
>> these before invoking hcall from 0x200.
>>
>> Or am I missing other ways to do this from QEMU?
> 
> If you just do
> 
> cpu_synchronize_state() and then change env->spr[SPRN_SRR0/1] inside
> your hypercall handler that should also change the value when you return
> from the hcall.

Thanks. I will use it in v2.

Regards,
Aravinda

> 
> 
> Alex
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob Aravinda Prasad
  2014-08-26  5:38   ` David Gibson
  2014-08-28 10:40   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
@ 2014-09-01  7:46   ` Alexey Kardashevskiy
  2014-09-01 11:23     ` Aravinda Prasad
  2 siblings, 1 reply; 73+ messages in thread
From: Alexey Kardashevskiy @ 2014-09-01  7:46 UTC (permalink / raw)
  To: Aravinda Prasad, qemu-ppc, qemu-devel; +Cc: benh, paulus

On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
> Extend rtas-blob to accommodate error log. Error log
> structure is saved in rtas space upon a machine check
> exception.
> 
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> ---
>  hw/ppc/spapr.c                  |   13 ++++++++++---
>  hw/ppc/spapr_rtas.c             |    4 ++--
>  include/hw/ppc/spapr.h          |    2 +-
>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>  4 files changed, 25 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index d01978f..1120988 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -85,6 +85,12 @@
>  
>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>  
> +/*
> + * The rtas-entry-offset should match the value specified in
> + * spapr-rtas.S
> + */
> +#define RTAS_ENTRY_OFFSET       0x1000
> +
>  typedef struct sPAPRMachineState sPAPRMachineState;
>  
>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>                                 hwaddr fdt_addr,
>                                 hwaddr rtas_addr,
> -                               hwaddr rtas_size)
> +                               hwaddr rtas_size,
> +                               hwaddr rtas_entry)
>  {
>      int ret, i;
>      size_t cb = 0;
> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>      }
>  
>      /* RTAS */
> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>      if (ret < 0) {
>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>      }
> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>  
>      /* Load the fdt */
>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
> -                       spapr->rtas_size);
> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>  
>      /* Set up the entry state */
>      first_ppc_cpu = POWERPC_CPU(first_cpu);
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index 9ba1ba6..02ddbf9 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>  }
>  
>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
> -                                 hwaddr rtas_size)
> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>  {
>      int ret;
>      int i;
> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>      }
>  
>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
> -                                rtas_addr);
> +                                rtas_entry);
>      if (ret < 0) {
>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>                  fdt_strerror(ret));
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index bbba51a..dedfa67 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>                               uint32_t token, uint32_t nargs, target_ulong args,
>                               uint32_t nret, target_ulong rets);
>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
> -                                 hwaddr rtas_size);
> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>  
>  #define SPAPR_TCE_PAGE_SHIFT   12
>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
> index 903bec2..8c9b17e 100644
> --- a/pc-bios/spapr-rtas/spapr-rtas.S
> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
> @@ -30,6 +30,18 @@
>  
>  .globl	_start
>  _start:
> +	/*
> +	 * Reserve space for error log in RTAS blob.
> +	 *
> +	 * Either we can reserve initial bytes for error log followed by
> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
> +	 * former, as we already have rtas-base and rtas-entry (currently
> +	 * both pointing to rtas-base) defined in qemu and we can update
> +	 * rtas-entry to point to an offset from rtas-base. This avoids
> +	 * unnecessary definition of rtas-error-offset while keeping
> +	 * rtas-entry redundant.
> +	 */
> +	. = 0x1000


Why not this (and not changing spapr-rtas.S)?

--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
                        spapr->rtas_size);

     /* Copy RTAS over */
-    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
+    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
+                              spapr->rtas_blob,
                               spapr->rtas_size);




>  	mr	4,3
>  	lis	3,KVMPPC_H_RTAS@h
>  	ori	3,3,KVMPPC_H_RTAS@l
> 


-- 
Alexey Kardashevskiy
IBM OzLabs, LTC Team

e-mail: aik@au1.ibm.com
notes: Alexey Kardashevskiy/Australia/IBM

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-09-01  7:46   ` [Qemu-devel] " Alexey Kardashevskiy
@ 2014-09-01 11:23     ` Aravinda Prasad
  2014-09-02  4:09       ` Alexey Kardashevskiy
  0 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-09-01 11:23 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: benh, qemu-ppc, qemu-devel, paulus



On Monday 01 September 2014 01:16 PM, Alexey Kardashevskiy wrote:
> On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
>> Extend rtas-blob to accommodate error log. Error log
>> structure is saved in rtas space upon a machine check
>> exception.
>>
>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>> ---
>>  hw/ppc/spapr.c                  |   13 ++++++++++---
>>  hw/ppc/spapr_rtas.c             |    4 ++--
>>  include/hw/ppc/spapr.h          |    2 +-
>>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>>  4 files changed, 25 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index d01978f..1120988 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -85,6 +85,12 @@
>>  
>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>  
>> +/*
>> + * The rtas-entry-offset should match the value specified in
>> + * spapr-rtas.S
>> + */
>> +#define RTAS_ENTRY_OFFSET       0x1000
>> +
>>  typedef struct sPAPRMachineState sPAPRMachineState;
>>  
>>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
>> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>                                 hwaddr fdt_addr,
>>                                 hwaddr rtas_addr,
>> -                               hwaddr rtas_size)
>> +                               hwaddr rtas_size,
>> +                               hwaddr rtas_entry)
>>  {
>>      int ret, i;
>>      size_t cb = 0;
>> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>      }
>>  
>>      /* RTAS */
>> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
>> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>>      if (ret < 0) {
>>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>>      }
>> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>>  
>>      /* Load the fdt */
>>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
>> -                       spapr->rtas_size);
>> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>>  
>>      /* Set up the entry state */
>>      first_ppc_cpu = POWERPC_CPU(first_cpu);
>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>> index 9ba1ba6..02ddbf9 100644
>> --- a/hw/ppc/spapr_rtas.c
>> +++ b/hw/ppc/spapr_rtas.c
>> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>>  }
>>  
>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>> -                                 hwaddr rtas_size)
>> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>>  {
>>      int ret;
>>      int i;
>> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>      }
>>  
>>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
>> -                                rtas_addr);
>> +                                rtas_entry);
>>      if (ret < 0) {
>>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>>                  fdt_strerror(ret));
>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>> index bbba51a..dedfa67 100644
>> --- a/include/hw/ppc/spapr.h
>> +++ b/include/hw/ppc/spapr.h
>> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>                               uint32_t token, uint32_t nargs, target_ulong args,
>>                               uint32_t nret, target_ulong rets);
>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>> -                                 hwaddr rtas_size);
>> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>>  
>>  #define SPAPR_TCE_PAGE_SHIFT   12
>>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
>> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
>> index 903bec2..8c9b17e 100644
>> --- a/pc-bios/spapr-rtas/spapr-rtas.S
>> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
>> @@ -30,6 +30,18 @@
>>  
>>  .globl	_start
>>  _start:
>> +	/*
>> +	 * Reserve space for error log in RTAS blob.
>> +	 *
>> +	 * Either we can reserve initial bytes for error log followed by
>> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
>> +	 * former, as we already have rtas-base and rtas-entry (currently
>> +	 * both pointing to rtas-base) defined in qemu and we can update
>> +	 * rtas-entry to point to an offset from rtas-base. This avoids
>> +	 * unnecessary definition of rtas-error-offset while keeping
>> +	 * rtas-entry redundant.
>> +	 */
>> +	. = 0x1000
> 
> 
> Why not this (and not changing spapr-rtas.S)?
> 
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
>                         spapr->rtas_size);
> 
>      /* Copy RTAS over */
> -    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
> +    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
> +                              spapr->rtas_blob,
>                                spapr->rtas_size);

This is possible, however requires suitable adjustment to make sure
spapr->rtas_addr has enough space allocated.

> 
> 
> 
> 
>>  	mr	4,3
>>  	lis	3,KVMPPC_H_RTAS@h
>>  	ori	3,3,KVMPPC_H_RTAS@l
>>
> 
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-09-01 11:23     ` Aravinda Prasad
@ 2014-09-02  4:09       ` Alexey Kardashevskiy
  2014-09-02  5:25         ` Aravinda Prasad
  0 siblings, 1 reply; 73+ messages in thread
From: Alexey Kardashevskiy @ 2014-09-02  4:09 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: benh, qemu-ppc, qemu-devel, paulus

On 09/01/2014 09:23 PM, Aravinda Prasad wrote:
> 
> 
> On Monday 01 September 2014 01:16 PM, Alexey Kardashevskiy wrote:
>> On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
>>> Extend rtas-blob to accommodate error log. Error log
>>> structure is saved in rtas space upon a machine check
>>> exception.
>>>
>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>> ---
>>>  hw/ppc/spapr.c                  |   13 ++++++++++---
>>>  hw/ppc/spapr_rtas.c             |    4 ++--
>>>  include/hw/ppc/spapr.h          |    2 +-
>>>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>>>  4 files changed, 25 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>> index d01978f..1120988 100644
>>> --- a/hw/ppc/spapr.c
>>> +++ b/hw/ppc/spapr.c
>>> @@ -85,6 +85,12 @@
>>>  
>>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>>  
>>> +/*
>>> + * The rtas-entry-offset should match the value specified in
>>> + * spapr-rtas.S
>>> + */
>>> +#define RTAS_ENTRY_OFFSET       0x1000
>>> +
>>>  typedef struct sPAPRMachineState sPAPRMachineState;
>>>  
>>>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
>>> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>>>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>                                 hwaddr fdt_addr,
>>>                                 hwaddr rtas_addr,
>>> -                               hwaddr rtas_size)
>>> +                               hwaddr rtas_size,
>>> +                               hwaddr rtas_entry)
>>>  {
>>>      int ret, i;
>>>      size_t cb = 0;
>>> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>      }
>>>  
>>>      /* RTAS */
>>> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
>>> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>>>      if (ret < 0) {
>>>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>>>      }
>>> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>>>  
>>>      /* Load the fdt */
>>>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
>>> -                       spapr->rtas_size);
>>> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>>>  
>>>      /* Set up the entry state */
>>>      first_ppc_cpu = POWERPC_CPU(first_cpu);
>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>> index 9ba1ba6..02ddbf9 100644
>>> --- a/hw/ppc/spapr_rtas.c
>>> +++ b/hw/ppc/spapr_rtas.c
>>> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>>>  }
>>>  
>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>> -                                 hwaddr rtas_size)
>>> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>>>  {
>>>      int ret;
>>>      int i;
>>> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>      }
>>>  
>>>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
>>> -                                rtas_addr);
>>> +                                rtas_entry);
>>>      if (ret < 0) {
>>>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>>>                  fdt_strerror(ret));
>>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>>> index bbba51a..dedfa67 100644
>>> --- a/include/hw/ppc/spapr.h
>>> +++ b/include/hw/ppc/spapr.h
>>> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>>                               uint32_t token, uint32_t nargs, target_ulong args,
>>>                               uint32_t nret, target_ulong rets);
>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>> -                                 hwaddr rtas_size);
>>> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>>>  
>>>  #define SPAPR_TCE_PAGE_SHIFT   12
>>>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
>>> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
>>> index 903bec2..8c9b17e 100644
>>> --- a/pc-bios/spapr-rtas/spapr-rtas.S
>>> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
>>> @@ -30,6 +30,18 @@
>>>  
>>>  .globl	_start
>>>  _start:
>>> +	/*
>>> +	 * Reserve space for error log in RTAS blob.
>>> +	 *
>>> +	 * Either we can reserve initial bytes for error log followed by
>>> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
>>> +	 * former, as we already have rtas-base and rtas-entry (currently
>>> +	 * both pointing to rtas-base) defined in qemu and we can update
>>> +	 * rtas-entry to point to an offset from rtas-base. This avoids
>>> +	 * unnecessary definition of rtas-error-offset while keeping
>>> +	 * rtas-entry redundant.
>>> +	 */
>>> +	. = 0x1000
>>
>>
>> Why not this (and not changing spapr-rtas.S)?
>>
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
>>                         spapr->rtas_size);
>>
>>      /* Copy RTAS over */
>> -    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>> +    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
>> +                              spapr->rtas_blob,
>>                                spapr->rtas_size);
> 
> This is possible, however requires suitable adjustment to make sure
> spapr->rtas_addr has enough space allocated.


How is adding RTAS_ENTRY_OFFSET not enough to make sure that is has enough
space? QEMU copies RTAS to guest memory, QEMU makes up rtas_addr/entry
properties.


> 
>>
>>
>>
>>
>>>  	mr	4,3
>>>  	lis	3,KVMPPC_H_RTAS@h
>>>  	ori	3,3,KVMPPC_H_RTAS@l
>>>
>>
>>
> 


-- 
Alexey Kardashevskiy
IBM OzLabs, LTC Team

e-mail: aik@au1.ibm.com
notes: Alexey Kardashevskiy/Australia/IBM

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-09-02  4:09       ` Alexey Kardashevskiy
@ 2014-09-02  5:25         ` Aravinda Prasad
  2014-09-02  5:49           ` Alexey Kardashevskiy
  0 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-09-02  5:25 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: benh, qemu-ppc, qemu-devel, paulus



On Tuesday 02 September 2014 09:39 AM, Alexey Kardashevskiy wrote:
> On 09/01/2014 09:23 PM, Aravinda Prasad wrote:
>>
>>
>> On Monday 01 September 2014 01:16 PM, Alexey Kardashevskiy wrote:
>>> On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
>>>> Extend rtas-blob to accommodate error log. Error log
>>>> structure is saved in rtas space upon a machine check
>>>> exception.
>>>>
>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>> ---
>>>>  hw/ppc/spapr.c                  |   13 ++++++++++---
>>>>  hw/ppc/spapr_rtas.c             |    4 ++--
>>>>  include/hw/ppc/spapr.h          |    2 +-
>>>>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>>>>  4 files changed, 25 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>>> index d01978f..1120988 100644
>>>> --- a/hw/ppc/spapr.c
>>>> +++ b/hw/ppc/spapr.c
>>>> @@ -85,6 +85,12 @@
>>>>  
>>>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>>>  
>>>> +/*
>>>> + * The rtas-entry-offset should match the value specified in
>>>> + * spapr-rtas.S
>>>> + */
>>>> +#define RTAS_ENTRY_OFFSET       0x1000
>>>> +
>>>>  typedef struct sPAPRMachineState sPAPRMachineState;
>>>>  
>>>>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
>>>> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>>>>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>                                 hwaddr fdt_addr,
>>>>                                 hwaddr rtas_addr,
>>>> -                               hwaddr rtas_size)
>>>> +                               hwaddr rtas_size,
>>>> +                               hwaddr rtas_entry)
>>>>  {
>>>>      int ret, i;
>>>>      size_t cb = 0;
>>>> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>      }
>>>>  
>>>>      /* RTAS */
>>>> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
>>>> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>>>>      if (ret < 0) {
>>>>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>>>>      }
>>>> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>>>>  
>>>>      /* Load the fdt */
>>>>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
>>>> -                       spapr->rtas_size);
>>>> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>>>>  
>>>>      /* Set up the entry state */
>>>>      first_ppc_cpu = POWERPC_CPU(first_cpu);
>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>> index 9ba1ba6..02ddbf9 100644
>>>> --- a/hw/ppc/spapr_rtas.c
>>>> +++ b/hw/ppc/spapr_rtas.c
>>>> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>>>>  }
>>>>  
>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>> -                                 hwaddr rtas_size)
>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>>>>  {
>>>>      int ret;
>>>>      int i;
>>>> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>      }
>>>>  
>>>>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
>>>> -                                rtas_addr);
>>>> +                                rtas_entry);
>>>>      if (ret < 0) {
>>>>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>>>>                  fdt_strerror(ret));
>>>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>>>> index bbba51a..dedfa67 100644
>>>> --- a/include/hw/ppc/spapr.h
>>>> +++ b/include/hw/ppc/spapr.h
>>>> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>>>                               uint32_t token, uint32_t nargs, target_ulong args,
>>>>                               uint32_t nret, target_ulong rets);
>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>> -                                 hwaddr rtas_size);
>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>>>>  
>>>>  #define SPAPR_TCE_PAGE_SHIFT   12
>>>>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
>>>> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
>>>> index 903bec2..8c9b17e 100644
>>>> --- a/pc-bios/spapr-rtas/spapr-rtas.S
>>>> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
>>>> @@ -30,6 +30,18 @@
>>>>  
>>>>  .globl	_start
>>>>  _start:
>>>> +	/*
>>>> +	 * Reserve space for error log in RTAS blob.
>>>> +	 *
>>>> +	 * Either we can reserve initial bytes for error log followed by
>>>> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
>>>> +	 * former, as we already have rtas-base and rtas-entry (currently
>>>> +	 * both pointing to rtas-base) defined in qemu and we can update
>>>> +	 * rtas-entry to point to an offset from rtas-base. This avoids
>>>> +	 * unnecessary definition of rtas-error-offset while keeping
>>>> +	 * rtas-entry redundant.
>>>> +	 */
>>>> +	. = 0x1000
>>>
>>>
>>> Why not this (and not changing spapr-rtas.S)?
>>>
>>> --- a/hw/ppc/spapr.c
>>> +++ b/hw/ppc/spapr.c
>>> @@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
>>>                         spapr->rtas_size);
>>>
>>>      /* Copy RTAS over */
>>> -    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>> +    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
>>> +                              spapr->rtas_blob,
>>>                                spapr->rtas_size);
>>
>> This is possible, however requires suitable adjustment to make sure
>> spapr->rtas_addr has enough space allocated.
> 
> 
> How is adding RTAS_ENTRY_OFFSET not enough to make sure that is has enough
> space? QEMU copies RTAS to guest memory, QEMU makes up rtas_addr/entry
> properties.

QEMU adds spapr-rtas.bin as a rom, with rom->addr set to
spapr->rtas_addr, rom->datasize set to 20 bytes (the size of current
spapr-rtas.bin) and contents of spapr-rtas.bin read into rom->data
(malloc-ed region).

I think, access to spapr->rtas_addr is mapped to this rom. Hence it is
necessary to have rtas_addr and rtas_size consistent with the Rom
struct. If we use spapr->rtas_addr + RTAS_ENTRY_OFFSET then we are
trying to access an invalid offset in rom region.


> 
> 
>>
>>>
>>>
>>>
>>>
>>>>  	mr	4,3
>>>>  	lis	3,KVMPPC_H_RTAS@h
>>>>  	ori	3,3,KVMPPC_H_RTAS@l
>>>>
>>>
>>>
>>
> 
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-09-02  5:25         ` Aravinda Prasad
@ 2014-09-02  5:49           ` Alexey Kardashevskiy
  2014-09-02  5:56             ` Aravinda Prasad
  0 siblings, 1 reply; 73+ messages in thread
From: Alexey Kardashevskiy @ 2014-09-02  5:49 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: benh, qemu-ppc, qemu-devel, paulus

On 09/02/2014 03:25 PM, Aravinda Prasad wrote:
> 
> 
> On Tuesday 02 September 2014 09:39 AM, Alexey Kardashevskiy wrote:
>> On 09/01/2014 09:23 PM, Aravinda Prasad wrote:
>>>
>>>
>>> On Monday 01 September 2014 01:16 PM, Alexey Kardashevskiy wrote:
>>>> On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
>>>>> Extend rtas-blob to accommodate error log. Error log
>>>>> structure is saved in rtas space upon a machine check
>>>>> exception.
>>>>>
>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>> ---
>>>>>  hw/ppc/spapr.c                  |   13 ++++++++++---
>>>>>  hw/ppc/spapr_rtas.c             |    4 ++--
>>>>>  include/hw/ppc/spapr.h          |    2 +-
>>>>>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>>>>>  4 files changed, 25 insertions(+), 6 deletions(-)
>>>>>
>>>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>>>> index d01978f..1120988 100644
>>>>> --- a/hw/ppc/spapr.c
>>>>> +++ b/hw/ppc/spapr.c
>>>>> @@ -85,6 +85,12 @@
>>>>>  
>>>>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>>>>  
>>>>> +/*
>>>>> + * The rtas-entry-offset should match the value specified in
>>>>> + * spapr-rtas.S
>>>>> + */
>>>>> +#define RTAS_ENTRY_OFFSET       0x1000
>>>>> +
>>>>>  typedef struct sPAPRMachineState sPAPRMachineState;
>>>>>  
>>>>>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
>>>>> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>>>>>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>                                 hwaddr fdt_addr,
>>>>>                                 hwaddr rtas_addr,
>>>>> -                               hwaddr rtas_size)
>>>>> +                               hwaddr rtas_size,
>>>>> +                               hwaddr rtas_entry)
>>>>>  {
>>>>>      int ret, i;
>>>>>      size_t cb = 0;
>>>>> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>      }
>>>>>  
>>>>>      /* RTAS */
>>>>> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
>>>>> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>>>>>      if (ret < 0) {
>>>>>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>>>>>      }
>>>>> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>>>>>  
>>>>>      /* Load the fdt */
>>>>>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
>>>>> -                       spapr->rtas_size);
>>>>> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>>>>>  
>>>>>      /* Set up the entry state */
>>>>>      first_ppc_cpu = POWERPC_CPU(first_cpu);
>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>> index 9ba1ba6..02ddbf9 100644
>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>>>>>  }
>>>>>  
>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>> -                                 hwaddr rtas_size)
>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>>>>>  {
>>>>>      int ret;
>>>>>      int i;
>>>>> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>      }
>>>>>  
>>>>>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
>>>>> -                                rtas_addr);
>>>>> +                                rtas_entry);
>>>>>      if (ret < 0) {
>>>>>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>>>>>                  fdt_strerror(ret));
>>>>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>>>>> index bbba51a..dedfa67 100644
>>>>> --- a/include/hw/ppc/spapr.h
>>>>> +++ b/include/hw/ppc/spapr.h
>>>>> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>>>>                               uint32_t token, uint32_t nargs, target_ulong args,
>>>>>                               uint32_t nret, target_ulong rets);
>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>> -                                 hwaddr rtas_size);
>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>>>>>  
>>>>>  #define SPAPR_TCE_PAGE_SHIFT   12
>>>>>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
>>>>> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>> index 903bec2..8c9b17e 100644
>>>>> --- a/pc-bios/spapr-rtas/spapr-rtas.S
>>>>> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>> @@ -30,6 +30,18 @@
>>>>>  
>>>>>  .globl	_start
>>>>>  _start:
>>>>> +	/*
>>>>> +	 * Reserve space for error log in RTAS blob.
>>>>> +	 *
>>>>> +	 * Either we can reserve initial bytes for error log followed by
>>>>> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
>>>>> +	 * former, as we already have rtas-base and rtas-entry (currently
>>>>> +	 * both pointing to rtas-base) defined in qemu and we can update
>>>>> +	 * rtas-entry to point to an offset from rtas-base. This avoids
>>>>> +	 * unnecessary definition of rtas-error-offset while keeping
>>>>> +	 * rtas-entry redundant.
>>>>> +	 */
>>>>> +	. = 0x1000
>>>>
>>>>
>>>> Why not this (and not changing spapr-rtas.S)?
>>>>
>>>> --- a/hw/ppc/spapr.c
>>>> +++ b/hw/ppc/spapr.c
>>>> @@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
>>>>                         spapr->rtas_size);
>>>>
>>>>      /* Copy RTAS over */
>>>> -    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>> +    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
>>>> +                              spapr->rtas_blob,
>>>>                                spapr->rtas_size);
>>>
>>> This is possible, however requires suitable adjustment to make sure
>>> spapr->rtas_addr has enough space allocated.
>>
>>
>> How is adding RTAS_ENTRY_OFFSET not enough to make sure that is has enough
>> space? QEMU copies RTAS to guest memory, QEMU makes up rtas_addr/entry
>> properties.
> 
> QEMU adds spapr-rtas.bin as a rom, with rom->addr set to
> spapr->rtas_addr, rom->datasize set to 20 bytes (the size of current
> spapr-rtas.bin) and contents of spapr-rtas.bin read into rom->data
> (malloc-ed region).
>
> I think, access to spapr->rtas_addr is mapped to this rom. Hence it is
> necessary to have rtas_addr and rtas_size consistent with the Rom
> struct. If we use spapr->rtas_addr + RTAS_ENTRY_OFFSET then we are
> trying to access an invalid offset in rom region.


What is that "rom" struct you are referring to? In upstream QEMU, I can
only see:

ppc_spapr_init():
[...]
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin")
spapr->rtas_size = get_image_size(filename);
spapr->rtas_blob = g_malloc(spapr->rtas_size);
if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
[...]

and then

ppc_spapr_reset():
[...]
spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE
[...]
cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
                          spapr->rtas_size);
[...]



> 
> 
>>
>>
>>>
>>>>
>>>>
>>>>
>>>>
>>>>>  	mr	4,3
>>>>>  	lis	3,KVMPPC_H_RTAS@h
>>>>>  	ori	3,3,KVMPPC_H_RTAS@l
>>>>>
>>>>
>>>>
>>>
>>
>>
> 


-- 
Alexey Kardashevskiy
IBM OzLabs, LTC Team

e-mail: aik@au1.ibm.com
notes: Alexey Kardashevskiy/Australia/IBM

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-09-02  5:49           ` Alexey Kardashevskiy
@ 2014-09-02  5:56             ` Aravinda Prasad
  2014-09-02  6:34               ` Alexey Kardashevskiy
  0 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-09-02  5:56 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: benh, qemu-ppc, qemu-devel, paulus



On Tuesday 02 September 2014 11:19 AM, Alexey Kardashevskiy wrote:
> On 09/02/2014 03:25 PM, Aravinda Prasad wrote:
>>
>>
>> On Tuesday 02 September 2014 09:39 AM, Alexey Kardashevskiy wrote:
>>> On 09/01/2014 09:23 PM, Aravinda Prasad wrote:
>>>>
>>>>
>>>> On Monday 01 September 2014 01:16 PM, Alexey Kardashevskiy wrote:
>>>>> On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
>>>>>> Extend rtas-blob to accommodate error log. Error log
>>>>>> structure is saved in rtas space upon a machine check
>>>>>> exception.
>>>>>>
>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>> ---
>>>>>>  hw/ppc/spapr.c                  |   13 ++++++++++---
>>>>>>  hw/ppc/spapr_rtas.c             |    4 ++--
>>>>>>  include/hw/ppc/spapr.h          |    2 +-
>>>>>>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>>>>>>  4 files changed, 25 insertions(+), 6 deletions(-)
>>>>>>
>>>>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>>>>> index d01978f..1120988 100644
>>>>>> --- a/hw/ppc/spapr.c
>>>>>> +++ b/hw/ppc/spapr.c
>>>>>> @@ -85,6 +85,12 @@
>>>>>>  
>>>>>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>>>>>  
>>>>>> +/*
>>>>>> + * The rtas-entry-offset should match the value specified in
>>>>>> + * spapr-rtas.S
>>>>>> + */
>>>>>> +#define RTAS_ENTRY_OFFSET       0x1000
>>>>>> +
>>>>>>  typedef struct sPAPRMachineState sPAPRMachineState;
>>>>>>  
>>>>>>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
>>>>>> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>>>>>>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>                                 hwaddr fdt_addr,
>>>>>>                                 hwaddr rtas_addr,
>>>>>> -                               hwaddr rtas_size)
>>>>>> +                               hwaddr rtas_size,
>>>>>> +                               hwaddr rtas_entry)
>>>>>>  {
>>>>>>      int ret, i;
>>>>>>      size_t cb = 0;
>>>>>> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>      }
>>>>>>  
>>>>>>      /* RTAS */
>>>>>> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
>>>>>> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>>>>>>      if (ret < 0) {
>>>>>>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>>>>>>      }
>>>>>> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>>>>>>  
>>>>>>      /* Load the fdt */
>>>>>>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
>>>>>> -                       spapr->rtas_size);
>>>>>> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>>>>>>  
>>>>>>      /* Set up the entry state */
>>>>>>      first_ppc_cpu = POWERPC_CPU(first_cpu);
>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>> index 9ba1ba6..02ddbf9 100644
>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>>>>>>  }
>>>>>>  
>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>> -                                 hwaddr rtas_size)
>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>>>>>>  {
>>>>>>      int ret;
>>>>>>      int i;
>>>>>> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>      }
>>>>>>  
>>>>>>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
>>>>>> -                                rtas_addr);
>>>>>> +                                rtas_entry);
>>>>>>      if (ret < 0) {
>>>>>>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>>>>>>                  fdt_strerror(ret));
>>>>>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>>>>>> index bbba51a..dedfa67 100644
>>>>>> --- a/include/hw/ppc/spapr.h
>>>>>> +++ b/include/hw/ppc/spapr.h
>>>>>> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>>>>>                               uint32_t token, uint32_t nargs, target_ulong args,
>>>>>>                               uint32_t nret, target_ulong rets);
>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>> -                                 hwaddr rtas_size);
>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>>>>>>  
>>>>>>  #define SPAPR_TCE_PAGE_SHIFT   12
>>>>>>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
>>>>>> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>> index 903bec2..8c9b17e 100644
>>>>>> --- a/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>> @@ -30,6 +30,18 @@
>>>>>>  
>>>>>>  .globl	_start
>>>>>>  _start:
>>>>>> +	/*
>>>>>> +	 * Reserve space for error log in RTAS blob.
>>>>>> +	 *
>>>>>> +	 * Either we can reserve initial bytes for error log followed by
>>>>>> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
>>>>>> +	 * former, as we already have rtas-base and rtas-entry (currently
>>>>>> +	 * both pointing to rtas-base) defined in qemu and we can update
>>>>>> +	 * rtas-entry to point to an offset from rtas-base. This avoids
>>>>>> +	 * unnecessary definition of rtas-error-offset while keeping
>>>>>> +	 * rtas-entry redundant.
>>>>>> +	 */
>>>>>> +	. = 0x1000
>>>>>
>>>>>
>>>>> Why not this (and not changing spapr-rtas.S)?
>>>>>
>>>>> --- a/hw/ppc/spapr.c
>>>>> +++ b/hw/ppc/spapr.c
>>>>> @@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
>>>>>                         spapr->rtas_size);
>>>>>
>>>>>      /* Copy RTAS over */
>>>>> -    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>>> +    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
>>>>> +                              spapr->rtas_blob,
>>>>>                                spapr->rtas_size);
>>>>
>>>> This is possible, however requires suitable adjustment to make sure
>>>> spapr->rtas_addr has enough space allocated.
>>>
>>>
>>> How is adding RTAS_ENTRY_OFFSET not enough to make sure that is has enough
>>> space? QEMU copies RTAS to guest memory, QEMU makes up rtas_addr/entry
>>> properties.
>>
>> QEMU adds spapr-rtas.bin as a rom, with rom->addr set to
>> spapr->rtas_addr, rom->datasize set to 20 bytes (the size of current
>> spapr-rtas.bin) and contents of spapr-rtas.bin read into rom->data
>> (malloc-ed region).
>>
>> I think, access to spapr->rtas_addr is mapped to this rom. Hence it is
>> necessary to have rtas_addr and rtas_size consistent with the Rom
>> struct. If we use spapr->rtas_addr + RTAS_ENTRY_OFFSET then we are
>> trying to access an invalid offset in rom region.
> 
> 
> What is that "rom" struct you are referring to? In upstream QEMU, I can
> only see:
> 
> ppc_spapr_init():
> [...]
> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin")

In ppc_spapr_init() just after qemu_find_file() we have:

spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr, ...);

load_image_targphys() -> rom_add_file_fixed() -> rom_add_file(), where
Rom is initialized.

> spapr->rtas_size = get_image_size(filename);
> spapr->rtas_blob = g_malloc(spapr->rtas_size);
> if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
> [...]
> 
> and then
> 
> ppc_spapr_reset():
> [...]
> spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE
> [...]
> cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>                           spapr->rtas_size);
> [...]
> 
> 
> 
>>
>>
>>>
>>>
>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>  	mr	4,3
>>>>>>  	lis	3,KVMPPC_H_RTAS@h
>>>>>>  	ori	3,3,KVMPPC_H_RTAS@l
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>
> 
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-09-02  5:56             ` Aravinda Prasad
@ 2014-09-02  6:34               ` Alexey Kardashevskiy
  2014-09-02  7:07                 ` Aravinda Prasad
  0 siblings, 1 reply; 73+ messages in thread
From: Alexey Kardashevskiy @ 2014-09-02  6:34 UTC (permalink / raw)
  To: Aravinda Prasad, Alexey Kardashevskiy; +Cc: paulus, benh, qemu-ppc, qemu-devel

On 09/02/2014 03:56 PM, Aravinda Prasad wrote:
> 
> 
> On Tuesday 02 September 2014 11:19 AM, Alexey Kardashevskiy wrote:
>> On 09/02/2014 03:25 PM, Aravinda Prasad wrote:
>>>
>>>
>>> On Tuesday 02 September 2014 09:39 AM, Alexey Kardashevskiy wrote:
>>>> On 09/01/2014 09:23 PM, Aravinda Prasad wrote:
>>>>>
>>>>>
>>>>> On Monday 01 September 2014 01:16 PM, Alexey Kardashevskiy wrote:
>>>>>> On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
>>>>>>> Extend rtas-blob to accommodate error log. Error log
>>>>>>> structure is saved in rtas space upon a machine check
>>>>>>> exception.
>>>>>>>
>>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>>> ---
>>>>>>>  hw/ppc/spapr.c                  |   13 ++++++++++---
>>>>>>>  hw/ppc/spapr_rtas.c             |    4 ++--
>>>>>>>  include/hw/ppc/spapr.h          |    2 +-
>>>>>>>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>>>>>>>  4 files changed, 25 insertions(+), 6 deletions(-)
>>>>>>>
>>>>>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>>>>>> index d01978f..1120988 100644
>>>>>>> --- a/hw/ppc/spapr.c
>>>>>>> +++ b/hw/ppc/spapr.c
>>>>>>> @@ -85,6 +85,12 @@
>>>>>>>  
>>>>>>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>>>>>>  
>>>>>>> +/*
>>>>>>> + * The rtas-entry-offset should match the value specified in
>>>>>>> + * spapr-rtas.S
>>>>>>> + */
>>>>>>> +#define RTAS_ENTRY_OFFSET       0x1000
>>>>>>> +
>>>>>>>  typedef struct sPAPRMachineState sPAPRMachineState;
>>>>>>>  
>>>>>>>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
>>>>>>> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>>>>>>>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>>                                 hwaddr fdt_addr,
>>>>>>>                                 hwaddr rtas_addr,
>>>>>>> -                               hwaddr rtas_size)
>>>>>>> +                               hwaddr rtas_size,
>>>>>>> +                               hwaddr rtas_entry)
>>>>>>>  {
>>>>>>>      int ret, i;
>>>>>>>      size_t cb = 0;
>>>>>>> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>>      }
>>>>>>>  
>>>>>>>      /* RTAS */
>>>>>>> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
>>>>>>> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>>>>>>>      if (ret < 0) {
>>>>>>>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>>>>>>>      }
>>>>>>> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>>>>>>>  
>>>>>>>      /* Load the fdt */
>>>>>>>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
>>>>>>> -                       spapr->rtas_size);
>>>>>>> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>>>>>>>  
>>>>>>>      /* Set up the entry state */
>>>>>>>      first_ppc_cpu = POWERPC_CPU(first_cpu);
>>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>>> index 9ba1ba6..02ddbf9 100644
>>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>>> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>>>>>>>  }
>>>>>>>  
>>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>> -                                 hwaddr rtas_size)
>>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>>>>>>>  {
>>>>>>>      int ret;
>>>>>>>      int i;
>>>>>>> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>      }
>>>>>>>  
>>>>>>>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
>>>>>>> -                                rtas_addr);
>>>>>>> +                                rtas_entry);
>>>>>>>      if (ret < 0) {
>>>>>>>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>>>>>>>                  fdt_strerror(ret));
>>>>>>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>>>>>>> index bbba51a..dedfa67 100644
>>>>>>> --- a/include/hw/ppc/spapr.h
>>>>>>> +++ b/include/hw/ppc/spapr.h
>>>>>>> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>>>>>>                               uint32_t token, uint32_t nargs, target_ulong args,
>>>>>>>                               uint32_t nret, target_ulong rets);
>>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>> -                                 hwaddr rtas_size);
>>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>>>>>>>  
>>>>>>>  #define SPAPR_TCE_PAGE_SHIFT   12
>>>>>>>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
>>>>>>> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>> index 903bec2..8c9b17e 100644
>>>>>>> --- a/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>> @@ -30,6 +30,18 @@
>>>>>>>  
>>>>>>>  .globl	_start
>>>>>>>  _start:
>>>>>>> +	/*
>>>>>>> +	 * Reserve space for error log in RTAS blob.
>>>>>>> +	 *
>>>>>>> +	 * Either we can reserve initial bytes for error log followed by
>>>>>>> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
>>>>>>> +	 * former, as we already have rtas-base and rtas-entry (currently
>>>>>>> +	 * both pointing to rtas-base) defined in qemu and we can update
>>>>>>> +	 * rtas-entry to point to an offset from rtas-base. This avoids
>>>>>>> +	 * unnecessary definition of rtas-error-offset while keeping
>>>>>>> +	 * rtas-entry redundant.
>>>>>>> +	 */
>>>>>>> +	. = 0x1000
>>>>>>
>>>>>>
>>>>>> Why not this (and not changing spapr-rtas.S)?
>>>>>>
>>>>>> --- a/hw/ppc/spapr.c
>>>>>> +++ b/hw/ppc/spapr.c
>>>>>> @@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
>>>>>>                         spapr->rtas_size);
>>>>>>
>>>>>>      /* Copy RTAS over */
>>>>>> -    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>>>> +    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
>>>>>> +                              spapr->rtas_blob,
>>>>>>                                spapr->rtas_size);
>>>>>
>>>>> This is possible, however requires suitable adjustment to make sure
>>>>> spapr->rtas_addr has enough space allocated.
>>>>
>>>>
>>>> How is adding RTAS_ENTRY_OFFSET not enough to make sure that is has enough
>>>> space? QEMU copies RTAS to guest memory, QEMU makes up rtas_addr/entry
>>>> properties.
>>>
>>> QEMU adds spapr-rtas.bin as a rom, with rom->addr set to
>>> spapr->rtas_addr, rom->datasize set to 20 bytes (the size of current
>>> spapr-rtas.bin) and contents of spapr-rtas.bin read into rom->data
>>> (malloc-ed region).
>>>
>>> I think, access to spapr->rtas_addr is mapped to this rom. Hence it is
>>> necessary to have rtas_addr and rtas_size consistent with the Rom
>>> struct. If we use spapr->rtas_addr + RTAS_ENTRY_OFFSET then we are
>>> trying to access an invalid offset in rom region.
>>
>>
>> What is that "rom" struct you are referring to? In upstream QEMU, I can
>> only see:
>>
>> ppc_spapr_init():
>> [...]
>> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin")
> 
> In ppc_spapr_init() just after qemu_find_file() we have:
> 
> spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr, ...);


What tree has this? Mine does not.

ka1:~/p/qemu$ grep load_image_targphys hw/ppc/spapr.c
            initrd_size = load_image_targphys(initrd_filename, initrd_base,
    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
ka1:~/p/qemu$



> 
> load_image_targphys() -> rom_add_file_fixed() -> rom_add_file(), where
> Rom is initialized.
> 
>> spapr->rtas_size = get_image_size(filename);
>> spapr->rtas_blob = g_malloc(spapr->rtas_size);
>> if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
>> [...]
>>
>> and then
>>
>> ppc_spapr_reset():
>> [...]
>> spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE
>> [...]
>> cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>                           spapr->rtas_size);
>> [...]
>>
>>
>>
>>>
>>>
>>>>
>>>>
>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>  	mr	4,3
>>>>>>>  	lis	3,KVMPPC_H_RTAS@h
>>>>>>>  	ori	3,3,KVMPPC_H_RTAS@l
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
> 


-- 
Alexey

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-09-02  6:34               ` Alexey Kardashevskiy
@ 2014-09-02  7:07                 ` Aravinda Prasad
  2014-09-02  8:40                   ` Alexey Kardashevskiy
  0 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-09-02  7:07 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: qemu-ppc, benh, Alexey Kardashevskiy, qemu-devel, paulus



On Tuesday 02 September 2014 12:04 PM, Alexey Kardashevskiy wrote:
> On 09/02/2014 03:56 PM, Aravinda Prasad wrote:
>>
>>
>> On Tuesday 02 September 2014 11:19 AM, Alexey Kardashevskiy wrote:
>>> On 09/02/2014 03:25 PM, Aravinda Prasad wrote:
>>>>
>>>>
>>>> On Tuesday 02 September 2014 09:39 AM, Alexey Kardashevskiy wrote:
>>>>> On 09/01/2014 09:23 PM, Aravinda Prasad wrote:
>>>>>>
>>>>>>
>>>>>> On Monday 01 September 2014 01:16 PM, Alexey Kardashevskiy wrote:
>>>>>>> On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
>>>>>>>> Extend rtas-blob to accommodate error log. Error log
>>>>>>>> structure is saved in rtas space upon a machine check
>>>>>>>> exception.
>>>>>>>>
>>>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>>>> ---
>>>>>>>>  hw/ppc/spapr.c                  |   13 ++++++++++---
>>>>>>>>  hw/ppc/spapr_rtas.c             |    4 ++--
>>>>>>>>  include/hw/ppc/spapr.h          |    2 +-
>>>>>>>>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>>>>>>>>  4 files changed, 25 insertions(+), 6 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>>>>>>> index d01978f..1120988 100644
>>>>>>>> --- a/hw/ppc/spapr.c
>>>>>>>> +++ b/hw/ppc/spapr.c
>>>>>>>> @@ -85,6 +85,12 @@
>>>>>>>>  
>>>>>>>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>>>>>>>  
>>>>>>>> +/*
>>>>>>>> + * The rtas-entry-offset should match the value specified in
>>>>>>>> + * spapr-rtas.S
>>>>>>>> + */
>>>>>>>> +#define RTAS_ENTRY_OFFSET       0x1000
>>>>>>>> +
>>>>>>>>  typedef struct sPAPRMachineState sPAPRMachineState;
>>>>>>>>  
>>>>>>>>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
>>>>>>>> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>>>>>>>>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>>>                                 hwaddr fdt_addr,
>>>>>>>>                                 hwaddr rtas_addr,
>>>>>>>> -                               hwaddr rtas_size)
>>>>>>>> +                               hwaddr rtas_size,
>>>>>>>> +                               hwaddr rtas_entry)
>>>>>>>>  {
>>>>>>>>      int ret, i;
>>>>>>>>      size_t cb = 0;
>>>>>>>> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>>>      }
>>>>>>>>  
>>>>>>>>      /* RTAS */
>>>>>>>> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
>>>>>>>> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>>>>>>>>      if (ret < 0) {
>>>>>>>>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>>>>>>>>      }
>>>>>>>> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>>>>>>>>  
>>>>>>>>      /* Load the fdt */
>>>>>>>>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
>>>>>>>> -                       spapr->rtas_size);
>>>>>>>> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>>>>>>>>  
>>>>>>>>      /* Set up the entry state */
>>>>>>>>      first_ppc_cpu = POWERPC_CPU(first_cpu);
>>>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>>>> index 9ba1ba6..02ddbf9 100644
>>>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>>>> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>>>>>>>>  }
>>>>>>>>  
>>>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>> -                                 hwaddr rtas_size)
>>>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>>>>>>>>  {
>>>>>>>>      int ret;
>>>>>>>>      int i;
>>>>>>>> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>>      }
>>>>>>>>  
>>>>>>>>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
>>>>>>>> -                                rtas_addr);
>>>>>>>> +                                rtas_entry);
>>>>>>>>      if (ret < 0) {
>>>>>>>>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>>>>>>>>                  fdt_strerror(ret));
>>>>>>>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>>>>>>>> index bbba51a..dedfa67 100644
>>>>>>>> --- a/include/hw/ppc/spapr.h
>>>>>>>> +++ b/include/hw/ppc/spapr.h
>>>>>>>> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>>>>>>>                               uint32_t token, uint32_t nargs, target_ulong args,
>>>>>>>>                               uint32_t nret, target_ulong rets);
>>>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>> -                                 hwaddr rtas_size);
>>>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>>>>>>>>  
>>>>>>>>  #define SPAPR_TCE_PAGE_SHIFT   12
>>>>>>>>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
>>>>>>>> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>> index 903bec2..8c9b17e 100644
>>>>>>>> --- a/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>> @@ -30,6 +30,18 @@
>>>>>>>>  
>>>>>>>>  .globl	_start
>>>>>>>>  _start:
>>>>>>>> +	/*
>>>>>>>> +	 * Reserve space for error log in RTAS blob.
>>>>>>>> +	 *
>>>>>>>> +	 * Either we can reserve initial bytes for error log followed by
>>>>>>>> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
>>>>>>>> +	 * former, as we already have rtas-base and rtas-entry (currently
>>>>>>>> +	 * both pointing to rtas-base) defined in qemu and we can update
>>>>>>>> +	 * rtas-entry to point to an offset from rtas-base. This avoids
>>>>>>>> +	 * unnecessary definition of rtas-error-offset while keeping
>>>>>>>> +	 * rtas-entry redundant.
>>>>>>>> +	 */
>>>>>>>> +	. = 0x1000
>>>>>>>
>>>>>>>
>>>>>>> Why not this (and not changing spapr-rtas.S)?
>>>>>>>
>>>>>>> --- a/hw/ppc/spapr.c
>>>>>>> +++ b/hw/ppc/spapr.c
>>>>>>> @@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
>>>>>>>                         spapr->rtas_size);
>>>>>>>
>>>>>>>      /* Copy RTAS over */
>>>>>>> -    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>>>>> +    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
>>>>>>> +                              spapr->rtas_blob,
>>>>>>>                                spapr->rtas_size);
>>>>>>
>>>>>> This is possible, however requires suitable adjustment to make sure
>>>>>> spapr->rtas_addr has enough space allocated.
>>>>>
>>>>>
>>>>> How is adding RTAS_ENTRY_OFFSET not enough to make sure that is has enough
>>>>> space? QEMU copies RTAS to guest memory, QEMU makes up rtas_addr/entry
>>>>> properties.
>>>>
>>>> QEMU adds spapr-rtas.bin as a rom, with rom->addr set to
>>>> spapr->rtas_addr, rom->datasize set to 20 bytes (the size of current
>>>> spapr-rtas.bin) and contents of spapr-rtas.bin read into rom->data
>>>> (malloc-ed region).
>>>>
>>>> I think, access to spapr->rtas_addr is mapped to this rom. Hence it is
>>>> necessary to have rtas_addr and rtas_size consistent with the Rom
>>>> struct. If we use spapr->rtas_addr + RTAS_ENTRY_OFFSET then we are
>>>> trying to access an invalid offset in rom region.
>>>
>>>
>>> What is that "rom" struct you are referring to? In upstream QEMU, I can
>>> only see:
>>>
>>> ppc_spapr_init():
>>> [...]
>>> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin")
>>
>> In ppc_spapr_init() just after qemu_find_file() we have:
>>
>> spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr, ...);
> 
> 
> What tree has this? Mine does not.
> 
> ka1:~/p/qemu$ grep load_image_targphys hw/ppc/spapr.c
>             initrd_size = load_image_targphys(initrd_filename, initrd_base,
>     fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> ka1:~/p/qemu$
> 

I am using git://git.qemu.org/qemu.git, master branch.

I have 88e89a57f9 as the latest commit and I see:

$ grep load_image_targphys hw/ppc/spapr.c
    spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr,
         initrd_size = load_image_targphys(initrd_filename, initrd_base,
    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);


This was introduced in commit a3467baa.

Regards,
Aravinda

> 
> 
>>
>> load_image_targphys() -> rom_add_file_fixed() -> rom_add_file(), where
>> Rom is initialized.
>>
>>> spapr->rtas_size = get_image_size(filename);
>>> spapr->rtas_blob = g_malloc(spapr->rtas_size);
>>> if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
>>> [...]
>>>
>>> and then
>>>
>>> ppc_spapr_reset():
>>> [...]
>>> spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE
>>> [...]
>>> cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>                           spapr->rtas_size);
>>> [...]
>>>
>>>
>>>
>>>>
>>>>
>>>>>
>>>>>
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>  	mr	4,3
>>>>>>>>  	lis	3,KVMPPC_H_RTAS@h
>>>>>>>>  	ori	3,3,KVMPPC_H_RTAS@l
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>
> 
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-09-02  7:07                 ` Aravinda Prasad
@ 2014-09-02  8:40                   ` Alexey Kardashevskiy
  2014-09-02  9:30                     ` Aravinda Prasad
  0 siblings, 1 reply; 73+ messages in thread
From: Alexey Kardashevskiy @ 2014-09-02  8:40 UTC (permalink / raw)
  To: Aravinda Prasad, Alexey Kardashevskiy; +Cc: paulus, benh, qemu-ppc, qemu-devel

On 09/02/2014 05:07 PM, Aravinda Prasad wrote:
> 
> 
> On Tuesday 02 September 2014 12:04 PM, Alexey Kardashevskiy wrote:
>> On 09/02/2014 03:56 PM, Aravinda Prasad wrote:
>>>
>>>
>>> On Tuesday 02 September 2014 11:19 AM, Alexey Kardashevskiy wrote:
>>>> On 09/02/2014 03:25 PM, Aravinda Prasad wrote:
>>>>>
>>>>>
>>>>> On Tuesday 02 September 2014 09:39 AM, Alexey Kardashevskiy wrote:
>>>>>> On 09/01/2014 09:23 PM, Aravinda Prasad wrote:
>>>>>>>
>>>>>>>
>>>>>>> On Monday 01 September 2014 01:16 PM, Alexey Kardashevskiy wrote:
>>>>>>>> On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
>>>>>>>>> Extend rtas-blob to accommodate error log. Error log
>>>>>>>>> structure is saved in rtas space upon a machine check
>>>>>>>>> exception.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>>>>> ---
>>>>>>>>>  hw/ppc/spapr.c                  |   13 ++++++++++---
>>>>>>>>>  hw/ppc/spapr_rtas.c             |    4 ++--
>>>>>>>>>  include/hw/ppc/spapr.h          |    2 +-
>>>>>>>>>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>>>>>>>>>  4 files changed, 25 insertions(+), 6 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>>>>>>>> index d01978f..1120988 100644
>>>>>>>>> --- a/hw/ppc/spapr.c
>>>>>>>>> +++ b/hw/ppc/spapr.c
>>>>>>>>> @@ -85,6 +85,12 @@
>>>>>>>>>  
>>>>>>>>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>>>>>>>>  
>>>>>>>>> +/*
>>>>>>>>> + * The rtas-entry-offset should match the value specified in
>>>>>>>>> + * spapr-rtas.S
>>>>>>>>> + */
>>>>>>>>> +#define RTAS_ENTRY_OFFSET       0x1000
>>>>>>>>> +
>>>>>>>>>  typedef struct sPAPRMachineState sPAPRMachineState;
>>>>>>>>>  
>>>>>>>>>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
>>>>>>>>> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>>>>>>>>>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>>>>                                 hwaddr fdt_addr,
>>>>>>>>>                                 hwaddr rtas_addr,
>>>>>>>>> -                               hwaddr rtas_size)
>>>>>>>>> +                               hwaddr rtas_size,
>>>>>>>>> +                               hwaddr rtas_entry)
>>>>>>>>>  {
>>>>>>>>>      int ret, i;
>>>>>>>>>      size_t cb = 0;
>>>>>>>>> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>>>>      }
>>>>>>>>>  
>>>>>>>>>      /* RTAS */
>>>>>>>>> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
>>>>>>>>> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>>>>>>>>>      if (ret < 0) {
>>>>>>>>>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>>>>>>>>>      }
>>>>>>>>> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>>>>>>>>>  
>>>>>>>>>      /* Load the fdt */
>>>>>>>>>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
>>>>>>>>> -                       spapr->rtas_size);
>>>>>>>>> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>>>>>>>>>  
>>>>>>>>>      /* Set up the entry state */
>>>>>>>>>      first_ppc_cpu = POWERPC_CPU(first_cpu);
>>>>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>>>>> index 9ba1ba6..02ddbf9 100644
>>>>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>>>>> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>>>>>>>>>  }
>>>>>>>>>  
>>>>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>>> -                                 hwaddr rtas_size)
>>>>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>>>>>>>>>  {
>>>>>>>>>      int ret;
>>>>>>>>>      int i;
>>>>>>>>> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>>>      }
>>>>>>>>>  
>>>>>>>>>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
>>>>>>>>> -                                rtas_addr);
>>>>>>>>> +                                rtas_entry);
>>>>>>>>>      if (ret < 0) {
>>>>>>>>>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>>>>>>>>>                  fdt_strerror(ret));
>>>>>>>>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>>>>>>>>> index bbba51a..dedfa67 100644
>>>>>>>>> --- a/include/hw/ppc/spapr.h
>>>>>>>>> +++ b/include/hw/ppc/spapr.h
>>>>>>>>> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>>>>>>>>                               uint32_t token, uint32_t nargs, target_ulong args,
>>>>>>>>>                               uint32_t nret, target_ulong rets);
>>>>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>>> -                                 hwaddr rtas_size);
>>>>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>>>>>>>>>  
>>>>>>>>>  #define SPAPR_TCE_PAGE_SHIFT   12
>>>>>>>>>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
>>>>>>>>> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>>> index 903bec2..8c9b17e 100644
>>>>>>>>> --- a/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>>> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>>> @@ -30,6 +30,18 @@
>>>>>>>>>  
>>>>>>>>>  .globl	_start
>>>>>>>>>  _start:
>>>>>>>>> +	/*
>>>>>>>>> +	 * Reserve space for error log in RTAS blob.
>>>>>>>>> +	 *
>>>>>>>>> +	 * Either we can reserve initial bytes for error log followed by
>>>>>>>>> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
>>>>>>>>> +	 * former, as we already have rtas-base and rtas-entry (currently
>>>>>>>>> +	 * both pointing to rtas-base) defined in qemu and we can update
>>>>>>>>> +	 * rtas-entry to point to an offset from rtas-base. This avoids
>>>>>>>>> +	 * unnecessary definition of rtas-error-offset while keeping
>>>>>>>>> +	 * rtas-entry redundant.
>>>>>>>>> +	 */
>>>>>>>>> +	. = 0x1000
>>>>>>>>
>>>>>>>>
>>>>>>>> Why not this (and not changing spapr-rtas.S)?
>>>>>>>>
>>>>>>>> --- a/hw/ppc/spapr.c
>>>>>>>> +++ b/hw/ppc/spapr.c
>>>>>>>> @@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
>>>>>>>>                         spapr->rtas_size);
>>>>>>>>
>>>>>>>>      /* Copy RTAS over */
>>>>>>>> -    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>>>>>> +    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
>>>>>>>> +                              spapr->rtas_blob,
>>>>>>>>                                spapr->rtas_size);
>>>>>>>
>>>>>>> This is possible, however requires suitable adjustment to make sure
>>>>>>> spapr->rtas_addr has enough space allocated.
>>>>>>
>>>>>>
>>>>>> How is adding RTAS_ENTRY_OFFSET not enough to make sure that is has enough
>>>>>> space? QEMU copies RTAS to guest memory, QEMU makes up rtas_addr/entry
>>>>>> properties.
>>>>>
>>>>> QEMU adds spapr-rtas.bin as a rom, with rom->addr set to
>>>>> spapr->rtas_addr, rom->datasize set to 20 bytes (the size of current
>>>>> spapr-rtas.bin) and contents of spapr-rtas.bin read into rom->data
>>>>> (malloc-ed region).
>>>>>
>>>>> I think, access to spapr->rtas_addr is mapped to this rom. Hence it is
>>>>> necessary to have rtas_addr and rtas_size consistent with the Rom
>>>>> struct. If we use spapr->rtas_addr + RTAS_ENTRY_OFFSET then we are
>>>>> trying to access an invalid offset in rom region.
>>>>
>>>>
>>>> What is that "rom" struct you are referring to? In upstream QEMU, I can
>>>> only see:
>>>>
>>>> ppc_spapr_init():
>>>> [...]
>>>> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin")
>>>
>>> In ppc_spapr_init() just after qemu_find_file() we have:
>>>
>>> spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr, ...);
>>
>>
>> What tree has this? Mine does not.
>>
>> ka1:~/p/qemu$ grep load_image_targphys hw/ppc/spapr.c
>>             initrd_size = load_image_targphys(initrd_filename, initrd_base,
>>     fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
>> ka1:~/p/qemu$
>>
> 
> I am using git://git.qemu.org/qemu.git, master branch.

Ah. I see. My bad, I recommended the wrong tree then, sorry about it...

This one is the current queue of ppc patches and I believe this patchset
will go through it:
git://github.com/agraf/qemu.git  branch: ppc-next

And it does not have load_image_targphys() for rtas.


> 
> I have 88e89a57f9 as the latest commit and I see:
> 
> $ grep load_image_targphys hw/ppc/spapr.c
>     spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr,
>          initrd_size = load_image_targphys(initrd_filename, initrd_base,
>     fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> 
> 
> This was introduced in commit a3467baa.
> 
> Regards,
> Aravinda
> 
>>
>>
>>>
>>> load_image_targphys() -> rom_add_file_fixed() -> rom_add_file(), where
>>> Rom is initialized.
>>>
>>>> spapr->rtas_size = get_image_size(filename);
>>>> spapr->rtas_blob = g_malloc(spapr->rtas_size);
>>>> if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
>>>> [...]
>>>>
>>>> and then
>>>>
>>>> ppc_spapr_reset():
>>>> [...]
>>>> spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE
>>>> [...]
>>>> cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>>                           spapr->rtas_size);
>>>> [...]
>>>>
>>>>
>>>>
>>>>>
>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>>  	mr	4,3
>>>>>>>>>  	lis	3,KVMPPC_H_RTAS@h
>>>>>>>>>  	ori	3,3,KVMPPC_H_RTAS@l
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
> 


-- 
Alexey Kardashevskiy
IBM OzLabs, LTC Team

e-mail: aik@au1.ibm.com
notes: Alexey Kardashevskiy/Australia/IBM

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-09-02  8:40                   ` Alexey Kardashevskiy
@ 2014-09-02  9:30                     ` Aravinda Prasad
  2014-09-02 13:17                       ` Alexey Kardashevskiy
  0 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-09-02  9:30 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: Alexey Kardashevskiy, qemu-ppc, benh, paulus, qemu-devel



On Tuesday 02 September 2014 02:10 PM, Alexey Kardashevskiy wrote:
> On 09/02/2014 05:07 PM, Aravinda Prasad wrote:
>>
>>
>> On Tuesday 02 September 2014 12:04 PM, Alexey Kardashevskiy wrote:
>>> On 09/02/2014 03:56 PM, Aravinda Prasad wrote:
>>>>
>>>>
>>>> On Tuesday 02 September 2014 11:19 AM, Alexey Kardashevskiy wrote:
>>>>> On 09/02/2014 03:25 PM, Aravinda Prasad wrote:
>>>>>>
>>>>>>
>>>>>> On Tuesday 02 September 2014 09:39 AM, Alexey Kardashevskiy wrote:
>>>>>>> On 09/01/2014 09:23 PM, Aravinda Prasad wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On Monday 01 September 2014 01:16 PM, Alexey Kardashevskiy wrote:
>>>>>>>>> On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
>>>>>>>>>> Extend rtas-blob to accommodate error log. Error log
>>>>>>>>>> structure is saved in rtas space upon a machine check
>>>>>>>>>> exception.
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>>>>>> ---
>>>>>>>>>>  hw/ppc/spapr.c                  |   13 ++++++++++---
>>>>>>>>>>  hw/ppc/spapr_rtas.c             |    4 ++--
>>>>>>>>>>  include/hw/ppc/spapr.h          |    2 +-
>>>>>>>>>>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>>>>>>>>>>  4 files changed, 25 insertions(+), 6 deletions(-)
>>>>>>>>>>
>>>>>>>>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>>>>>>>>> index d01978f..1120988 100644
>>>>>>>>>> --- a/hw/ppc/spapr.c
>>>>>>>>>> +++ b/hw/ppc/spapr.c
>>>>>>>>>> @@ -85,6 +85,12 @@
>>>>>>>>>>  
>>>>>>>>>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>>>>>>>>>  
>>>>>>>>>> +/*
>>>>>>>>>> + * The rtas-entry-offset should match the value specified in
>>>>>>>>>> + * spapr-rtas.S
>>>>>>>>>> + */
>>>>>>>>>> +#define RTAS_ENTRY_OFFSET       0x1000
>>>>>>>>>> +
>>>>>>>>>>  typedef struct sPAPRMachineState sPAPRMachineState;
>>>>>>>>>>  
>>>>>>>>>>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
>>>>>>>>>> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>>>>>>>>>>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>>>>>                                 hwaddr fdt_addr,
>>>>>>>>>>                                 hwaddr rtas_addr,
>>>>>>>>>> -                               hwaddr rtas_size)
>>>>>>>>>> +                               hwaddr rtas_size,
>>>>>>>>>> +                               hwaddr rtas_entry)
>>>>>>>>>>  {
>>>>>>>>>>      int ret, i;
>>>>>>>>>>      size_t cb = 0;
>>>>>>>>>> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>>>>>      }
>>>>>>>>>>  
>>>>>>>>>>      /* RTAS */
>>>>>>>>>> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
>>>>>>>>>> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>>>>>>>>>>      if (ret < 0) {
>>>>>>>>>>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>>>>>>>>>>      }
>>>>>>>>>> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>>>>>>>>>>  
>>>>>>>>>>      /* Load the fdt */
>>>>>>>>>>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
>>>>>>>>>> -                       spapr->rtas_size);
>>>>>>>>>> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>>>>>>>>>>  
>>>>>>>>>>      /* Set up the entry state */
>>>>>>>>>>      first_ppc_cpu = POWERPC_CPU(first_cpu);
>>>>>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>>>>>> index 9ba1ba6..02ddbf9 100644
>>>>>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>>>>>> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>>>>>>>>>>  }
>>>>>>>>>>  
>>>>>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>>>> -                                 hwaddr rtas_size)
>>>>>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>>>>>>>>>>  {
>>>>>>>>>>      int ret;
>>>>>>>>>>      int i;
>>>>>>>>>> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>>>>      }
>>>>>>>>>>  
>>>>>>>>>>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
>>>>>>>>>> -                                rtas_addr);
>>>>>>>>>> +                                rtas_entry);
>>>>>>>>>>      if (ret < 0) {
>>>>>>>>>>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>>>>>>>>>>                  fdt_strerror(ret));
>>>>>>>>>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>>>>>>>>>> index bbba51a..dedfa67 100644
>>>>>>>>>> --- a/include/hw/ppc/spapr.h
>>>>>>>>>> +++ b/include/hw/ppc/spapr.h
>>>>>>>>>> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>>>>>>>>>                               uint32_t token, uint32_t nargs, target_ulong args,
>>>>>>>>>>                               uint32_t nret, target_ulong rets);
>>>>>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>>>> -                                 hwaddr rtas_size);
>>>>>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>>>>>>>>>>  
>>>>>>>>>>  #define SPAPR_TCE_PAGE_SHIFT   12
>>>>>>>>>>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
>>>>>>>>>> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>>>> index 903bec2..8c9b17e 100644
>>>>>>>>>> --- a/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>>>> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>>>> @@ -30,6 +30,18 @@
>>>>>>>>>>  
>>>>>>>>>>  .globl	_start
>>>>>>>>>>  _start:
>>>>>>>>>> +	/*
>>>>>>>>>> +	 * Reserve space for error log in RTAS blob.
>>>>>>>>>> +	 *
>>>>>>>>>> +	 * Either we can reserve initial bytes for error log followed by
>>>>>>>>>> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
>>>>>>>>>> +	 * former, as we already have rtas-base and rtas-entry (currently
>>>>>>>>>> +	 * both pointing to rtas-base) defined in qemu and we can update
>>>>>>>>>> +	 * rtas-entry to point to an offset from rtas-base. This avoids
>>>>>>>>>> +	 * unnecessary definition of rtas-error-offset while keeping
>>>>>>>>>> +	 * rtas-entry redundant.
>>>>>>>>>> +	 */
>>>>>>>>>> +	. = 0x1000
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Why not this (and not changing spapr-rtas.S)?
>>>>>>>>>
>>>>>>>>> --- a/hw/ppc/spapr.c
>>>>>>>>> +++ b/hw/ppc/spapr.c
>>>>>>>>> @@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
>>>>>>>>>                         spapr->rtas_size);
>>>>>>>>>
>>>>>>>>>      /* Copy RTAS over */
>>>>>>>>> -    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>>>>>>> +    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
>>>>>>>>> +                              spapr->rtas_blob,
>>>>>>>>>                                spapr->rtas_size);
>>>>>>>>
>>>>>>>> This is possible, however requires suitable adjustment to make sure
>>>>>>>> spapr->rtas_addr has enough space allocated.
>>>>>>>
>>>>>>>
>>>>>>> How is adding RTAS_ENTRY_OFFSET not enough to make sure that is has enough
>>>>>>> space? QEMU copies RTAS to guest memory, QEMU makes up rtas_addr/entry
>>>>>>> properties.
>>>>>>
>>>>>> QEMU adds spapr-rtas.bin as a rom, with rom->addr set to
>>>>>> spapr->rtas_addr, rom->datasize set to 20 bytes (the size of current
>>>>>> spapr-rtas.bin) and contents of spapr-rtas.bin read into rom->data
>>>>>> (malloc-ed region).
>>>>>>
>>>>>> I think, access to spapr->rtas_addr is mapped to this rom. Hence it is
>>>>>> necessary to have rtas_addr and rtas_size consistent with the Rom
>>>>>> struct. If we use spapr->rtas_addr + RTAS_ENTRY_OFFSET then we are
>>>>>> trying to access an invalid offset in rom region.
>>>>>
>>>>>
>>>>> What is that "rom" struct you are referring to? In upstream QEMU, I can
>>>>> only see:
>>>>>
>>>>> ppc_spapr_init():
>>>>> [...]
>>>>> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin")
>>>>
>>>> In ppc_spapr_init() just after qemu_find_file() we have:
>>>>
>>>> spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr, ...);
>>>
>>>
>>> What tree has this? Mine does not.
>>>
>>> ka1:~/p/qemu$ grep load_image_targphys hw/ppc/spapr.c
>>>             initrd_size = load_image_targphys(initrd_filename, initrd_base,
>>>     fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
>>> ka1:~/p/qemu$
>>>
>>
>> I am using git://git.qemu.org/qemu.git, master branch.
> 
> Ah. I see. My bad, I recommended the wrong tree then, sorry about it...
> 
> This one is the current queue of ppc patches and I believe this patchset
> will go through it:
> git://github.com/agraf/qemu.git  branch: ppc-next
> 
> And it does not have load_image_targphys() for rtas.

Hmm.. ok. Let me have a look at it.

So my v2 should be based on git://github.com/agraf/qemu.git  branch:
ppc-next right?

> 
> 
>>
>> I have 88e89a57f9 as the latest commit and I see:
>>
>> $ grep load_image_targphys hw/ppc/spapr.c
>>     spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr,
>>          initrd_size = load_image_targphys(initrd_filename, initrd_base,
>>     fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
>>
>>
>> This was introduced in commit a3467baa.
>>
>> Regards,
>> Aravinda
>>
>>>
>>>
>>>>
>>>> load_image_targphys() -> rom_add_file_fixed() -> rom_add_file(), where
>>>> Rom is initialized.
>>>>
>>>>> spapr->rtas_size = get_image_size(filename);
>>>>> spapr->rtas_blob = g_malloc(spapr->rtas_size);
>>>>> if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
>>>>> [...]
>>>>>
>>>>> and then
>>>>>
>>>>> ppc_spapr_reset():
>>>>> [...]
>>>>> spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE
>>>>> [...]
>>>>> cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>>>                           spapr->rtas_size);
>>>>> [...]
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>>  	mr	4,3
>>>>>>>>>>  	lis	3,KVMPPC_H_RTAS@h
>>>>>>>>>>  	ori	3,3,KVMPPC_H_RTAS@l
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>
> 
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob
  2014-09-02  9:30                     ` Aravinda Prasad
@ 2014-09-02 13:17                       ` Alexey Kardashevskiy
  0 siblings, 0 replies; 73+ messages in thread
From: Alexey Kardashevskiy @ 2014-09-02 13:17 UTC (permalink / raw)
  To: Aravinda Prasad, Alexey Kardashevskiy; +Cc: qemu-ppc, benh, paulus, qemu-devel

On 09/02/2014 07:30 PM, Aravinda Prasad wrote:
> 
> 
> On Tuesday 02 September 2014 02:10 PM, Alexey Kardashevskiy wrote:
>> On 09/02/2014 05:07 PM, Aravinda Prasad wrote:
>>>
>>>
>>> On Tuesday 02 September 2014 12:04 PM, Alexey Kardashevskiy wrote:
>>>> On 09/02/2014 03:56 PM, Aravinda Prasad wrote:
>>>>>
>>>>>
>>>>> On Tuesday 02 September 2014 11:19 AM, Alexey Kardashevskiy wrote:
>>>>>> On 09/02/2014 03:25 PM, Aravinda Prasad wrote:
>>>>>>>
>>>>>>>
>>>>>>> On Tuesday 02 September 2014 09:39 AM, Alexey Kardashevskiy wrote:
>>>>>>>> On 09/01/2014 09:23 PM, Aravinda Prasad wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Monday 01 September 2014 01:16 PM, Alexey Kardashevskiy wrote:
>>>>>>>>>> On 08/25/2014 11:45 PM, Aravinda Prasad wrote:
>>>>>>>>>>> Extend rtas-blob to accommodate error log. Error log
>>>>>>>>>>> structure is saved in rtas space upon a machine check
>>>>>>>>>>> exception.
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>>>>>>> ---
>>>>>>>>>>>  hw/ppc/spapr.c                  |   13 ++++++++++---
>>>>>>>>>>>  hw/ppc/spapr_rtas.c             |    4 ++--
>>>>>>>>>>>  include/hw/ppc/spapr.h          |    2 +-
>>>>>>>>>>>  pc-bios/spapr-rtas/spapr-rtas.S |   12 ++++++++++++
>>>>>>>>>>>  4 files changed, 25 insertions(+), 6 deletions(-)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>>>>>>>>>> index d01978f..1120988 100644
>>>>>>>>>>> --- a/hw/ppc/spapr.c
>>>>>>>>>>> +++ b/hw/ppc/spapr.c
>>>>>>>>>>> @@ -85,6 +85,12 @@
>>>>>>>>>>>  
>>>>>>>>>>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>>>>>>>>>>  
>>>>>>>>>>> +/*
>>>>>>>>>>> + * The rtas-entry-offset should match the value specified in
>>>>>>>>>>> + * spapr-rtas.S
>>>>>>>>>>> + */
>>>>>>>>>>> +#define RTAS_ENTRY_OFFSET       0x1000
>>>>>>>>>>> +
>>>>>>>>>>>  typedef struct sPAPRMachineState sPAPRMachineState;
>>>>>>>>>>>  
>>>>>>>>>>>  #define TYPE_SPAPR_MACHINE      "spapr-machine"
>>>>>>>>>>> @@ -670,7 +676,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
>>>>>>>>>>>  static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>>>>>>                                 hwaddr fdt_addr,
>>>>>>>>>>>                                 hwaddr rtas_addr,
>>>>>>>>>>> -                               hwaddr rtas_size)
>>>>>>>>>>> +                               hwaddr rtas_size,
>>>>>>>>>>> +                               hwaddr rtas_entry)
>>>>>>>>>>>  {
>>>>>>>>>>>      int ret, i;
>>>>>>>>>>>      size_t cb = 0;
>>>>>>>>>>> @@ -705,7 +712,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>>>>>>>>>>>      }
>>>>>>>>>>>  
>>>>>>>>>>>      /* RTAS */
>>>>>>>>>>> -    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
>>>>>>>>>>> +    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size, rtas_entry);
>>>>>>>>>>>      if (ret < 0) {
>>>>>>>>>>>          fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
>>>>>>>>>>>      }
>>>>>>>>>>> @@ -808,7 +815,7 @@ static void ppc_spapr_reset(void)
>>>>>>>>>>>  
>>>>>>>>>>>      /* Load the fdt */
>>>>>>>>>>>      spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
>>>>>>>>>>> -                       spapr->rtas_size);
>>>>>>>>>>> +                       spapr->rtas_size, spapr->rtas_addr + RTAS_ENTRY_OFFSET);
>>>>>>>>>>>  
>>>>>>>>>>>      /* Set up the entry state */
>>>>>>>>>>>      first_ppc_cpu = POWERPC_CPU(first_cpu);
>>>>>>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>>>>>>> index 9ba1ba6..02ddbf9 100644
>>>>>>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>>>>>>> @@ -328,7 +328,7 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>>>>>>>>>>>  }
>>>>>>>>>>>  
>>>>>>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>>>>> -                                 hwaddr rtas_size)
>>>>>>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry)
>>>>>>>>>>>  {
>>>>>>>>>>>      int ret;
>>>>>>>>>>>      int i;
>>>>>>>>>>> @@ -349,7 +349,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>>>>>      }
>>>>>>>>>>>  
>>>>>>>>>>>      ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
>>>>>>>>>>> -                                rtas_addr);
>>>>>>>>>>> +                                rtas_entry);
>>>>>>>>>>>      if (ret < 0) {
>>>>>>>>>>>          fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
>>>>>>>>>>>                  fdt_strerror(ret));
>>>>>>>>>>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>>>>>>>>>>> index bbba51a..dedfa67 100644
>>>>>>>>>>> --- a/include/hw/ppc/spapr.h
>>>>>>>>>>> +++ b/include/hw/ppc/spapr.h
>>>>>>>>>>> @@ -436,7 +436,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>>>>>>>>>>                               uint32_t token, uint32_t nargs, target_ulong args,
>>>>>>>>>>>                               uint32_t nret, target_ulong rets);
>>>>>>>>>>>  int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>>>>>>>>>>> -                                 hwaddr rtas_size);
>>>>>>>>>>> +                                 hwaddr rtas_size, hwaddr rtas_entry);
>>>>>>>>>>>  
>>>>>>>>>>>  #define SPAPR_TCE_PAGE_SHIFT   12
>>>>>>>>>>>  #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
>>>>>>>>>>> diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>>>>> index 903bec2..8c9b17e 100644
>>>>>>>>>>> --- a/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>>>>> +++ b/pc-bios/spapr-rtas/spapr-rtas.S
>>>>>>>>>>> @@ -30,6 +30,18 @@
>>>>>>>>>>>  
>>>>>>>>>>>  .globl	_start
>>>>>>>>>>>  _start:
>>>>>>>>>>> +	/*
>>>>>>>>>>> +	 * Reserve space for error log in RTAS blob.
>>>>>>>>>>> +	 *
>>>>>>>>>>> +	 * Either we can reserve initial bytes for error log followed by
>>>>>>>>>>> +	 * rtas-entry or space can be reserved after rtas-entry. I prefer
>>>>>>>>>>> +	 * former, as we already have rtas-base and rtas-entry (currently
>>>>>>>>>>> +	 * both pointing to rtas-base) defined in qemu and we can update
>>>>>>>>>>> +	 * rtas-entry to point to an offset from rtas-base. This avoids
>>>>>>>>>>> +	 * unnecessary definition of rtas-error-offset while keeping
>>>>>>>>>>> +	 * rtas-entry redundant.
>>>>>>>>>>> +	 */
>>>>>>>>>>> +	. = 0x1000
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Why not this (and not changing spapr-rtas.S)?
>>>>>>>>>>
>>>>>>>>>> --- a/hw/ppc/spapr.c
>>>>>>>>>> +++ b/hw/ppc/spapr.c
>>>>>>>>>> @@ -875,7 +875,8 @@ static void ppc_spapr_reset(void)
>>>>>>>>>>                         spapr->rtas_size);
>>>>>>>>>>
>>>>>>>>>>      /* Copy RTAS over */
>>>>>>>>>> -    cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>>>>>>>> +    cpu_physical_memory_write(spapr->rtas_addr + RTAS_ENTRY_OFFSET,
>>>>>>>>>> +                              spapr->rtas_blob,
>>>>>>>>>>                                spapr->rtas_size);
>>>>>>>>>
>>>>>>>>> This is possible, however requires suitable adjustment to make sure
>>>>>>>>> spapr->rtas_addr has enough space allocated.
>>>>>>>>
>>>>>>>>
>>>>>>>> How is adding RTAS_ENTRY_OFFSET not enough to make sure that is has enough
>>>>>>>> space? QEMU copies RTAS to guest memory, QEMU makes up rtas_addr/entry
>>>>>>>> properties.
>>>>>>>
>>>>>>> QEMU adds spapr-rtas.bin as a rom, with rom->addr set to
>>>>>>> spapr->rtas_addr, rom->datasize set to 20 bytes (the size of current
>>>>>>> spapr-rtas.bin) and contents of spapr-rtas.bin read into rom->data
>>>>>>> (malloc-ed region).
>>>>>>>
>>>>>>> I think, access to spapr->rtas_addr is mapped to this rom. Hence it is
>>>>>>> necessary to have rtas_addr and rtas_size consistent with the Rom
>>>>>>> struct. If we use spapr->rtas_addr + RTAS_ENTRY_OFFSET then we are
>>>>>>> trying to access an invalid offset in rom region.
>>>>>>
>>>>>>
>>>>>> What is that "rom" struct you are referring to? In upstream QEMU, I can
>>>>>> only see:
>>>>>>
>>>>>> ppc_spapr_init():
>>>>>> [...]
>>>>>> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin")
>>>>>
>>>>> In ppc_spapr_init() just after qemu_find_file() we have:
>>>>>
>>>>> spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr, ...);
>>>>
>>>>
>>>> What tree has this? Mine does not.
>>>>
>>>> ka1:~/p/qemu$ grep load_image_targphys hw/ppc/spapr.c
>>>>             initrd_size = load_image_targphys(initrd_filename, initrd_base,
>>>>     fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
>>>> ka1:~/p/qemu$
>>>>
>>>
>>> I am using git://git.qemu.org/qemu.git, master branch.
>>
>> Ah. I see. My bad, I recommended the wrong tree then, sorry about it...
>>
>> This one is the current queue of ppc patches and I believe this patchset
>> will go through it:
>> git://github.com/agraf/qemu.git  branch: ppc-next
>>
>> And it does not have load_image_targphys() for rtas.
> 
> Hmm.. ok. Let me have a look at it.
> 
> So my v2 should be based on git://github.com/agraf/qemu.git  branch:
> ppc-next right?


Yes since this branch is closer to upstream and affects what you do.



> 
>>
>>
>>>
>>> I have 88e89a57f9 as the latest commit and I see:
>>>
>>> $ grep load_image_targphys hw/ppc/spapr.c
>>>     spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr,
>>>          initrd_size = load_image_targphys(initrd_filename, initrd_base,
>>>     fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
>>>
>>>
>>> This was introduced in commit a3467baa.
>>>
>>> Regards,
>>> Aravinda
>>>
>>>>
>>>>
>>>>>
>>>>> load_image_targphys() -> rom_add_file_fixed() -> rom_add_file(), where
>>>>> Rom is initialized.
>>>>>
>>>>>> spapr->rtas_size = get_image_size(filename);
>>>>>> spapr->rtas_blob = g_malloc(spapr->rtas_size);
>>>>>> if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
>>>>>> [...]
>>>>>>
>>>>>> and then
>>>>>>
>>>>>> ppc_spapr_reset():
>>>>>> [...]
>>>>>> spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE
>>>>>> [...]
>>>>>> cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
>>>>>>                           spapr->rtas_size);
>>>>>> [...]


-- 
Alexey

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-28 22:16           ` Alexander Graf
  2014-08-30  8:08             ` Aravinda Prasad
@ 2014-09-04  8:25             ` Aravinda Prasad
  2014-09-04 13:09               ` Alexander Graf
  1 sibling, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-09-04  8:25 UTC (permalink / raw)
  To: Alexander Graf; +Cc: aik, benh, qemu-ppc, qemu-devel, paulus



On Friday 29 August 2014 03:46 AM, Alexander Graf wrote:
> 
> 
> On 28.08.14 19:42, Aravinda Prasad wrote:
>>
>>
>> On Thursday 28 August 2014 02:07 PM, Alexander Graf wrote:
>>>
>>>
>>> On 28.08.14 08:38, Aravinda Prasad wrote:
>>>>
>>>>
>>>> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>>>>
>>>>>
>>>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>>>> This patch adds FWNMI support in qemu for powerKVM
>>>>>> guests by handling the ibm,nmi-register rtas call.
>>>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>>>> machine check notification address is saved and the
>>>>>> machine check interrupt vector 0x200 is patched to
>>>>>> issue a private hcall.
>>>>>>
>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>> ---
>>>>>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>  include/hw/ppc/spapr.h |    8 ++++
>>>>>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>> index 02ddbf9..1135d2b 100644
>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>>>      rtas_st(rets, 0, ret);
>>>>>>  }
>>>>>>  
>>>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>>>> +                                  sPAPREnvironment *spapr,
>>>>>> +                                  uint32_t token, uint32_t nargs,
>>>>>> +                                  target_ulong args,
>>>>>> +                                  uint32_t nret, target_ulong rets)
>>>>>> +{
>>>>>> +    int i;
>>>>>> +    uint32_t branch_inst = 0x48000002;
>>>>>> +    target_ulong guest_machine_check_addr;
>>>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>>>> +    /*
>>>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>>>> +     * to request qemu to build error log. QEMU builds the
>>>>>> +     * error log, copies to rtas-blob and returns the address.
>>>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>>>> +     * and srr1 which we restore and pass on the actual error
>>>>>> +     * log address to OS handled mcachine check notification
>>>>>> +     * routine
>>>>>> +     */
>>>>>> +    uint32_t trampoline[] = {
>>>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>>>> +        0x38600000,    /* li      r3,0   */
>>>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>>>> +        /* Issue H_CALL */
>>>>>> +        0x44000022,    /*  sc      1     */
>>>>>
>>>>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>>>>> clobber it?) and call our special hypercall.
>>>>>
>>>>> But what does all the cruft below here do?
>>>>
>>>> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
>>>> can clobber SPRG2 after hcall returns. I have included a comment in
>>>> patch 3/5 while building error log. I think better I add one here as well.
>>>>
>>>>>
>>>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>>>
>>>>> Apart from th fact that your order is wrong, this destroys the value of
>>>>> r3 that we saved above again.
>>>>
>>>> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
>>>> KVMPPC_H_REPORT_ERR hcall returns.
>>>>
>>>>>
>>>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>>>
>>>>> Can't we just set srr0 and srr1 directly?
>>>>
>>>> I checked for instructions in ISA which set srr0/1 directly given an
>>>> address, but could not find any such instructions.
>>>
>>> I mean from QEMU :).
>>
>> srr0 and srr1, which are properly set when 0x200 is invoked, are
>> clobbered when we return from KVMPPC_H_REPORT_ERR hcall. I think they
>> are modified before issuing rfid (I can see them getting clobbered from
>> QEMU monitor). However when we jump to OS registered machine check
>> routine srr0 and srr1 should reflect the value they had when 0x200 was
>> invoked.
>>
>> Hence srr0 and srr1 are saved in hcall and restored when we return from
>> hcall. Also we don't have enough scratch registers available to save
>> these before invoking hcall from 0x200.
>>
>> Or am I missing other ways to do this from QEMU?
> 
> If you just do
> 
> cpu_synchronize_state() and then change env->spr[SPRN_SRR0/1] inside
> your hypercall handler that should also change the value when you return
> from the hcall.

I tried cpu_synchronize_state(), however, srr0 and srr1 are still clobbered.

Just before I issue hcall from 0x200 I see the following values from
QEMU monitor:

SRR0 d000000000f40264  SRR1 8000000000209033

Inside hcall, I call cpu_synchronize_state(). As soon as I return from
hcall I see:

SRR0 0000000000000214  SRR1 8000000000001001

I see SRR0 is now set to nip in 0x200 and SRR1 to msr value. I think it
is reset during returning from hcall before executing rfid.

So I think I still need to explicitly save/restore srr0 and srr1 across
hcall.

> 
> 
> Alex
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-09-04  8:25             ` Aravinda Prasad
@ 2014-09-04 13:09               ` Alexander Graf
  2014-09-04 13:49                 ` Aravinda Prasad
  0 siblings, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-09-04 13:09 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: aik, benh, qemu-ppc, qemu-devel, paulus



> Am 04.09.2014 um 10:25 schrieb Aravinda Prasad <aravinda@linux.vnet.ibm.com>:
> 
> 
> 
>> On Friday 29 August 2014 03:46 AM, Alexander Graf wrote:
>> 
>> 
>>> On 28.08.14 19:42, Aravinda Prasad wrote:
>>> 
>>> 
>>>> On Thursday 28 August 2014 02:07 PM, Alexander Graf wrote:
>>>> 
>>>> 
>>>>> On 28.08.14 08:38, Aravinda Prasad wrote:
>>>>> 
>>>>> 
>>>>>> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>>>>> 
>>>>>> 
>>>>>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>>>>> This patch adds FWNMI support in qemu for powerKVM
>>>>>>> guests by handling the ibm,nmi-register rtas call.
>>>>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>>>>> machine check notification address is saved and the
>>>>>>> machine check interrupt vector 0x200 is patched to
>>>>>>> issue a private hcall.
>>>>>>> 
>>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>>> ---
>>>>>>> hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>> include/hw/ppc/spapr.h |    8 ++++
>>>>>>> 2 files changed, 98 insertions(+), 1 deletion(-)
>>>>>>> 
>>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>>> index 02ddbf9..1135d2b 100644
>>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>>>>     rtas_st(rets, 0, ret);
>>>>>>> }
>>>>>>> 
>>>>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>>>>> +                                  sPAPREnvironment *spapr,
>>>>>>> +                                  uint32_t token, uint32_t nargs,
>>>>>>> +                                  target_ulong args,
>>>>>>> +                                  uint32_t nret, target_ulong rets)
>>>>>>> +{
>>>>>>> +    int i;
>>>>>>> +    uint32_t branch_inst = 0x48000002;
>>>>>>> +    target_ulong guest_machine_check_addr;
>>>>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>>>>> +    /*
>>>>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>>>>> +     * to request qemu to build error log. QEMU builds the
>>>>>>> +     * error log, copies to rtas-blob and returns the address.
>>>>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>>>>> +     * and srr1 which we restore and pass on the actual error
>>>>>>> +     * log address to OS handled mcachine check notification
>>>>>>> +     * routine
>>>>>>> +     */
>>>>>>> +    uint32_t trampoline[] = {
>>>>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>>>>> +        0x38600000,    /* li      r3,0   */
>>>>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>>>>> +        /* Issue H_CALL */
>>>>>>> +        0x44000022,    /*  sc      1     */
>>>>>> 
>>>>>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>>>>>> clobber it?) and call our special hypercall.
>>>>>> 
>>>>>> But what does all the cruft below here do?
>>>>> 
>>>>> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
>>>>> can clobber SPRG2 after hcall returns. I have included a comment in
>>>>> patch 3/5 while building error log. I think better I add one here as well.
>>>>> 
>>>>>> 
>>>>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>>>> 
>>>>>> Apart from th fact that your order is wrong, this destroys the value of
>>>>>> r3 that we saved above again.
>>>>> 
>>>>> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
>>>>> KVMPPC_H_REPORT_ERR hcall returns.
>>>>> 
>>>>>> 
>>>>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>>>> 
>>>>>> Can't we just set srr0 and srr1 directly?
>>>>> 
>>>>> I checked for instructions in ISA which set srr0/1 directly given an
>>>>> address, but could not find any such instructions.
>>>> 
>>>> I mean from QEMU :).
>>> 
>>> srr0 and srr1, which are properly set when 0x200 is invoked, are
>>> clobbered when we return from KVMPPC_H_REPORT_ERR hcall. I think they
>>> are modified before issuing rfid (I can see them getting clobbered from
>>> QEMU monitor). However when we jump to OS registered machine check
>>> routine srr0 and srr1 should reflect the value they had when 0x200 was
>>> invoked.
>>> 
>>> Hence srr0 and srr1 are saved in hcall and restored when we return from
>>> hcall. Also we don't have enough scratch registers available to save
>>> these before invoking hcall from 0x200.
>>> 
>>> Or am I missing other ways to do this from QEMU?
>> 
>> If you just do
>> 
>> cpu_synchronize_state() and then change env->spr[SPRN_SRR0/1] inside
>> your hypercall handler that should also change the value when you return
>> from the hcall.
> 
> I tried cpu_synchronize_state(), however, srr0 and srr1 are still clobbered.
> 
> Just before I issue hcall from 0x200 I see the following values from
> QEMU monitor:
> 
> SRR0 d000000000f40264  SRR1 8000000000209033
> 
> Inside hcall, I call cpu_synchronize_state(). As soon as I return from
> hcall I see:
> 
> SRR0 0000000000000214  SRR1 8000000000001001
> 
> I see SRR0 is now set to nip in 0x200 and SRR1 to msr value. I think it
> is reset during returning from hcall before executing rfid.
> 
> So I think I still need to explicitly save/restore srr0 and srr1 across
> hcall.

Please paste the diff that you did to enable use of cpu_synchronize_state().

Alex

> 
>> 
>> 
>> Alex
> 
> -- 
> Regards,
> Aravinda
> 

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-09-04 13:09               ` Alexander Graf
@ 2014-09-04 13:49                 ` Aravinda Prasad
  2014-09-05  8:46                   ` Alexander Graf
  0 siblings, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-09-04 13:49 UTC (permalink / raw)
  To: Alexander Graf; +Cc: aik, benh, qemu-ppc, qemu-devel, paulus



On Thursday 04 September 2014 06:39 PM, Alexander Graf wrote:
> 
> 
>> Am 04.09.2014 um 10:25 schrieb Aravinda Prasad <aravinda@linux.vnet.ibm.com>:
>>
>>
>>
>>> On Friday 29 August 2014 03:46 AM, Alexander Graf wrote:
>>>
>>>
>>>> On 28.08.14 19:42, Aravinda Prasad wrote:
>>>>
>>>>
>>>>> On Thursday 28 August 2014 02:07 PM, Alexander Graf wrote:
>>>>>
>>>>>
>>>>>> On 28.08.14 08:38, Aravinda Prasad wrote:
>>>>>>
>>>>>>
>>>>>>> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>>>>>>
>>>>>>>
>>>>>>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>>>>>> This patch adds FWNMI support in qemu for powerKVM
>>>>>>>> guests by handling the ibm,nmi-register rtas call.
>>>>>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>>>>>> machine check notification address is saved and the
>>>>>>>> machine check interrupt vector 0x200 is patched to
>>>>>>>> issue a private hcall.
>>>>>>>>
>>>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>>>> ---
>>>>>>>> hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>>> include/hw/ppc/spapr.h |    8 ++++
>>>>>>>> 2 files changed, 98 insertions(+), 1 deletion(-)
>>>>>>>>
>>>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>>>> index 02ddbf9..1135d2b 100644
>>>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>>>>>     rtas_st(rets, 0, ret);
>>>>>>>> }
>>>>>>>>
>>>>>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>>>>>> +                                  sPAPREnvironment *spapr,
>>>>>>>> +                                  uint32_t token, uint32_t nargs,
>>>>>>>> +                                  target_ulong args,
>>>>>>>> +                                  uint32_t nret, target_ulong rets)
>>>>>>>> +{
>>>>>>>> +    int i;
>>>>>>>> +    uint32_t branch_inst = 0x48000002;
>>>>>>>> +    target_ulong guest_machine_check_addr;
>>>>>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>>>>>> +    /*
>>>>>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>>>>>> +     * to request qemu to build error log. QEMU builds the
>>>>>>>> +     * error log, copies to rtas-blob and returns the address.
>>>>>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>>>>>> +     * and srr1 which we restore and pass on the actual error
>>>>>>>> +     * log address to OS handled mcachine check notification
>>>>>>>> +     * routine
>>>>>>>> +     */
>>>>>>>> +    uint32_t trampoline[] = {
>>>>>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>>>>>> +        0x38600000,    /* li      r3,0   */
>>>>>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>>>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>>>>>> +        /* Issue H_CALL */
>>>>>>>> +        0x44000022,    /*  sc      1     */
>>>>>>>
>>>>>>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>>>>>>> clobber it?) and call our special hypercall.
>>>>>>>
>>>>>>> But what does all the cruft below here do?
>>>>>>
>>>>>> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
>>>>>> can clobber SPRG2 after hcall returns. I have included a comment in
>>>>>> patch 3/5 while building error log. I think better I add one here as well.
>>>>>>
>>>>>>>
>>>>>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>>>>>
>>>>>>> Apart from th fact that your order is wrong, this destroys the value of
>>>>>>> r3 that we saved above again.
>>>>>>
>>>>>> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
>>>>>> KVMPPC_H_REPORT_ERR hcall returns.
>>>>>>
>>>>>>>
>>>>>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>>>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>>>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>>>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>>>>>
>>>>>>> Can't we just set srr0 and srr1 directly?
>>>>>>
>>>>>> I checked for instructions in ISA which set srr0/1 directly given an
>>>>>> address, but could not find any such instructions.
>>>>>
>>>>> I mean from QEMU :).
>>>>
>>>> srr0 and srr1, which are properly set when 0x200 is invoked, are
>>>> clobbered when we return from KVMPPC_H_REPORT_ERR hcall. I think they
>>>> are modified before issuing rfid (I can see them getting clobbered from
>>>> QEMU monitor). However when we jump to OS registered machine check
>>>> routine srr0 and srr1 should reflect the value they had when 0x200 was
>>>> invoked.
>>>>
>>>> Hence srr0 and srr1 are saved in hcall and restored when we return from
>>>> hcall. Also we don't have enough scratch registers available to save
>>>> these before invoking hcall from 0x200.
>>>>
>>>> Or am I missing other ways to do this from QEMU?
>>>
>>> If you just do
>>>
>>> cpu_synchronize_state() and then change env->spr[SPRN_SRR0/1] inside
>>> your hypercall handler that should also change the value when you return
>>> from the hcall.
>>
>> I tried cpu_synchronize_state(), however, srr0 and srr1 are still clobbered.
>>
>> Just before I issue hcall from 0x200 I see the following values from
>> QEMU monitor:
>>
>> SRR0 d000000000f40264  SRR1 8000000000209033
>>
>> Inside hcall, I call cpu_synchronize_state(). As soon as I return from
>> hcall I see:
>>
>> SRR0 0000000000000214  SRR1 8000000000001001
>>
>> I see SRR0 is now set to nip in 0x200 and SRR1 to msr value. I think it
>> is reset during returning from hcall before executing rfid.
>>
>> So I think I still need to explicitly save/restore srr0 and srr1 across
>> hcall.
> 
> Please paste the diff that you did to enable use of cpu_synchronize_state().

@@ -668,20 +668,22 @@ static target_ulong h_rtas_update(PowerP
     return 0;
 }

 static target_ulong h_report_mc_err(PowerPCCPU *cpu, sPAPREnvironment
*spapr,
                            target_ulong opcode, target_ulong *args)
 {
     struct rtas_mc_log mc_log;
     CPUPPCState *env = &cpu->env;
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);

+    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
+
     /*
      * 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
      */
     mc_log.r3 = env->spr[SPR_SPRG2];

     /*
      * SRR0 and SRR1, containing nip and msr at the time of exception,
      * are clobbered when we return from this hcall. Hence they



> 
> Alex
> 
>>
>>>
>>>
>>> Alex
>>
>> -- 
>> Regards,
>> Aravinda
>>
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-09-04 13:49                 ` Aravinda Prasad
@ 2014-09-05  8:46                   ` Alexander Graf
  2014-09-05  8:52                     ` Aravinda Prasad
  0 siblings, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-09-05  8:46 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: aik, benh, qemu-ppc, qemu-devel, paulus



On 04.09.14 15:49, Aravinda Prasad wrote:
> 
> 
> On Thursday 04 September 2014 06:39 PM, Alexander Graf wrote:
>>
>>
>>> Am 04.09.2014 um 10:25 schrieb Aravinda Prasad <aravinda@linux.vnet.ibm.com>:
>>>
>>>
>>>
>>>> On Friday 29 August 2014 03:46 AM, Alexander Graf wrote:
>>>>
>>>>
>>>>> On 28.08.14 19:42, Aravinda Prasad wrote:
>>>>>
>>>>>
>>>>>> On Thursday 28 August 2014 02:07 PM, Alexander Graf wrote:
>>>>>>
>>>>>>
>>>>>>> On 28.08.14 08:38, Aravinda Prasad wrote:
>>>>>>>
>>>>>>>
>>>>>>>> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>>>>>>> This patch adds FWNMI support in qemu for powerKVM
>>>>>>>>> guests by handling the ibm,nmi-register rtas call.
>>>>>>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>>>>>>> machine check notification address is saved and the
>>>>>>>>> machine check interrupt vector 0x200 is patched to
>>>>>>>>> issue a private hcall.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>>>>> ---
>>>>>>>>> hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>>>> include/hw/ppc/spapr.h |    8 ++++
>>>>>>>>> 2 files changed, 98 insertions(+), 1 deletion(-)
>>>>>>>>>
>>>>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>>>>> index 02ddbf9..1135d2b 100644
>>>>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>>>>>>     rtas_st(rets, 0, ret);
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>>>>>>> +                                  sPAPREnvironment *spapr,
>>>>>>>>> +                                  uint32_t token, uint32_t nargs,
>>>>>>>>> +                                  target_ulong args,
>>>>>>>>> +                                  uint32_t nret, target_ulong rets)
>>>>>>>>> +{
>>>>>>>>> +    int i;
>>>>>>>>> +    uint32_t branch_inst = 0x48000002;
>>>>>>>>> +    target_ulong guest_machine_check_addr;
>>>>>>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>>>>>>> +    /*
>>>>>>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>>>>>>> +     * to request qemu to build error log. QEMU builds the
>>>>>>>>> +     * error log, copies to rtas-blob and returns the address.
>>>>>>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>>>>>>> +     * and srr1 which we restore and pass on the actual error
>>>>>>>>> +     * log address to OS handled mcachine check notification
>>>>>>>>> +     * routine
>>>>>>>>> +     */
>>>>>>>>> +    uint32_t trampoline[] = {
>>>>>>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>>>>>>> +        0x38600000,    /* li      r3,0   */
>>>>>>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>>>>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>>>>>>> +        /* Issue H_CALL */
>>>>>>>>> +        0x44000022,    /*  sc      1     */
>>>>>>>>
>>>>>>>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>>>>>>>> clobber it?) and call our special hypercall.
>>>>>>>>
>>>>>>>> But what does all the cruft below here do?
>>>>>>>
>>>>>>> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
>>>>>>> can clobber SPRG2 after hcall returns. I have included a comment in
>>>>>>> patch 3/5 while building error log. I think better I add one here as well.
>>>>>>>
>>>>>>>>
>>>>>>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>>>>>>
>>>>>>>> Apart from th fact that your order is wrong, this destroys the value of
>>>>>>>> r3 that we saved above again.
>>>>>>>
>>>>>>> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
>>>>>>> KVMPPC_H_REPORT_ERR hcall returns.
>>>>>>>
>>>>>>>>
>>>>>>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>>>>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>>>>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>>>>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>>>>>>
>>>>>>>> Can't we just set srr0 and srr1 directly?
>>>>>>>
>>>>>>> I checked for instructions in ISA which set srr0/1 directly given an
>>>>>>> address, but could not find any such instructions.
>>>>>>
>>>>>> I mean from QEMU :).
>>>>>
>>>>> srr0 and srr1, which are properly set when 0x200 is invoked, are
>>>>> clobbered when we return from KVMPPC_H_REPORT_ERR hcall. I think they
>>>>> are modified before issuing rfid (I can see them getting clobbered from
>>>>> QEMU monitor). However when we jump to OS registered machine check
>>>>> routine srr0 and srr1 should reflect the value they had when 0x200 was
>>>>> invoked.
>>>>>
>>>>> Hence srr0 and srr1 are saved in hcall and restored when we return from
>>>>> hcall. Also we don't have enough scratch registers available to save
>>>>> these before invoking hcall from 0x200.
>>>>>
>>>>> Or am I missing other ways to do this from QEMU?
>>>>
>>>> If you just do
>>>>
>>>> cpu_synchronize_state() and then change env->spr[SPRN_SRR0/1] inside
>>>> your hypercall handler that should also change the value when you return
>>>> from the hcall.
>>>
>>> I tried cpu_synchronize_state(), however, srr0 and srr1 are still clobbered.
>>>
>>> Just before I issue hcall from 0x200 I see the following values from
>>> QEMU monitor:
>>>
>>> SRR0 d000000000f40264  SRR1 8000000000209033
>>>
>>> Inside hcall, I call cpu_synchronize_state(). As soon as I return from
>>> hcall I see:
>>>
>>> SRR0 0000000000000214  SRR1 8000000000001001
>>>
>>> I see SRR0 is now set to nip in 0x200 and SRR1 to msr value. I think it
>>> is reset during returning from hcall before executing rfid.

Ah, because the hypercall is an interrupt itself. Heh ;). True.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-09-05  8:46                   ` Alexander Graf
@ 2014-09-05  8:52                     ` Aravinda Prasad
  0 siblings, 0 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-09-05  8:52 UTC (permalink / raw)
  To: Alexander Graf; +Cc: aik, benh, qemu-ppc, qemu-devel, paulus



On Friday 05 September 2014 02:16 PM, Alexander Graf wrote:
> 
> 
> On 04.09.14 15:49, Aravinda Prasad wrote:
>>
>>
>> On Thursday 04 September 2014 06:39 PM, Alexander Graf wrote:
>>>
>>>
>>>> Am 04.09.2014 um 10:25 schrieb Aravinda Prasad <aravinda@linux.vnet.ibm.com>:
>>>>
>>>>
>>>>
>>>>> On Friday 29 August 2014 03:46 AM, Alexander Graf wrote:
>>>>>
>>>>>
>>>>>> On 28.08.14 19:42, Aravinda Prasad wrote:
>>>>>>
>>>>>>
>>>>>>> On Thursday 28 August 2014 02:07 PM, Alexander Graf wrote:
>>>>>>>
>>>>>>>
>>>>>>>> On 28.08.14 08:38, Aravinda Prasad wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>> On Wednesday 27 August 2014 04:07 PM, Alexander Graf wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>>>>>>>> This patch adds FWNMI support in qemu for powerKVM
>>>>>>>>>> guests by handling the ibm,nmi-register rtas call.
>>>>>>>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>>>>>>>> machine check notification address is saved and the
>>>>>>>>>> machine check interrupt vector 0x200 is patched to
>>>>>>>>>> issue a private hcall.
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>>>>>>>> ---
>>>>>>>>>> hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>>>>> include/hw/ppc/spapr.h |    8 ++++
>>>>>>>>>> 2 files changed, 98 insertions(+), 1 deletion(-)
>>>>>>>>>>
>>>>>>>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>>>>>>>> index 02ddbf9..1135d2b 100644
>>>>>>>>>> --- a/hw/ppc/spapr_rtas.c
>>>>>>>>>> +++ b/hw/ppc/spapr_rtas.c
>>>>>>>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>>>>>>>     rtas_st(rets, 0, ret);
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>>>>>>>> +                                  sPAPREnvironment *spapr,
>>>>>>>>>> +                                  uint32_t token, uint32_t nargs,
>>>>>>>>>> +                                  target_ulong args,
>>>>>>>>>> +                                  uint32_t nret, target_ulong rets)
>>>>>>>>>> +{
>>>>>>>>>> +    int i;
>>>>>>>>>> +    uint32_t branch_inst = 0x48000002;
>>>>>>>>>> +    target_ulong guest_machine_check_addr;
>>>>>>>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>>>>>>>> +    /*
>>>>>>>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>>>>>>>> +     * to request qemu to build error log. QEMU builds the
>>>>>>>>>> +     * error log, copies to rtas-blob and returns the address.
>>>>>>>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>>>>>>>> +     * and srr1 which we restore and pass on the actual error
>>>>>>>>>> +     * log address to OS handled mcachine check notification
>>>>>>>>>> +     * routine
>>>>>>>>>> +     */
>>>>>>>>>> +    uint32_t trampoline[] = {
>>>>>>>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>>>>>>>> +        0x38600000,    /* li      r3,0   */
>>>>>>>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>>>>>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>>>>>>>> +        /* Issue H_CALL */
>>>>>>>>>> +        0x44000022,    /*  sc      1     */
>>>>>>>>>
>>>>>>>>> So up to here we're saving r3 in SPRG2 (how do we know that we can
>>>>>>>>> clobber it?) and call our special hypercall.
>>>>>>>>>
>>>>>>>>> But what does all the cruft below here do?
>>>>>>>>
>>>>>>>> The saved r3 in SPRG2 is consumed in KVMPPC_H_REPORT_ERR hcall, hence we
>>>>>>>> can clobber SPRG2 after hcall returns. I have included a comment in
>>>>>>>> patch 3/5 while building error log. I think better I add one here as well.
>>>>>>>>
>>>>>>>>>
>>>>>>>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>>>>>>>
>>>>>>>>> Apart from th fact that your order is wrong, this destroys the value of
>>>>>>>>> r3 that we saved above again.
>>>>>>>>
>>>>>>>> SPRG2 is saved inside hcall and hence we don't need SPRG2 further after
>>>>>>>> KVMPPC_H_REPORT_ERR hcall returns.
>>>>>>>>
>>>>>>>>>
>>>>>>>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>>>>>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>>>>>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>>>>>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>>>>>>>
>>>>>>>>> Can't we just set srr0 and srr1 directly?
>>>>>>>>
>>>>>>>> I checked for instructions in ISA which set srr0/1 directly given an
>>>>>>>> address, but could not find any such instructions.
>>>>>>>
>>>>>>> I mean from QEMU :).
>>>>>>
>>>>>> srr0 and srr1, which are properly set when 0x200 is invoked, are
>>>>>> clobbered when we return from KVMPPC_H_REPORT_ERR hcall. I think they
>>>>>> are modified before issuing rfid (I can see them getting clobbered from
>>>>>> QEMU monitor). However when we jump to OS registered machine check
>>>>>> routine srr0 and srr1 should reflect the value they had when 0x200 was
>>>>>> invoked.
>>>>>>
>>>>>> Hence srr0 and srr1 are saved in hcall and restored when we return from
>>>>>> hcall. Also we don't have enough scratch registers available to save
>>>>>> these before invoking hcall from 0x200.
>>>>>>
>>>>>> Or am I missing other ways to do this from QEMU?
>>>>>
>>>>> If you just do
>>>>>
>>>>> cpu_synchronize_state() and then change env->spr[SPRN_SRR0/1] inside
>>>>> your hypercall handler that should also change the value when you return
>>>>> from the hcall.
>>>>
>>>> I tried cpu_synchronize_state(), however, srr0 and srr1 are still clobbered.
>>>>
>>>> Just before I issue hcall from 0x200 I see the following values from
>>>> QEMU monitor:
>>>>
>>>> SRR0 d000000000f40264  SRR1 8000000000209033
>>>>
>>>> Inside hcall, I call cpu_synchronize_state(). As soon as I return from
>>>> hcall I see:
>>>>
>>>> SRR0 0000000000000214  SRR1 8000000000001001
>>>>
>>>> I see SRR0 is now set to nip in 0x200 and SRR1 to msr value. I think it
>>>> is reset during returning from hcall before executing rfid.
> 
> Ah, because the hypercall is an interrupt itself. Heh ;). True.

Yes. However, as you mentioned, we still need cpu_synchronize_state() to
avoid stale value when we read env->spr[SPR_SPRG2]

Aravinda.

> 
> 
> Alex
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-08-25 13:45 ` [Qemu-devel] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call Aravinda Prasad
  2014-08-26  6:02   ` David Gibson
  2014-08-27 10:37   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
@ 2014-09-07 20:47   ` Alexander Graf
  2014-09-26  3:58     ` Alexey Kardashevskiy
  2014-10-06  6:32     ` Aravinda Prasad
  2 siblings, 2 replies; 73+ messages in thread
From: Alexander Graf @ 2014-09-07 20:47 UTC (permalink / raw)
  To: Aravinda Prasad, aik, qemu-ppc, qemu-devel; +Cc: benh, paulus



On 25.08.14 15:45, Aravinda Prasad wrote:
> This patch adds FWNMI support in qemu for powerKVM
> guests by handling the ibm,nmi-register rtas call.
> Whenever OS issues ibm,nmi-register RTAS call, the
> machine check notification address is saved and the
> machine check interrupt vector 0x200 is patched to
> issue a private hcall.
> 
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> ---
>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr.h |    8 ++++
>  2 files changed, 98 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index 02ddbf9..1135d2b 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>      rtas_st(rets, 0, ret);
>  }
>  
> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
> +                                  sPAPREnvironment *spapr,
> +                                  uint32_t token, uint32_t nargs,
> +                                  target_ulong args,
> +                                  uint32_t nret, target_ulong rets)
> +{
> +    int i;
> +    uint32_t branch_inst = 0x48000002;
> +    target_ulong guest_machine_check_addr;
> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
> +    /*
> +     * Trampoline saves r3 in sprg2 and issues private hcall
> +     * to request qemu to build error log. QEMU builds the
> +     * error log, copies to rtas-blob and returns the address.
> +     * The initial 16 bytes in rtas-blob consists of saved srr0
> +     * and srr1 which we restore and pass on the actual error
> +     * log address to OS handled mcachine check notification
> +     * routine
> +     */
> +    uint32_t trampoline[] = {
> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
> +        0x38600000,    /* li      r3,0   */
> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
> +        0x6063f004,    /* ori     r3,r3,f004  */
> +        /* Issue H_CALL */
> +        0x44000022,    /*  sc      1     */
> +        0x7c9243a6,    /* mtspr r4 sprg2 */
> +        0xe8830000,    /* ld r4, 0(r3) */
> +        0x7c9a03a6,    /* mtspr r4, srr0 */
> +        0xe8830008,    /* ld r4, 8(r3) */
> +        0x7c9b03a6,    /* mtspr r4, srr1 */
> +        0x38630010,    /* addi r3,r3,16 */
> +        0x7c9242a6,    /* mfspr r4 sprg2 */
> +        0x48000002,    /* Branch to address registered
> +                        * by OS. The branch address is
> +                        * patched below */
> +        0x48000000,    /* b . */

So how about we just completely change the layout of the RTAS blob?

Imagine something like the following (completely untested):

----

/**** index table ****/
.long rtas_entry
.long nmi_register
.long nmi_register_final_branch
.long nmi_data

/**** RTAS handling code ****/
.align 1024
rtas_entry:
	...
nmi_register:
	...
nmi_register_final_branch:
	ba .

/**** RTAS data regions ****/
.align 4096
nmi_data:
.long 0
.align 4096

----

With this we should be able to have a nice hybrid between easily tunable
asm code and an easy to load and handle blob.


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-09-07 20:47   ` Alexander Graf
@ 2014-09-26  3:58     ` Alexey Kardashevskiy
  2014-10-06  6:32     ` Aravinda Prasad
  1 sibling, 0 replies; 73+ messages in thread
From: Alexey Kardashevskiy @ 2014-09-26  3:58 UTC (permalink / raw)
  To: Alexander Graf, Aravinda Prasad, qemu-ppc, qemu-devel; +Cc: benh, paulus

On 09/08/2014 06:47 AM, Alexander Graf wrote:
> 
> 
> On 25.08.14 15:45, Aravinda Prasad wrote:
>> This patch adds FWNMI support in qemu for powerKVM
>> guests by handling the ibm,nmi-register rtas call.
>> Whenever OS issues ibm,nmi-register RTAS call, the
>> machine check notification address is saved and the
>> machine check interrupt vector 0x200 is patched to
>> issue a private hcall.
>>
>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>> ---
>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/hw/ppc/spapr.h |    8 ++++
>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>> index 02ddbf9..1135d2b 100644
>> --- a/hw/ppc/spapr_rtas.c
>> +++ b/hw/ppc/spapr_rtas.c
>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>      rtas_st(rets, 0, ret);
>>  }
>>  
>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>> +                                  sPAPREnvironment *spapr,
>> +                                  uint32_t token, uint32_t nargs,
>> +                                  target_ulong args,
>> +                                  uint32_t nret, target_ulong rets)
>> +{
>> +    int i;
>> +    uint32_t branch_inst = 0x48000002;
>> +    target_ulong guest_machine_check_addr;
>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>> +    /*
>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>> +     * to request qemu to build error log. QEMU builds the
>> +     * error log, copies to rtas-blob and returns the address.
>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>> +     * and srr1 which we restore and pass on the actual error
>> +     * log address to OS handled mcachine check notification
>> +     * routine
>> +     */
>> +    uint32_t trampoline[] = {
>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>> +        0x38600000,    /* li      r3,0   */
>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>> +        0x6063f004,    /* ori     r3,r3,f004  */
>> +        /* Issue H_CALL */
>> +        0x44000022,    /*  sc      1     */
>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>> +        0xe8830000,    /* ld r4, 0(r3) */
>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>> +        0xe8830008,    /* ld r4, 8(r3) */
>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>> +        0x38630010,    /* addi r3,r3,16 */
>> +        0x7c9242a6,    /* mfspr r4 sprg2 */
>> +        0x48000002,    /* Branch to address registered
>> +                        * by OS. The branch address is
>> +                        * patched below */
>> +        0x48000000,    /* b . */
> 
> So how about we just completely change the layout of the RTAS blob?


Aravinda, ping?



> 
> Imagine something like the following (completely untested):
> 
> ----
> 
> /**** index table ****/
> .long rtas_entry
> .long nmi_register
> .long nmi_register_final_branch
> .long nmi_data
> 
> /**** RTAS handling code ****/
> .align 1024
> rtas_entry:
> 	...
> nmi_register:
> 	...
> nmi_register_final_branch:
> 	ba .
> 
> /**** RTAS data regions ****/
> .align 4096
> nmi_data:
> .long 0
> .align 4096
> 
> ----
> 
> With this we should be able to have a nice hybrid between easily tunable
> asm code and an easy to load and handle blob.
> 
> 
> Alex
> 


-- 
Alexey Kardashevskiy
IBM OzLabs, LTC Team

e-mail: aik@au1.ibm.com
notes: Alexey Kardashevskiy/Australia/IBM

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-09-07 20:47   ` Alexander Graf
  2014-09-26  3:58     ` Alexey Kardashevskiy
@ 2014-10-06  6:32     ` Aravinda Prasad
  2014-10-06  9:40       ` Alexander Graf
  1 sibling, 1 reply; 73+ messages in thread
From: Aravinda Prasad @ 2014-10-06  6:32 UTC (permalink / raw)
  To: Alexander Graf; +Cc: benh, aik, qemu-devel, qemu-ppc, paulus



On Monday 08 September 2014 02:17 AM, Alexander Graf wrote:
> 
> 
> On 25.08.14 15:45, Aravinda Prasad wrote:
>> This patch adds FWNMI support in qemu for powerKVM
>> guests by handling the ibm,nmi-register rtas call.
>> Whenever OS issues ibm,nmi-register RTAS call, the
>> machine check notification address is saved and the
>> machine check interrupt vector 0x200 is patched to
>> issue a private hcall.
>>
>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>> ---
>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/hw/ppc/spapr.h |    8 ++++
>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>> index 02ddbf9..1135d2b 100644
>> --- a/hw/ppc/spapr_rtas.c
>> +++ b/hw/ppc/spapr_rtas.c
>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>      rtas_st(rets, 0, ret);
>>  }
>>  
>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>> +                                  sPAPREnvironment *spapr,
>> +                                  uint32_t token, uint32_t nargs,
>> +                                  target_ulong args,
>> +                                  uint32_t nret, target_ulong rets)
>> +{
>> +    int i;
>> +    uint32_t branch_inst = 0x48000002;
>> +    target_ulong guest_machine_check_addr;
>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>> +    /*
>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>> +     * to request qemu to build error log. QEMU builds the
>> +     * error log, copies to rtas-blob and returns the address.
>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>> +     * and srr1 which we restore and pass on the actual error
>> +     * log address to OS handled mcachine check notification
>> +     * routine
>> +     */
>> +    uint32_t trampoline[] = {
>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>> +        0x38600000,    /* li      r3,0   */
>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>> +        0x6063f004,    /* ori     r3,r3,f004  */
>> +        /* Issue H_CALL */
>> +        0x44000022,    /*  sc      1     */
>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>> +        0xe8830000,    /* ld r4, 0(r3) */
>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>> +        0xe8830008,    /* ld r4, 8(r3) */
>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>> +        0x38630010,    /* addi r3,r3,16 */
>> +        0x7c9242a6,    /* mfspr r4 sprg2 */
>> +        0x48000002,    /* Branch to address registered
>> +                        * by OS. The branch address is
>> +                        * patched below */
>> +        0x48000000,    /* b . */
> 
> So how about we just completely change the layout of the RTAS blob?
> 
> Imagine something like the following (completely untested):
> 
> ----
> 
> /**** index table ****/
> .long rtas_entry
> .long nmi_register
> .long nmi_register_final_branch
> .long nmi_data
> 
> /**** RTAS handling code ****/
> .align 1024
> rtas_entry:
> 	...
> nmi_register:
> 	...
> nmi_register_final_branch:
> 	ba .
> 
> /**** RTAS data regions ****/
> .align 4096
> nmi_data:
> .long 0
> .align 4096
> 
> ----
> 
> With this we should be able to have a nice hybrid between easily tunable
> asm code and an easy to load and handle blob.

Sorry, I was out of office hence could not respond.

Yes, even I prefer something like this.

BTB, did you intend to have this in spapr-rtas.S? The spapr-rtas.S is
compiled into a binary and is read into spapr->rtas_blob. If we want to
have rtas-blob layout something similar to above then we may need to
link the object file of spapr-rtas.S to QEMU so that the symbols in
"index table" and other places could be resolved inside QEMU.

If this is fine I will include it in v3.

Regards,
Aravinda

> 
> 
> Alex
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-10-06  6:32     ` Aravinda Prasad
@ 2014-10-06  9:40       ` Alexander Graf
  2014-10-06 11:01         ` Aravinda Prasad
  0 siblings, 1 reply; 73+ messages in thread
From: Alexander Graf @ 2014-10-06  9:40 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: benh, aik, qemu-devel, qemu-ppc, paulus



On 06.10.14 08:32, Aravinda Prasad wrote:
> 
> 
> On Monday 08 September 2014 02:17 AM, Alexander Graf wrote:
>>
>>
>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>> This patch adds FWNMI support in qemu for powerKVM
>>> guests by handling the ibm,nmi-register rtas call.
>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>> machine check notification address is saved and the
>>> machine check interrupt vector 0x200 is patched to
>>> issue a private hcall.
>>>
>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>> ---
>>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>  include/hw/ppc/spapr.h |    8 ++++
>>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>> index 02ddbf9..1135d2b 100644
>>> --- a/hw/ppc/spapr_rtas.c
>>> +++ b/hw/ppc/spapr_rtas.c
>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>      rtas_st(rets, 0, ret);
>>>  }
>>>  
>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>> +                                  sPAPREnvironment *spapr,
>>> +                                  uint32_t token, uint32_t nargs,
>>> +                                  target_ulong args,
>>> +                                  uint32_t nret, target_ulong rets)
>>> +{
>>> +    int i;
>>> +    uint32_t branch_inst = 0x48000002;
>>> +    target_ulong guest_machine_check_addr;
>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>> +    /*
>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>> +     * to request qemu to build error log. QEMU builds the
>>> +     * error log, copies to rtas-blob and returns the address.
>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>> +     * and srr1 which we restore and pass on the actual error
>>> +     * log address to OS handled mcachine check notification
>>> +     * routine
>>> +     */
>>> +    uint32_t trampoline[] = {
>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>> +        0x38600000,    /* li      r3,0   */
>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>> +        /* Issue H_CALL */
>>> +        0x44000022,    /*  sc      1     */
>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>> +        0x38630010,    /* addi r3,r3,16 */
>>> +        0x7c9242a6,    /* mfspr r4 sprg2 */
>>> +        0x48000002,    /* Branch to address registered
>>> +                        * by OS. The branch address is
>>> +                        * patched below */
>>> +        0x48000000,    /* b . */
>>
>> So how about we just completely change the layout of the RTAS blob?
>>
>> Imagine something like the following (completely untested):
>>
>> ----
>>
>> /**** index table ****/
>> .long rtas_entry
>> .long nmi_register
>> .long nmi_register_final_branch
>> .long nmi_data
>>
>> /**** RTAS handling code ****/
>> .align 1024
>> rtas_entry:
>> 	...
>> nmi_register:
>> 	...
>> nmi_register_final_branch:
>> 	ba .
>>
>> /**** RTAS data regions ****/
>> .align 4096
>> nmi_data:
>> .long 0
>> .align 4096
>>
>> ----
>>
>> With this we should be able to have a nice hybrid between easily tunable
>> asm code and an easy to load and handle blob.
> 
> Sorry, I was out of office hence could not respond.
> 
> Yes, even I prefer something like this.
> 
> BTB, did you intend to have this in spapr-rtas.S? The spapr-rtas.S is
> compiled into a binary and is read into spapr->rtas_blob. If we want to
> have rtas-blob layout something similar to above then we may need to
> link the object file of spapr-rtas.S to QEMU so that the symbols in
> "index table" and other places could be resolved inside QEMU.
> 
> If this is fine I will include it in v3.

You can't link against the object file with QEMU, since QEMU could be
executed on an x86 machine which can't compile the rtas blob.

In my proposal above, you would maintain a table of entry points at well
known locations in the binary blob (starting from 0 is probably the
easiest).


Alex

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call
  2014-10-06  9:40       ` Alexander Graf
@ 2014-10-06 11:01         ` Aravinda Prasad
  0 siblings, 0 replies; 73+ messages in thread
From: Aravinda Prasad @ 2014-10-06 11:01 UTC (permalink / raw)
  To: Alexander Graf; +Cc: benh, aik, qemu-devel, qemu-ppc, paulus



On Monday 06 October 2014 03:10 PM, Alexander Graf wrote:
> 
> 
> On 06.10.14 08:32, Aravinda Prasad wrote:
>>
>>
>> On Monday 08 September 2014 02:17 AM, Alexander Graf wrote:
>>>
>>>
>>> On 25.08.14 15:45, Aravinda Prasad wrote:
>>>> This patch adds FWNMI support in qemu for powerKVM
>>>> guests by handling the ibm,nmi-register rtas call.
>>>> Whenever OS issues ibm,nmi-register RTAS call, the
>>>> machine check notification address is saved and the
>>>> machine check interrupt vector 0x200 is patched to
>>>> issue a private hcall.
>>>>
>>>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>>>> ---
>>>>  hw/ppc/spapr_rtas.c    |   91 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>  include/hw/ppc/spapr.h |    8 ++++
>>>>  2 files changed, 98 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>>>> index 02ddbf9..1135d2b 100644
>>>> --- a/hw/ppc/spapr_rtas.c
>>>> +++ b/hw/ppc/spapr_rtas.c
>>>> @@ -277,6 +277,91 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
>>>>      rtas_st(rets, 0, ret);
>>>>  }
>>>>  
>>>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>>> +                                  sPAPREnvironment *spapr,
>>>> +                                  uint32_t token, uint32_t nargs,
>>>> +                                  target_ulong args,
>>>> +                                  uint32_t nret, target_ulong rets)
>>>> +{
>>>> +    int i;
>>>> +    uint32_t branch_inst = 0x48000002;
>>>> +    target_ulong guest_machine_check_addr;
>>>> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>>>> +    /*
>>>> +     * Trampoline saves r3 in sprg2 and issues private hcall
>>>> +     * to request qemu to build error log. QEMU builds the
>>>> +     * error log, copies to rtas-blob and returns the address.
>>>> +     * The initial 16 bytes in rtas-blob consists of saved srr0
>>>> +     * and srr1 which we restore and pass on the actual error
>>>> +     * log address to OS handled mcachine check notification
>>>> +     * routine
>>>> +     */
>>>> +    uint32_t trampoline[] = {
>>>> +        0x7c7243a6,    /* mtspr   SPRN_SPRG2,r3 */
>>>> +        0x38600000,    /* li      r3,0   */
>>>> +        /* 0xf004 is the KVMPPC_H_REPORT_ERR private HCALL */
>>>> +        0x6063f004,    /* ori     r3,r3,f004  */
>>>> +        /* Issue H_CALL */
>>>> +        0x44000022,    /*  sc      1     */
>>>> +        0x7c9243a6,    /* mtspr r4 sprg2 */
>>>> +        0xe8830000,    /* ld r4, 0(r3) */
>>>> +        0x7c9a03a6,    /* mtspr r4, srr0 */
>>>> +        0xe8830008,    /* ld r4, 8(r3) */
>>>> +        0x7c9b03a6,    /* mtspr r4, srr1 */
>>>> +        0x38630010,    /* addi r3,r3,16 */
>>>> +        0x7c9242a6,    /* mfspr r4 sprg2 */
>>>> +        0x48000002,    /* Branch to address registered
>>>> +                        * by OS. The branch address is
>>>> +                        * patched below */
>>>> +        0x48000000,    /* b . */
>>>
>>> So how about we just completely change the layout of the RTAS blob?
>>>
>>> Imagine something like the following (completely untested):
>>>
>>> ----
>>>
>>> /**** index table ****/
>>> .long rtas_entry
>>> .long nmi_register
>>> .long nmi_register_final_branch
>>> .long nmi_data
>>>
>>> /**** RTAS handling code ****/
>>> .align 1024
>>> rtas_entry:
>>> 	...
>>> nmi_register:
>>> 	...
>>> nmi_register_final_branch:
>>> 	ba .
>>>
>>> /**** RTAS data regions ****/
>>> .align 4096
>>> nmi_data:
>>> .long 0
>>> .align 4096
>>>
>>> ----
>>>
>>> With this we should be able to have a nice hybrid between easily tunable
>>> asm code and an easy to load and handle blob.
>>
>> Sorry, I was out of office hence could not respond.
>>
>> Yes, even I prefer something like this.
>>
>> BTB, did you intend to have this in spapr-rtas.S? The spapr-rtas.S is
>> compiled into a binary and is read into spapr->rtas_blob. If we want to
>> have rtas-blob layout something similar to above then we may need to
>> link the object file of spapr-rtas.S to QEMU so that the symbols in
>> "index table" and other places could be resolved inside QEMU.
>>
>> If this is fine I will include it in v3.
> 
> You can't link against the object file with QEMU, since QEMU could be
> executed on an x86 machine which can't compile the rtas blob.
> 
> In my proposal above, you would maintain a table of entry points at well
> known locations in the binary blob (starting from 0 is probably the
> easiest).

ok. I will include it in v3 of my patch.

> 
> 
> Alex
> 

-- 
Regards,
Aravinda

^ permalink raw reply	[flat|nested] 73+ messages in thread

end of thread, other threads:[~2014-10-06 11:01 UTC | newest]

Thread overview: 73+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-25 13:45 [Qemu-devel] [PATCH 0/5] target-ppc: Add FWNMI support in QEMU for powerKVM guests Aravinda Prasad
2014-08-25 13:45 ` [Qemu-devel] [PATCH 1/5] target-ppc: Extend rtas-blob Aravinda Prasad
2014-08-26  5:38   ` David Gibson
2014-08-26  6:34     ` Aravinda Prasad
2014-08-26  7:24       ` David Gibson
2014-08-28 10:40   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
2014-08-28 18:20     ` Aravinda Prasad
2014-08-28 22:18       ` Alexander Graf
2014-08-28 22:25         ` Benjamin Herrenschmidt
2014-08-29  0:40           ` Alexander Graf
2014-08-29  1:06             ` Benjamin Herrenschmidt
2014-08-29  1:33               ` Alexander Graf
2014-08-29  2:42                 ` Benjamin Herrenschmidt
2014-08-29  3:46                 ` David Gibson
2014-08-29  3:47         ` David Gibson
2014-09-01  7:46   ` [Qemu-devel] " Alexey Kardashevskiy
2014-09-01 11:23     ` Aravinda Prasad
2014-09-02  4:09       ` Alexey Kardashevskiy
2014-09-02  5:25         ` Aravinda Prasad
2014-09-02  5:49           ` Alexey Kardashevskiy
2014-09-02  5:56             ` Aravinda Prasad
2014-09-02  6:34               ` Alexey Kardashevskiy
2014-09-02  7:07                 ` Aravinda Prasad
2014-09-02  8:40                   ` Alexey Kardashevskiy
2014-09-02  9:30                     ` Aravinda Prasad
2014-09-02 13:17                       ` Alexey Kardashevskiy
2014-08-25 13:45 ` [Qemu-devel] [PATCH 2/5] target-ppc: Register and handle HCALL to receive updated RTAS region Aravinda Prasad
2014-08-26  5:39   ` David Gibson
2014-08-26  6:15     ` Benjamin Herrenschmidt
2014-08-26  7:24       ` David Gibson
2014-08-26 20:05         ` Benjamin Herrenschmidt
2014-08-25 13:45 ` [Qemu-devel] [PATCH 3/5] target-ppc: Build error log Aravinda Prasad
2014-08-26  5:47   ` David Gibson
2014-08-26  6:40     ` Aravinda Prasad
2014-08-27  9:50   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
2014-08-28  6:12     ` Aravinda Prasad
2014-08-28  8:36       ` Alexander Graf
2014-08-28 10:21         ` Benjamin Herrenschmidt
2014-08-28 10:29           ` Alexander Graf
2014-08-28 10:33             ` Benjamin Herrenschmidt
2014-08-28 10:34               ` Benjamin Herrenschmidt
2014-08-28 17:17               ` Aravinda Prasad
2014-08-28 20:07                 ` Benjamin Herrenschmidt
2014-08-30  8:06                   ` Aravinda Prasad
2014-08-25 13:45 ` [Qemu-devel] [PATCH 4/5] target-ppc: Handle ibm, nmi-register RTAS call Aravinda Prasad
2014-08-26  6:02   ` David Gibson
2014-08-26  6:57     ` Aravinda Prasad
2014-08-27 10:37   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
2014-08-28  6:38     ` Aravinda Prasad
2014-08-28  8:37       ` Alexander Graf
2014-08-28 13:06         ` Tom Musta
2014-08-28 13:11           ` Alexander Graf
2014-08-28 17:42         ` Aravinda Prasad
2014-08-28 22:16           ` Alexander Graf
2014-08-30  8:08             ` Aravinda Prasad
2014-09-04  8:25             ` Aravinda Prasad
2014-09-04 13:09               ` Alexander Graf
2014-09-04 13:49                 ` Aravinda Prasad
2014-09-05  8:46                   ` Alexander Graf
2014-09-05  8:52                     ` Aravinda Prasad
2014-09-07 20:47   ` Alexander Graf
2014-09-26  3:58     ` Alexey Kardashevskiy
2014-10-06  6:32     ` Aravinda Prasad
2014-10-06  9:40       ` Alexander Graf
2014-10-06 11:01         ` Aravinda Prasad
2014-08-25 13:45 ` [Qemu-devel] [PATCH 5/5] target-ppc: Handle cases when multi-processors get machine-check Aravinda Prasad
2014-08-26  6:04   ` David Gibson
2014-08-26  7:04     ` Aravinda Prasad
2014-08-27 10:40   ` [Qemu-devel] [Qemu-ppc] " Alexander Graf
2014-08-28  6:56     ` Aravinda Prasad
2014-08-28  8:39       ` Alexander Graf
2014-08-28  8:42       ` Alexander Graf
2014-08-28 17:45         ` Aravinda Prasad

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.