qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PULL 00/18] ppc-for-5.1 queue 20200507
@ 2020-05-07  5:02 David Gibson
  2020-05-07  5:02 ` [PULL 01/18] target/ppc: Improve syscall exception logging David Gibson
                   ` (19 more replies)
  0 siblings, 20 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, David Gibson

The following changes since commit 570a9214827e3d42f7173c4d4c9f045b99834cf0:

  Merge remote-tracking branch 'remotes/alistair/tags/pull-reg-to-apply-20200505' into staging (2020-05-06 15:38:02 +0100)

are available in the Git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-5.1-20200507

for you to fetch changes up to c4f6a4a3dd5f2aa15329b8158de25f50b5ba3252:

  target-ppc: fix rlwimi, rlwinm, rlwnm for Clang-9 (2020-05-07 11:10:50 +1000)

----------------------------------------------------------------
ppc patch queue for 2020-04-07

First pull request for qemu-5.1.  This includes:
 * Removal of all remaining cases where we had CAS triggered reboots
 * A number of improvements to NMI injection
 * Support for partition scoped radix translation in softmmu
 * Some fixes for NVDIMM handling
 * A handful of other minor fixes

----------------------------------------------------------------
Alexey Kardashevskiy (1):
      spapr/cas: Separate CAS handling from rebuilding the FDT

Cédric Le Goater (6):
      target/ppc: Introduce a relocation bool in ppc_radix64_handle_mmu_fault()
      target/ppc: Assert if HV mode is set when running under a pseries machine
      target/ppc: Introduce ppc_radix64_xlate() for Radix tree translation
      target/ppc: Extend ppc_radix64_check_prot() with a 'partition_scoped' bool
      target/ppc: Rework ppc_radix64_walk_tree() for partition-scoped translation
      target/ppc: Add support for Radix partition-scoped translation

Daniel Henrique Barboza (1):
      spapr_nvdimm.c: make 'label-size' mandatory

Daniele Buono (1):
      target-ppc: fix rlwimi, rlwinm, rlwnm for Clang-9

David Gibson (2):
      spapr: Don't allow unplug of NVLink2 devices
      spapr_nvdimm: Tweak error messages

Greg Kurz (3):
      spapr: Don't check capabilities removed between CAS calls
      spapr: Simplify selection of radix/hash during CAS
      spapr: Drop CAS reboot flag

Nicholas Piggin (3):
      target/ppc: Improve syscall exception logging
      ppc/spapr: tweak change system reset helper
      ppc/pnv: Add support for NMI interface

Suraj Jitindar Singh (1):
      target/ppc: Enforce that the root page directory size must be at least 5

 hw/ppc/pnv.c             |  29 +++
 hw/ppc/spapr.c           |  29 ++-
 hw/ppc/spapr_hcall.c     | 108 ++++++-----
 hw/ppc/spapr_nvdimm.c    |  10 +-
 hw/ppc/spapr_pci.c       |   4 +
 include/hw/ppc/spapr.h   |   8 +-
 target/ppc/cpu.h         |   5 +-
 target/ppc/excp_helper.c |  38 +++-
 target/ppc/mmu-radix64.c | 468 ++++++++++++++++++++++++++++++++++-------------
 target/ppc/translate.c   |  24 ++-
 10 files changed, 506 insertions(+), 217 deletions(-)


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

* [PULL 01/18] target/ppc: Improve syscall exception logging
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 02/18] spapr: Don't check capabilities removed between CAS calls David Gibson
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, David Gibson

From: Nicholas Piggin <npiggin@gmail.com>

system calls (at least in Linux) use registers r3-r8 for inputs, so
include those registers in the dump.

This also adds a mode for PAPR hcalls, which have a different calling
convention.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Message-Id: <20200317054918.199161-1-npiggin@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/excp_helper.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 08bc885ca6..81ee19ebae 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -57,12 +57,29 @@ static void ppc_hw_interrupt(CPUPPCState *env)
 #else /* defined(CONFIG_USER_ONLY) */
 static inline void dump_syscall(CPUPPCState *env)
 {
-    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
-                  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
+    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
+                  " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
+                  " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
                   " nip=" TARGET_FMT_lx "\n",
                   ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
                   ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
-                  ppc_dump_gpr(env, 6), env->nip);
+                  ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
+                  ppc_dump_gpr(env, 8), env->nip);
+}
+
+static inline void dump_hcall(CPUPPCState *env)
+{
+    qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
+		  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
+		  " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64
+		  " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64
+                  " nip=" TARGET_FMT_lx "\n",
+                  ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4),
+		  ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6),
+		  ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
+		  ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
+		  ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
+		  env->nip);
 }
 
 static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
@@ -379,9 +396,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         break;
     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
-        dump_syscall(env);
         lev = env->error_code;
 
+        if ((lev == 1) && cpu->vhyp) {
+            dump_hcall(env);
+        } else {
+            dump_syscall(env);
+        }
+
         /*
          * We need to correct the NIP which in this case is supposed
          * to point to the next instruction
-- 
2.26.2



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

* [PULL 02/18] spapr: Don't check capabilities removed between CAS calls
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
  2020-05-07  5:02 ` [PULL 01/18] target/ppc: Improve syscall exception logging David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 03/18] ppc/spapr: tweak change system reset helper David Gibson
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

We currently check if some capability in OV5 was removed by the guest
since the previous CAS, and we trigger a CAS reboot in that case. This
was required because it could call for a device-tree property or node
removal, that we didn't support until recently (see commit 6787d27b04a7
"spapr: add option vector handling in CAS-generated resets" for details).

Now that we render a full FDT at CAS and that SLOF is able to handle
node removal, we don't need to do a CAS reset in this case anymore.
Also, this check can only return true if the guest has already called
CAS since the last full system reset (otherwise spapr->ov5_cas is
empty). Linux doesn't do that so this can be considered as dead code
for the vast majority of existing setups.

Drop the check. Since the only use of the ov5_cas_old variable is
precisely the check itself, drop the variable as well.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <158514993021.478799.10928618293640651819.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_hcall.c | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 0d50fc9117..e8ee447537 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1676,7 +1676,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     target_ulong fdt_bufsize = args[2];
     target_ulong ov_table;
     uint32_t cas_pvr;
-    SpaprOptionVector *ov1_guest, *ov5_guest, *ov5_cas_old;
+    SpaprOptionVector *ov1_guest, *ov5_guest;
     bool guest_radix;
     Error *local_err = NULL;
     bool raw_mode_supported = false;
@@ -1782,22 +1782,10 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
      * by LoPAPR 1.1, 14.5.4.8, which QEMU doesn't implement, we don't need
      * to worry about this for now.
      */
-    ov5_cas_old = spapr_ovec_clone(spapr->ov5_cas);
-
-    /* also clear the radix/hash bit from the current ov5_cas bits to
-     * be in sync with the newly ov5 bits. Else the radix bit will be
-     * seen as being removed and this will generate a reset loop
-     */
-    spapr_ovec_clear(ov5_cas_old, OV5_MMU_RADIX_300);
 
     /* full range of negotiated ov5 capabilities */
     spapr_ovec_intersect(spapr->ov5_cas, spapr->ov5, ov5_guest);
     spapr_ovec_cleanup(ov5_guest);
-    /* capabilities that have been added since CAS-generated guest reset.
-     * if capabilities have since been removed, generate another reset
-     */
-    spapr->cas_reboot = !spapr_ovec_subset(ov5_cas_old, spapr->ov5_cas);
-    spapr_ovec_cleanup(ov5_cas_old);
     /* Now that processing is finished, set the radix/hash bit for the
      * guest if it requested a valid mode; otherwise terminate the boot. */
     if (guest_radix) {
-- 
2.26.2



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

* [PULL 03/18] ppc/spapr: tweak change system reset helper
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
  2020-05-07  5:02 ` [PULL 01/18] target/ppc: Improve syscall exception logging David Gibson
  2020-05-07  5:02 ` [PULL 02/18] spapr: Don't check capabilities removed between CAS calls David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 04/18] ppc/pnv: Add support for NMI interface David Gibson
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, David Gibson

From: Nicholas Piggin <npiggin@gmail.com>

Rather than have the helper take an optional vector address
override, instead have its caller modify env->nip itself.
This is more consistent when adding pnv nmi support, and also
with mce injection added later.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Message-Id: <20200325144147.221875-2-npiggin@gmail.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c           | 9 ++++++---
 target/ppc/cpu.h         | 2 +-
 target/ppc/excp_helper.c | 5 +----
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9a2bd501aa..785c41d205 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3385,13 +3385,13 @@ static void spapr_machine_finalizefn(Object *obj)
 void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg)
 {
     SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
 
     cpu_synchronize_state(cs);
     /* If FWNMI is inactive, addr will be -1, which will deliver to 0x100 */
     if (spapr->fwnmi_system_reset_addr != -1) {
         uint64_t rtas_addr, addr;
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
-        CPUPPCState *env = &cpu->env;
 
         /* get rtas addr from fdt */
         rtas_addr = spapr_get_rtas_addr();
@@ -3405,7 +3405,10 @@ void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg)
         stq_be_phys(&address_space_memory, addr + sizeof(uint64_t), 0);
         env->gpr[3] = addr;
     }
-    ppc_cpu_do_system_reset(cs, spapr->fwnmi_system_reset_addr);
+    ppc_cpu_do_system_reset(cs);
+    if (spapr->fwnmi_system_reset_addr != -1) {
+        env->nip = spapr->fwnmi_system_reset_addr;
+    }
 }
 
 static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 88d9449555..f4a5304d43 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1220,7 +1220,7 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
 int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
                                int cpuid, void *opaque);
 #ifndef CONFIG_USER_ONLY
-void ppc_cpu_do_system_reset(CPUState *cs, target_ulong vector);
+void ppc_cpu_do_system_reset(CPUState *cs);
 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector);
 extern const VMStateDescription vmstate_ppc_cpu;
 #endif
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 81ee19ebae..1acc3786de 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -983,15 +983,12 @@ static void ppc_hw_interrupt(CPUPPCState *env)
     }
 }
 
-void ppc_cpu_do_system_reset(CPUState *cs, target_ulong vector)
+void ppc_cpu_do_system_reset(CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
 
     powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
-    if (vector != -1) {
-        env->nip = vector;
-    }
 }
 
 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
-- 
2.26.2



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

* [PULL 04/18] ppc/pnv: Add support for NMI interface
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (2 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 03/18] ppc/spapr: tweak change system reset helper David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 05/18] spapr: Simplify selection of radix/hash during CAS David Gibson
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, David Gibson

From: Nicholas Piggin <npiggin@gmail.com>

This implements the NMI interface for the PNV machine, similarly to
commit 3431648272d ("spapr: Add support for new NMI interface") for
SPAPR.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Message-Id: <20200325144147.221875-3-npiggin@gmail.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index c9cb6fa357..a3b7a8d0ff 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -27,6 +27,7 @@
 #include "sysemu/runstate.h"
 #include "sysemu/cpus.h"
 #include "sysemu/device_tree.h"
+#include "sysemu/hw_accel.h"
 #include "target/ppc/cpu.h"
 #include "qemu/log.h"
 #include "hw/ppc/fdt.h"
@@ -34,6 +35,7 @@
 #include "hw/ppc/pnv.h"
 #include "hw/ppc/pnv_core.h"
 #include "hw/loader.h"
+#include "hw/nmi.h"
 #include "exec/address-spaces.h"
 #include "qapi/visitor.h"
 #include "monitor/monitor.h"
@@ -1977,10 +1979,35 @@ static void pnv_machine_set_hb(Object *obj, bool value, Error **errp)
     }
 }
 
+static void pnv_cpu_do_nmi_on_cpu(CPUState *cs, run_on_cpu_data arg)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    cpu_synchronize_state(cs);
+    ppc_cpu_do_system_reset(cs);
+    /*
+     * SRR1[42:45] is set to 0100 which the ISA defines as implementation
+     * dependent. POWER processors use this for xscom triggered interrupts,
+     * which come from the BMC or NMI IPIs.
+     */
+    env->spr[SPR_SRR1] |= PPC_BIT(43);
+}
+
+static void pnv_nmi(NMIState *n, int cpu_index, Error **errp)
+{
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        async_run_on_cpu(cs, pnv_cpu_do_nmi_on_cpu, RUN_ON_CPU_NULL);
+    }
+}
+
 static void pnv_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
     InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
+    NMIClass *nc = NMI_CLASS(oc);
 
     mc->desc = "IBM PowerNV (Non-Virtualized)";
     mc->init = pnv_init;
@@ -1997,6 +2024,7 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
     mc->default_ram_size = INITRD_LOAD_ADDR + INITRD_MAX_SIZE;
     mc->default_ram_id = "pnv.ram";
     ispc->print_info = pnv_pic_print_info;
+    nc->nmi_monitor_handler = pnv_nmi;
 
     object_class_property_add_bool(oc, "hb-mode",
                                    pnv_machine_get_hb, pnv_machine_set_hb,
@@ -2060,6 +2088,7 @@ static const TypeInfo types[] = {
         .class_size    = sizeof(PnvMachineClass),
         .interfaces = (InterfaceInfo[]) {
             { TYPE_INTERRUPT_STATS_PROVIDER },
+            { TYPE_NMI },
             { },
         },
     },
-- 
2.26.2



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

* [PULL 05/18] spapr: Simplify selection of radix/hash during CAS
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (3 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 04/18] ppc/pnv: Add support for NMI interface David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 06/18] spapr/cas: Separate CAS handling from rebuilding the FDT David Gibson
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The guest can select the MMU mode by setting bits 0-1 of byte 24
in OV5 to to 0b00 for hash or 0b01 for radix. As required by the
architecture, we terminate the boot process if any other value
is found there.

The usual way to negotiate features in OV5 is basically ANDing
the bitfield provided by the guest and the bitfield of features
supported by QEMU, previously populated at machine init.

For some not documented reason, MMU is treated differently : bit 1
of byte 24 (the radix/hash bit) is cleared from the guest OV5 and
explicitely set in the final negotiated OV5 if radix was requested.

Since the only expected input from the guest is the radix/hash bit
being set or not, it seems more appropriate to handle this like we
do for XIVE.

Set the radix bit in spapr->ov5 at machine init if it has a chance
to work (ie. power9, either TCG or a radix capable KVM) and rely
exclusively on spapr_ovec_intersect() to set the radix bit in
spapr->ov5_cas.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <158514993621.478799.4204740354545734293.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c       | 1 +
 hw/ppc/spapr_hcall.c | 6 +-----
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 785c41d205..167b1216ba 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2837,6 +2837,7 @@ static void spapr_machine_init(MachineState *machine)
     if ((!kvm_enabled() || kvmppc_has_cap_mmu_radix()) &&
         ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, 0,
                               spapr->max_compat_pvr)) {
+        spapr_ovec_set(spapr->ov5, OV5_MMU_RADIX_300);
         /* KVM and TCG always allow GTSE with radix... */
         spapr_ovec_set(spapr->ov5, OV5_MMU_RADIX_GTSE);
     }
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index e8ee447537..fb4fdd4a0c 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1739,9 +1739,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
         exit(EXIT_FAILURE);
     }
 
-    /* The radix/hash bit in byte 24 requires special handling: */
     guest_radix = spapr_ovec_test(ov5_guest, OV5_MMU_RADIX_300);
-    spapr_ovec_clear(ov5_guest, OV5_MMU_RADIX_300);
 
     guest_xive = spapr_ovec_test(ov5_guest, OV5_XIVE_EXPLOIT);
 
@@ -1786,14 +1784,12 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     /* full range of negotiated ov5 capabilities */
     spapr_ovec_intersect(spapr->ov5_cas, spapr->ov5, ov5_guest);
     spapr_ovec_cleanup(ov5_guest);
-    /* Now that processing is finished, set the radix/hash bit for the
-     * guest if it requested a valid mode; otherwise terminate the boot. */
+
     if (guest_radix) {
         if (kvm_enabled() && !kvmppc_has_cap_mmu_radix()) {
             error_report("Guest requested unavailable MMU mode (radix).");
             exit(EXIT_FAILURE);
         }
-        spapr_ovec_set(spapr->ov5_cas, OV5_MMU_RADIX_300);
     } else {
         if (kvm_enabled() && kvmppc_has_cap_mmu_radix()
             && !kvmppc_has_cap_mmu_hash_v3()) {
-- 
2.26.2



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

* [PULL 06/18] spapr/cas: Separate CAS handling from rebuilding the FDT
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (4 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 05/18] spapr: Simplify selection of radix/hash during CAS David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 07/18] spapr: Drop CAS reboot flag David Gibson
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

At the moment "ibm,client-architecture-support" ("CAS") is implemented
in SLOF and QEMU assists via the custom H_CAS hypercall which copies
an updated flatten device tree (FDT) blob to the SLOF memory which
it then uses to update its internal tree.

When we enable the OpenFirmware client interface in QEMU, we won't need
to copy the FDT to the guest as the client is expected to fetch
the device tree using the client interface.

This moves FDT rebuild out to a separate helper which is going to be
called from the "ibm,client-architecture-support" handler and leaves
writing FDT to the guest in the H_CAS handler.

This should not cause any behavioral change.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Message-Id: <20200310050733.29805-3-aik@ozlabs.ru>
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <158514994229.478799.2178881312094922324.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c         |  1 -
 hw/ppc/spapr_hcall.c   | 67 ++++++++++++++++++++++++++----------------
 include/hw/ppc/spapr.h |  7 +++++
 3 files changed, 48 insertions(+), 27 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 167b1216ba..f52488d397 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -96,7 +96,6 @@
  *
  * We load our kernel at 4M, leaving space for SLOF initial image
  */
-#define FDT_MAX_SIZE            0x100000
 #define RTAS_MAX_ADDR           0x80000000 /* RTAS must stay below that */
 #define FW_MAX_SIZE             0x400000
 #define FW_FILE_NAME            "slof.bin"
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index fb4fdd4a0c..48a8745514 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1665,16 +1665,12 @@ static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr)
     spapr_clear_pending_hotplug_events(spapr);
 }
 
-static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
-                                                  SpaprMachineState *spapr,
-                                                  target_ulong opcode,
-                                                  target_ulong *args)
+target_ulong do_client_architecture_support(PowerPCCPU *cpu,
+                                            SpaprMachineState *spapr,
+                                            target_ulong vec,
+                                            target_ulong fdt_bufsize)
 {
-    /* Working address in data buffer */
-    target_ulong addr = ppc64_phys_to_real(args[0]);
-    target_ulong fdt_buf = args[1];
-    target_ulong fdt_bufsize = args[2];
-    target_ulong ov_table;
+    target_ulong ov_table; /* Working address in data buffer */
     uint32_t cas_pvr;
     SpaprOptionVector *ov1_guest, *ov5_guest;
     bool guest_radix;
@@ -1694,7 +1690,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
         }
     }
 
-    cas_pvr = cas_check_pvr(spapr, cpu, &addr, &raw_mode_supported, &local_err);
+    cas_pvr = cas_check_pvr(spapr, cpu, &vec, &raw_mode_supported, &local_err);
     if (local_err) {
         error_report_err(local_err);
         return H_HARDWARE;
@@ -1717,7 +1713,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     }
 
     /* For the future use: here @ov_table points to the first option vector */
-    ov_table = addr;
+    ov_table = vec;
 
     ov1_guest = spapr_ovec_parse_vector(ov_table, 1);
     if (!ov1_guest) {
@@ -1824,7 +1820,6 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
 
     if (!spapr->cas_reboot) {
         void *fdt;
-        SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 };
 
         /* If spapr_machine_reset() did not set up a HPT but one is necessary
          * (because the guest isn't going to use radix) then set it up here. */
@@ -1833,21 +1828,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
             spapr_setup_hpt(spapr);
         }
 
-        if (fdt_bufsize < sizeof(hdr)) {
-            error_report("SLOF provided insufficient CAS buffer "
-                         TARGET_FMT_lu " (min: %zu)", fdt_bufsize, sizeof(hdr));
-            exit(EXIT_FAILURE);
-        }
-
-        fdt_bufsize -= sizeof(hdr);
-
         fdt = spapr_build_fdt(spapr, false, fdt_bufsize);
-        _FDT((fdt_pack(fdt)));
-
-        cpu_physical_memory_write(fdt_buf, &hdr, sizeof(hdr));
-        cpu_physical_memory_write(fdt_buf + sizeof(hdr), fdt,
-                                  fdt_totalsize(fdt));
-        trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr));
 
         g_free(spapr->fdt_blob);
         spapr->fdt_size = fdt_totalsize(fdt);
@@ -1862,6 +1843,40 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     return H_SUCCESS;
 }
 
+static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
+                                                  SpaprMachineState *spapr,
+                                                  target_ulong opcode,
+                                                  target_ulong *args)
+{
+    target_ulong vec = ppc64_phys_to_real(args[0]);
+    target_ulong fdt_buf = args[1];
+    target_ulong fdt_bufsize = args[2];
+    target_ulong ret;
+    SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 };
+
+    if (fdt_bufsize < sizeof(hdr)) {
+        error_report("SLOF provided insufficient CAS buffer "
+                     TARGET_FMT_lu " (min: %zu)", fdt_bufsize, sizeof(hdr));
+        exit(EXIT_FAILURE);
+    }
+
+    fdt_bufsize -= sizeof(hdr);
+
+    ret = do_client_architecture_support(cpu, spapr, vec, fdt_bufsize);
+    if (ret == H_SUCCESS) {
+        _FDT((fdt_pack(spapr->fdt_blob)));
+        spapr->fdt_size = fdt_totalsize(spapr->fdt_blob);
+        spapr->fdt_initial_size = spapr->fdt_size;
+
+        cpu_physical_memory_write(fdt_buf, &hdr, sizeof(hdr));
+        cpu_physical_memory_write(fdt_buf + sizeof(hdr), spapr->fdt_blob,
+                                  spapr->fdt_size);
+        trace_spapr_cas_continue(spapr->fdt_size + sizeof(hdr));
+    }
+
+    return ret;
+}
+
 static target_ulong h_home_node_associativity(PowerPCCPU *cpu,
                                               SpaprMachineState *spapr,
                                               target_ulong opcode,
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 42d64a0368..b7e13e5aaf 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -102,6 +102,8 @@ typedef enum {
 #define SPAPR_CAP_FIXED_CCD             0x03
 #define SPAPR_CAP_FIXED_NA              0x10 /* Lets leave a bit of a gap... */
 
+#define FDT_MAX_SIZE                    0x100000
+
 typedef struct SpaprCapabilities SpaprCapabilities;
 struct SpaprCapabilities {
     uint8_t caps[SPAPR_CAP_NUM];
@@ -566,6 +568,11 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn);
 target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
                              target_ulong *args);
 
+target_ulong do_client_architecture_support(PowerPCCPU *cpu,
+                                            SpaprMachineState *spapr,
+                                            target_ulong addr,
+                                            target_ulong fdt_bufsize);
+
 /* Virtual Processor Area structure constants */
 #define VPA_MIN_SIZE           640
 #define VPA_SIZE_OFFSET        0x4
-- 
2.26.2



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

* [PULL 07/18] spapr: Drop CAS reboot flag
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (5 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 06/18] spapr/cas: Separate CAS handling from rebuilding the FDT David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 08/18] target/ppc: Enforce that the root page directory size must be at least 5 David Gibson
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The CAS reboot flag is false by default and all the locations that
could set it to true have been dropped. This means that all code
blocks depending on the flag being set is dead code and the other
code blocks should be executed always.

Just do that and drop the now uneeded CAS reboot flag. Fix a
comment on the way to make checkpatch happy.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <158514994893.478799.11772512888322840990.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c         | 18 ++++--------------
 hw/ppc/spapr_hcall.c   | 33 ++++++++++++++-------------------
 include/hw/ppc/spapr.h |  1 -
 3 files changed, 18 insertions(+), 34 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f52488d397..841b5ec59b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1579,9 +1579,7 @@ void spapr_setup_hpt(SpaprMachineState *spapr)
 {
     int hpt_shift;
 
-    if ((spapr->resize_hpt == SPAPR_RESIZE_HPT_DISABLED)
-        || (spapr->cas_reboot
-            && !spapr_ovec_test(spapr->ov5_cas, OV5_HPT_RESIZE))) {
+    if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DISABLED) {
         hpt_shift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->maxram_size);
     } else {
         uint64_t current_ram_size;
@@ -1645,16 +1643,10 @@ static void spapr_machine_reset(MachineState *machine)
 
     qemu_devices_reset();
 
-    /*
-     * If this reset wasn't generated by CAS, we should reset our
-     * negotiated options and start from scratch
-     */
-    if (!spapr->cas_reboot) {
-        spapr_ovec_cleanup(spapr->ov5_cas);
-        spapr->ov5_cas = spapr_ovec_new();
+    spapr_ovec_cleanup(spapr->ov5_cas);
+    spapr->ov5_cas = spapr_ovec_new();
 
-        ppc_set_compat_all(spapr->max_compat_pvr, &error_fatal);
-    }
+    ppc_set_compat_all(spapr->max_compat_pvr, &error_fatal);
 
     /*
      * This is fixing some of the default configuration of the XIVE
@@ -1707,8 +1699,6 @@ static void spapr_machine_reset(MachineState *machine)
     spapr_cpu_set_entry_state(first_ppc_cpu, SPAPR_ENTRY_POINT, 0, fdt_addr, 0);
     first_ppc_cpu->env.gpr[5] = 0;
 
-    spapr->cas_reboot = false;
-
     spapr->fwnmi_system_reset_addr = -1;
     spapr->fwnmi_machine_check_addr = -1;
     spapr->fwnmi_machine_check_interlock = -1;
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 48a8745514..0f54988f2e 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1678,6 +1678,7 @@ target_ulong do_client_architecture_support(PowerPCCPU *cpu,
     bool raw_mode_supported = false;
     bool guest_xive;
     CPUState *cs;
+    void *fdt;
 
     /* CAS is supposed to be called early when only the boot vCPU is active. */
     CPU_FOREACH(cs) {
@@ -1818,27 +1819,21 @@ target_ulong do_client_architecture_support(PowerPCCPU *cpu,
 
     spapr_handle_transient_dev_before_cas(spapr);
 
-    if (!spapr->cas_reboot) {
-        void *fdt;
-
-        /* If spapr_machine_reset() did not set up a HPT but one is necessary
-         * (because the guest isn't going to use radix) then set it up here. */
-        if ((spapr->patb_entry & PATE1_GR) && !guest_radix) {
-            /* legacy hash or new hash: */
-            spapr_setup_hpt(spapr);
-        }
-
-        fdt = spapr_build_fdt(spapr, false, fdt_bufsize);
-
-        g_free(spapr->fdt_blob);
-        spapr->fdt_size = fdt_totalsize(fdt);
-        spapr->fdt_initial_size = spapr->fdt_size;
-        spapr->fdt_blob = fdt;
+    /*
+     * If spapr_machine_reset() did not set up a HPT but one is necessary
+     * (because the guest isn't going to use radix) then set it up here.
+     */
+    if ((spapr->patb_entry & PATE1_GR) && !guest_radix) {
+        /* legacy hash or new hash: */
+        spapr_setup_hpt(spapr);
     }
 
-    if (spapr->cas_reboot) {
-        qemu_system_reset_request(SHUTDOWN_CAUSE_SUBSYSTEM_RESET);
-    }
+    fdt = spapr_build_fdt(spapr, false, fdt_bufsize);
+
+    g_free(spapr->fdt_blob);
+    spapr->fdt_size = fdt_totalsize(fdt);
+    spapr->fdt_initial_size = spapr->fdt_size;
+    spapr->fdt_blob = fdt;
 
     return H_SUCCESS;
 }
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index b7e13e5aaf..e579eaf28c 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -178,7 +178,6 @@ struct SpaprMachineState {
     SpaprEventSource *event_sources;
 
     /* ibm,client-architecture-support option negotiation */
-    bool cas_reboot;
     bool cas_pre_isa3_guest;
     SpaprOptionVector *ov5;         /* QEMU-supported option vectors */
     SpaprOptionVector *ov5_cas;     /* negotiated (via CAS) option vectors */
-- 
2.26.2



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

* [PULL 08/18] target/ppc: Enforce that the root page directory size must be at least 5
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (6 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 07/18] spapr: Drop CAS reboot flag David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 09/18] target/ppc: Introduce a relocation bool in ppc_radix64_handle_mmu_fault() David Gibson
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

According to the ISA the root page directory size of a radix tree for
either process- or partition-scoped translation must be >= 5.

Thus add this to the list of conditions checked when validating the
partition table entry in validate_pate();

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20200330094946.24678-2-clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/mmu-radix64.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 224e646c50..9967857058 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -212,6 +212,9 @@ static bool validate_pate(PowerPCCPU *cpu, uint64_t lpid, ppc_v3_pate_t *pate)
     if (lpid == 0 && !msr_hv) {
         return false;
     }
+    if ((pate->dw0 & PATE1_R_PRTS) < 5) {
+        return false;
+    }
     /* More checks ... */
     return true;
 }
-- 
2.26.2



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

* [PULL 09/18] target/ppc: Introduce a relocation bool in ppc_radix64_handle_mmu_fault()
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (7 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 08/18] target/ppc: Enforce that the root page directory size must be at least 5 David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 10/18] target/ppc: Assert if HV mode is set when running under a pseries machine David Gibson
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Cédric Le Goater <clg@kaod.org>

It will ease the introduction of new routines for partition-scoped
Radix translation.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20200330094946.24678-3-clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/mmu-radix64.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 9967857058..f6007e9565 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -229,12 +229,13 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
     uint64_t lpid = 0, pid = 0, offset, size, prtbe0, pte;
     int page_size, prot, fault_cause = 0;
     ppc_v3_pate_t pate;
+    bool relocation;
 
     assert((rwx == 0) || (rwx == 1) || (rwx == 2));
 
+    relocation = ((rwx == 2) && (msr_ir == 1)) || ((rwx != 2) && (msr_dr == 1));
     /* HV or virtual hypervisor Real Mode Access */
-    if ((msr_hv || cpu->vhyp) &&
-        (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0)))) {
+    if (!relocation && (msr_hv || cpu->vhyp)) {
         /* In real mode top 4 effective addr bits (mostly) ignored */
         raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL;
 
-- 
2.26.2



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

* [PULL 10/18] target/ppc: Assert if HV mode is set when running under a pseries machine
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (8 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 09/18] target/ppc: Introduce a relocation bool in ppc_radix64_handle_mmu_fault() David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 11/18] spapr: Don't allow unplug of NVLink2 devices David Gibson
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Cédric Le Goater <clg@kaod.org>

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20200330094946.24678-4-clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/mmu-radix64.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index f6007e9565..d2422d1c54 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -231,6 +231,7 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
     ppc_v3_pate_t pate;
     bool relocation;
 
+    assert(!(msr_hv && cpu->vhyp));
     assert((rwx == 0) || (rwx == 1) || (rwx == 2));
 
     relocation = ((rwx == 2) && (msr_ir == 1)) || ((rwx != 2) && (msr_dr == 1));
-- 
2.26.2



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

* [PULL 11/18] spapr: Don't allow unplug of NVLink2 devices
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (9 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 10/18] target/ppc: Assert if HV mode is set when running under a pseries machine David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 12/18] target/ppc: Introduce ppc_radix64_xlate() for Radix tree translation David Gibson
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, David Gibson

Currently, we can't properly handle unplug of NVLink2 devices, because we
don't have code to tear down their special memory resources.  There's not
a lot of impetus to implement that: since hardware NVLink2 devices can't
be hot unplugged, the guest side drivers don't usually support unplug
anyway.

Therefore, simply prevent unplug of NVLink2 devices.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 hw/ppc/spapr_pci.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 55ca9dee1e..61b84a392d 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1665,6 +1665,10 @@ static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
             error_setg(errp, "PCI: Hot unplug of PCI bridges not supported");
             return;
         }
+        if (object_property_get_uint(OBJECT(pdev), "nvlink2-tgt", NULL)) {
+            error_setg(errp, "PCI: Cannot unplug NVLink2 devices");
+            return;
+        }
 
         /* ensure any other present functions are pending unplug */
         if (PCI_FUNC(pdev->devfn) == 0) {
-- 
2.26.2



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

* [PULL 12/18] target/ppc: Introduce ppc_radix64_xlate() for Radix tree translation
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (10 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 11/18] spapr: Don't allow unplug of NVLink2 devices David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 13/18] target/ppc: Extend ppc_radix64_check_prot() with a 'partition_scoped' bool David Gibson
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Cédric Le Goater <clg@kaod.org>

This is moving code under a new ppc_radix64_xlate() routine shared by
the MMU Radix page fault handler and the 'get_phys_page_debug' PPC
callback. The difference being that 'get_phys_page_debug' does not
generate exceptions.

The specific part of process-scoped Radix translation is moved under
ppc_radix64_process_scoped_xlate() in preparation of the future support
for partition-scoped Radix translation. Routines raising the exceptions
now take a 'cause_excp' bool to cover the 'get_phys_page_debug' case.

It should be functionally equivalent.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20200403140056.59465-2-clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/mmu-radix64.c | 219 ++++++++++++++++++++++-----------------
 1 file changed, 123 insertions(+), 96 deletions(-)

diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index d2422d1c54..4b0d0ff50a 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -219,17 +219,127 @@ static bool validate_pate(PowerPCCPU *cpu, uint64_t lpid, ppc_v3_pate_t *pate)
     return true;
 }
 
+static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx,
+                                            vaddr eaddr, uint64_t pid,
+                                            ppc_v3_pate_t pate, hwaddr *g_raddr,
+                                            int *g_prot, int *g_page_size,
+                                            bool cause_excp)
+{
+    CPUState *cs = CPU(cpu);
+    uint64_t offset, size, prtbe_addr, prtbe0, pte;
+    int fault_cause = 0;
+    hwaddr pte_addr;
+
+    /* Index Process Table by PID to Find Corresponding Process Table Entry */
+    offset = pid * sizeof(struct prtb_entry);
+    size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12);
+    if (offset >= size) {
+        /* offset exceeds size of the process table */
+        if (cause_excp) {
+            ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE);
+        }
+        return 1;
+    }
+    prtbe_addr = (pate.dw1 & PATE1_R_PRTB) + offset;
+    prtbe0 = ldq_phys(cs->as, prtbe_addr);
+
+    /* Walk Radix Tree from Process Table Entry to Convert EA to RA */
+    *g_page_size = PRTBE_R_GET_RTS(prtbe0);
+    pte = ppc_radix64_walk_tree(cpu, eaddr & R_EADDR_MASK,
+                                prtbe0 & PRTBE_R_RPDB, prtbe0 & PRTBE_R_RPDS,
+                                g_raddr, g_page_size, &fault_cause, &pte_addr);
+
+    if (!(pte & R_PTE_VALID) ||
+        ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, g_prot)) {
+        /* No valid pte or access denied due to protection */
+        if (cause_excp) {
+            ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause);
+        }
+        return 1;
+    }
+
+    ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, g_prot);
+
+    return 0;
+}
+
+static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx,
+                             bool relocation,
+                             hwaddr *raddr, int *psizep, int *protp,
+                             bool cause_excp)
+{
+    uint64_t lpid = 0, pid = 0;
+    ppc_v3_pate_t pate;
+    int psize, prot;
+    hwaddr g_raddr;
+
+    /* Virtual Mode Access - get the fully qualified address */
+    if (!ppc_radix64_get_fully_qualified_addr(&cpu->env, eaddr, &lpid, &pid)) {
+        if (cause_excp) {
+            ppc_radix64_raise_segi(cpu, rwx, eaddr);
+        }
+        return 1;
+    }
+
+    /* Get Process Table */
+    if (cpu->vhyp) {
+        PPCVirtualHypervisorClass *vhc;
+        vhc = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+        vhc->get_pate(cpu->vhyp, &pate);
+    } else {
+        if (!ppc64_v3_get_pate(cpu, lpid, &pate)) {
+            if (cause_excp) {
+                ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE);
+            }
+            return 1;
+        }
+        if (!validate_pate(cpu, lpid, &pate)) {
+            if (cause_excp) {
+                ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_R_BADCONFIG);
+            }
+            return 1;
+        }
+        /* We don't support guest mode yet */
+        if (lpid != 0) {
+            error_report("PowerNV guest support Unimplemented");
+            exit(1);
+        }
+    }
+
+    *psizep = INT_MAX;
+    *protp = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+
+    /*
+     * Perform process-scoped translation if relocation enabled.
+     *
+     * - Translates an effective address to a host real address in
+     *   quadrants 0 and 3 when HV=1.
+     */
+    if (relocation) {
+        int ret = ppc_radix64_process_scoped_xlate(cpu, rwx, eaddr, pid,
+                                                   pate, &g_raddr, &prot,
+                                                   &psize, cause_excp);
+        if (ret) {
+            return ret;
+        }
+        *psizep = MIN(*psizep, psize);
+        *protp &= prot;
+    } else {
+        g_raddr = eaddr & R_EADDR_MASK;
+    }
+
+    *raddr = g_raddr;
+    return 0;
+}
+
 int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
                                  int mmu_idx)
 {
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
-    PPCVirtualHypervisorClass *vhc;
-    hwaddr raddr, pte_addr;
-    uint64_t lpid = 0, pid = 0, offset, size, prtbe0, pte;
-    int page_size, prot, fault_cause = 0;
-    ppc_v3_pate_t pate;
+    int page_size, prot;
     bool relocation;
+    hwaddr raddr;
 
     assert(!(msr_hv && cpu->vhyp));
     assert((rwx == 0) || (rwx == 1) || (rwx == 2));
@@ -262,55 +372,12 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
                       TARGET_FMT_lx "\n", env->spr[SPR_LPCR]);
     }
 
-    /* Virtual Mode Access - get the fully qualified address */
-    if (!ppc_radix64_get_fully_qualified_addr(env, eaddr, &lpid, &pid)) {
-        ppc_radix64_raise_segi(cpu, rwx, eaddr);
+    /* Translate eaddr to raddr (where raddr is addr qemu needs for access) */
+    if (ppc_radix64_xlate(cpu, eaddr, rwx, relocation, &raddr,
+                          &page_size, &prot, true)) {
         return 1;
     }
 
-    /* Get Process Table */
-    if (cpu->vhyp) {
-        vhc = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
-        vhc->get_pate(cpu->vhyp, &pate);
-    } else {
-        if (!ppc64_v3_get_pate(cpu, lpid, &pate)) {
-            ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE);
-            return 1;
-        }
-        if (!validate_pate(cpu, lpid, &pate)) {
-            ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_R_BADCONFIG);
-        }
-        /* We don't support guest mode yet */
-        if (lpid != 0) {
-            error_report("PowerNV guest support Unimplemented");
-            exit(1);
-       }
-    }
-
-    /* Index Process Table by PID to Find Corresponding Process Table Entry */
-    offset = pid * sizeof(struct prtb_entry);
-    size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12);
-    if (offset >= size) {
-        /* offset exceeds size of the process table */
-        ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE);
-        return 1;
-    }
-    prtbe0 = ldq_phys(cs->as, (pate.dw1 & PATE1_R_PRTB) + offset);
-
-    /* Walk Radix Tree from Process Table Entry to Convert EA to RA */
-    page_size = PRTBE_R_GET_RTS(prtbe0);
-    pte = ppc_radix64_walk_tree(cpu, eaddr & R_EADDR_MASK,
-                                prtbe0 & PRTBE_R_RPDB, prtbe0 & PRTBE_R_RPDS,
-                                &raddr, &page_size, &fault_cause, &pte_addr);
-    if (!pte || ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, &prot)) {
-        /* Couldn't get pte or access denied due to protection */
-        ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause);
-        return 1;
-    }
-
-    /* Update Reference and Change Bits */
-    ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, &prot);
-
     tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
                  prot, mmu_idx, 1UL << page_size);
     return 0;
@@ -318,58 +385,18 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
 
 hwaddr ppc_radix64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong eaddr)
 {
-    CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
-    PPCVirtualHypervisorClass *vhc;
-    hwaddr raddr, pte_addr;
-    uint64_t lpid = 0, pid = 0, offset, size, prtbe0, pte;
-    int page_size, fault_cause = 0;
-    ppc_v3_pate_t pate;
+    int psize, prot;
+    hwaddr raddr;
 
     /* Handle Real Mode */
-    if (msr_dr == 0) {
+    if ((msr_dr == 0) && (msr_hv || cpu->vhyp)) {
         /* In real mode top 4 effective addr bits (mostly) ignored */
         return eaddr & 0x0FFFFFFFFFFFFFFFULL;
     }
 
-    /* Virtual Mode Access - get the fully qualified address */
-    if (!ppc_radix64_get_fully_qualified_addr(env, eaddr, &lpid, &pid)) {
-        return -1;
-    }
-
-    /* Get Process Table */
-    if (cpu->vhyp) {
-        vhc = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
-        vhc->get_pate(cpu->vhyp, &pate);
-    } else {
-        if (!ppc64_v3_get_pate(cpu, lpid, &pate)) {
-            return -1;
-        }
-        if (!validate_pate(cpu, lpid, &pate)) {
-            return -1;
-        }
-        /* We don't support guest mode yet */
-        if (lpid != 0) {
-            error_report("PowerNV guest support Unimplemented");
-            exit(1);
-       }
-    }
-
-    /* Index Process Table by PID to Find Corresponding Process Table Entry */
-    offset = pid * sizeof(struct prtb_entry);
-    size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12);
-    if (offset >= size) {
-        /* offset exceeds size of the process table */
-        return -1;
-    }
-    prtbe0 = ldq_phys(cs->as, (pate.dw1 & PATE1_R_PRTB) + offset);
-
-    /* Walk Radix Tree from Process Table Entry to Convert EA to RA */
-    page_size = PRTBE_R_GET_RTS(prtbe0);
-    pte = ppc_radix64_walk_tree(cpu, eaddr & R_EADDR_MASK,
-                                prtbe0 & PRTBE_R_RPDB, prtbe0 & PRTBE_R_RPDS,
-                                &raddr, &page_size, &fault_cause, &pte_addr);
-    if (!pte) {
+    if (ppc_radix64_xlate(cpu, eaddr, 0, msr_dr, &raddr, &psize,
+                          &prot, false)) {
         return -1;
     }
 
-- 
2.26.2



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

* [PULL 13/18] target/ppc: Extend ppc_radix64_check_prot() with a 'partition_scoped' bool
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (11 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 12/18] target/ppc: Introduce ppc_radix64_xlate() for Radix tree translation David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 14/18] target/ppc: Rework ppc_radix64_walk_tree() for partition-scoped translation David Gibson
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Cédric Le Goater <clg@kaod.org>

This prepares ground for partition-scoped Radix translation.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Message-Id: <20200403140056.59465-3-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/mmu-radix64.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 4b0d0ff50a..11b3c6d48c 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -105,7 +105,8 @@ static void ppc_radix64_raise_si(PowerPCCPU *cpu, int rwx, vaddr eaddr,
 
 
 static bool ppc_radix64_check_prot(PowerPCCPU *cpu, int rwx, uint64_t pte,
-                                   int *fault_cause, int *prot)
+                                   int *fault_cause, int *prot,
+                                   bool partition_scoped)
 {
     CPUPPCState *env = &cpu->env;
     const int need_prot[] = { PAGE_READ, PAGE_WRITE, PAGE_EXEC };
@@ -121,11 +122,11 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu, int rwx, uint64_t pte,
     }
 
     /* Determine permissions allowed by Encoded Access Authority */
-    if ((pte & R_PTE_EAA_PRIV) && msr_pr) { /* Insufficient Privilege */
+    if (!partition_scoped && (pte & R_PTE_EAA_PRIV) && msr_pr) {
         *prot = 0;
-    } else if (msr_pr || (pte & R_PTE_EAA_PRIV)) {
+    } else if (msr_pr || (pte & R_PTE_EAA_PRIV) || partition_scoped) {
         *prot = ppc_radix64_get_prot_eaa(pte);
-    } else { /* !msr_pr && !(pte & R_PTE_EAA_PRIV) */
+    } else { /* !msr_pr && !(pte & R_PTE_EAA_PRIV) && !partition_scoped */
         *prot = ppc_radix64_get_prot_eaa(pte);
         *prot &= ppc_radix64_get_prot_amr(cpu); /* Least combined permissions */
     }
@@ -250,7 +251,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx,
                                 g_raddr, g_page_size, &fault_cause, &pte_addr);
 
     if (!(pte & R_PTE_VALID) ||
-        ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, g_prot)) {
+        ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, g_prot, false)) {
         /* No valid pte or access denied due to protection */
         if (cause_excp) {
             ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause);
-- 
2.26.2



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

* [PULL 14/18] target/ppc: Rework ppc_radix64_walk_tree() for partition-scoped translation
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (12 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 13/18] target/ppc: Extend ppc_radix64_check_prot() with a 'partition_scoped' bool David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 15/18] target/ppc: Add support for Radix " David Gibson
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The ppc_radix64_walk_tree() routine walks through the nested radix
tables to look for a PTE.

Split it in two and introduce a new routine ppc_radix64_next_level()
which we will use for partition-scoped Radix translation when
translating the process tree addresses. The prototypes are slightly
change to use a 'AddressSpace *' parameter, instead of a 'PowerPCCPU *'
which is not required, and to return an error code instead of a PTE
value. It clarifies error handling in the callers.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20200403140056.59465-4-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/mmu-radix64.c | 79 ++++++++++++++++++++++++++--------------
 1 file changed, 52 insertions(+), 27 deletions(-)

diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 11b3c6d48c..2400da41e0 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -163,44 +163,67 @@ static void ppc_radix64_set_rc(PowerPCCPU *cpu, int rwx, uint64_t pte,
     }
 }
 
-static uint64_t ppc_radix64_walk_tree(PowerPCCPU *cpu, vaddr eaddr,
-                                      uint64_t base_addr, uint64_t nls,
-                                      hwaddr *raddr, int *psize,
-                                      int *fault_cause, hwaddr *pte_addr)
+static int ppc_radix64_next_level(AddressSpace *as, vaddr eaddr,
+                                  uint64_t *pte_addr, uint64_t *nls,
+                                  int *psize, uint64_t *pte, int *fault_cause)
 {
-    CPUState *cs = CPU(cpu);
     uint64_t index, pde;
 
-    if (nls < 5) { /* Directory maps less than 2**5 entries */
+    if (*nls < 5) { /* Directory maps less than 2**5 entries */
         *fault_cause |= DSISR_R_BADCONFIG;
-        return 0;
+        return 1;
     }
 
     /* Read page <directory/table> entry from guest address space */
-    index = eaddr >> (*psize - nls); /* Shift */
-    index &= ((1UL << nls) - 1); /* Mask */
-    pde = ldq_phys(cs->as, base_addr + (index * sizeof(pde)));
-    if (!(pde & R_PTE_VALID)) { /* Invalid Entry */
+    pde = ldq_phys(as, *pte_addr);
+    if (!(pde & R_PTE_VALID)) {         /* Invalid Entry */
         *fault_cause |= DSISR_NOPTE;
-        return 0;
+        return 1;
     }
 
-    *psize -= nls;
+    *pte = pde;
+    *psize -= *nls;
+    if (!(pde & R_PTE_LEAF)) { /* Prepare for next iteration */
+        *nls = pde & R_PDE_NLS;
+        index = eaddr >> (*psize - *nls);       /* Shift */
+        index &= ((1UL << *nls) - 1);           /* Mask */
+        *pte_addr = (pde & R_PDE_NLB) + (index * sizeof(pde));
+    }
+    return 0;
+}
 
-    /* Check if Leaf Entry -> Page Table Entry -> Stop the Search */
-    if (pde & R_PTE_LEAF) {
-        uint64_t rpn = pde & R_PTE_RPN;
-        uint64_t mask = (1UL << *psize) - 1;
+static int ppc_radix64_walk_tree(AddressSpace *as, vaddr eaddr,
+                                 uint64_t base_addr, uint64_t nls,
+                                 hwaddr *raddr, int *psize, uint64_t *pte,
+                                 int *fault_cause, hwaddr *pte_addr)
+{
+    uint64_t index, pde, rpn , mask;
 
-        /* Or high bits of rpn and low bits to ea to form whole real addr */
-        *raddr = (rpn & ~mask) | (eaddr & mask);
-        *pte_addr = base_addr + (index * sizeof(pde));
-        return pde;
+    if (nls < 5) { /* Directory maps less than 2**5 entries */
+        *fault_cause |= DSISR_R_BADCONFIG;
+        return 1;
     }
 
-    /* Next Level of Radix Tree */
-    return ppc_radix64_walk_tree(cpu, eaddr, pde & R_PDE_NLB, pde & R_PDE_NLS,
-                                 raddr, psize, fault_cause, pte_addr);
+    index = eaddr >> (*psize - nls);    /* Shift */
+    index &= ((1UL << nls) - 1);       /* Mask */
+    *pte_addr = base_addr + (index * sizeof(pde));
+    do {
+        int ret;
+
+        ret = ppc_radix64_next_level(as, eaddr, pte_addr, &nls, psize, &pde,
+                                     fault_cause);
+        if (ret) {
+            return ret;
+        }
+    } while (!(pde & R_PTE_LEAF));
+
+    *pte = pde;
+    rpn = pde & R_PTE_RPN;
+    mask = (1UL << *psize) - 1;
+
+    /* Or high bits of rpn and low bits to ea to form whole real addr */
+    *raddr = (rpn & ~mask) | (eaddr & mask);
+    return 0;
 }
 
 static bool validate_pate(PowerPCCPU *cpu, uint64_t lpid, ppc_v3_pate_t *pate)
@@ -230,6 +253,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx,
     uint64_t offset, size, prtbe_addr, prtbe0, pte;
     int fault_cause = 0;
     hwaddr pte_addr;
+    int ret;
 
     /* Index Process Table by PID to Find Corresponding Process Table Entry */
     offset = pid * sizeof(struct prtb_entry);
@@ -246,11 +270,12 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx,
 
     /* Walk Radix Tree from Process Table Entry to Convert EA to RA */
     *g_page_size = PRTBE_R_GET_RTS(prtbe0);
-    pte = ppc_radix64_walk_tree(cpu, eaddr & R_EADDR_MASK,
+    ret = ppc_radix64_walk_tree(cs->as, eaddr & R_EADDR_MASK,
                                 prtbe0 & PRTBE_R_RPDB, prtbe0 & PRTBE_R_RPDS,
-                                g_raddr, g_page_size, &fault_cause, &pte_addr);
+                                g_raddr, g_page_size, &pte, &fault_cause,
+                                &pte_addr);
 
-    if (!(pte & R_PTE_VALID) ||
+    if (ret ||
         ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, g_prot, false)) {
         /* No valid pte or access denied due to protection */
         if (cause_excp) {
-- 
2.26.2



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

* [PULL 15/18] target/ppc: Add support for Radix partition-scoped translation
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (13 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 14/18] target/ppc: Rework ppc_radix64_walk_tree() for partition-scoped translation David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 16/18] spapr_nvdimm.c: make 'label-size' mandatory David Gibson
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The Radix tree translation model currently supports process-scoped
translation for the PowerNV machine (Hypervisor mode) and for the
pSeries machine (Guest mode). Guests running under an emulated
Hypervisor (PowerNV machine) require a new type of Radix translation,
called partition-scoped, which is missing today.

The Radix tree translation is a 2 steps process. The first step,
process-scoped translation, converts an effective Address to a guest
real address, and the second step, partition-scoped translation,
converts a guest real address to a host real address.

There are difference cases to covers :

* Hypervisor real mode access: no Radix translation.

* Hypervisor or host application access (quadrant 0 and 3) with
  relocation on: process-scoped translation.

* Guest OS real mode access: only partition-scoped translation.

* Guest OS real or guest application access (quadrant 0 and 3) with
  relocation on: both process-scoped translation and partition-scoped
  translations.

* Hypervisor access in quadrant 1 and 2 with relocation on: both
  process-scoped translation and partition-scoped translations.

The radix tree partition-scoped translation is performed using tables
pointed to by the first double-word of the Partition Table Entries and
process-scoped translation uses tables pointed to by the Process Table
Entries (second double-word of the Partition Table Entries).

Both partition-scoped and process-scoped translations process are
identical and thus the radix tree traversing code is largely reused.
However, errors in partition-scoped translations generate hypervisor
exceptions.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20200403140056.59465-5-clg@kaod.org>
[dwg: Fixup from Greg Kurz folded in]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/cpu.h         |   3 +
 target/ppc/excp_helper.c |   3 +-
 target/ppc/mmu-radix64.c | 194 +++++++++++++++++++++++++++++++++++----
 3 files changed, 181 insertions(+), 19 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index f4a5304d43..6b6dd7e483 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -463,6 +463,9 @@ typedef struct ppc_v3_pate_t {
 #define DSISR_AMR                0x00200000
 /* Unsupported Radix Tree Configuration */
 #define DSISR_R_BADCONFIG        0x00080000
+#define DSISR_ATOMIC_RC          0x00040000
+/* Unable to translate address of (guest) pde or process/page table entry */
+#define DSISR_PRTABLE_FAULT      0x00020000
 
 /* SRR1 error code fields */
 
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 1acc3786de..f052979664 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -506,9 +506,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
         break;
+    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
+        msr |= env->error_code;
     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
-    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
     case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
     case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
     case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt            */
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 2400da41e0..1404e53dec 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -103,6 +103,27 @@ static void ppc_radix64_raise_si(PowerPCCPU *cpu, int rwx, vaddr eaddr,
     }
 }
 
+static void ppc_radix64_raise_hsi(PowerPCCPU *cpu, int rwx, vaddr eaddr,
+                                  hwaddr g_raddr, uint32_t cause)
+{
+    CPUState *cs = CPU(cpu);
+    CPUPPCState *env = &cpu->env;
+
+    if (rwx == 2) { /* H Instruction Storage Interrupt */
+        cs->exception_index = POWERPC_EXCP_HISI;
+        env->spr[SPR_ASDR] = g_raddr;
+        env->error_code = cause;
+    } else { /* H Data Storage Interrupt */
+        cs->exception_index = POWERPC_EXCP_HDSI;
+        if (rwx == 1) { /* Write -> Store */
+            cause |= DSISR_ISSTORE;
+        }
+        env->spr[SPR_HDSISR] = cause;
+        env->spr[SPR_HDAR] = eaddr;
+        env->spr[SPR_ASDR] = g_raddr;
+        env->error_code = 0;
+    }
+}
 
 static bool ppc_radix64_check_prot(PowerPCCPU *cpu, int rwx, uint64_t pte,
                                    int *fault_cause, int *prot,
@@ -243,6 +264,37 @@ static bool validate_pate(PowerPCCPU *cpu, uint64_t lpid, ppc_v3_pate_t *pate)
     return true;
 }
 
+static int ppc_radix64_partition_scoped_xlate(PowerPCCPU *cpu, int rwx,
+                                              vaddr eaddr, hwaddr g_raddr,
+                                              ppc_v3_pate_t pate,
+                                              hwaddr *h_raddr, int *h_prot,
+                                              int *h_page_size, bool pde_addr,
+                                              bool cause_excp)
+{
+    int fault_cause = 0;
+    hwaddr pte_addr;
+    uint64_t pte;
+
+    *h_page_size = PRTBE_R_GET_RTS(pate.dw0);
+    /* No valid pte or access denied due to protection */
+    if (ppc_radix64_walk_tree(CPU(cpu)->as, g_raddr, pate.dw0 & PRTBE_R_RPDB,
+                              pate.dw0 & PRTBE_R_RPDS, h_raddr, h_page_size,
+                              &pte, &fault_cause, &pte_addr) ||
+        ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, h_prot, true)) {
+        if (pde_addr) /* address being translated was that of a guest pde */
+            fault_cause |= DSISR_PRTABLE_FAULT;
+        if (cause_excp) {
+            ppc_radix64_raise_hsi(cpu, rwx, eaddr, g_raddr, fault_cause);
+        }
+        return 1;
+    }
+
+    /* Update Reference and Change Bits */
+    ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, h_prot);
+
+    return 0;
+}
+
 static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx,
                                             vaddr eaddr, uint64_t pid,
                                             ppc_v3_pate_t pate, hwaddr *g_raddr,
@@ -250,9 +302,10 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx,
                                             bool cause_excp)
 {
     CPUState *cs = CPU(cpu);
-    uint64_t offset, size, prtbe_addr, prtbe0, pte;
-    int fault_cause = 0;
-    hwaddr pte_addr;
+    CPUPPCState *env = &cpu->env;
+    uint64_t offset, size, prtbe_addr, prtbe0, base_addr, nls, index, pte;
+    int fault_cause = 0, h_page_size, h_prot;
+    hwaddr h_raddr, pte_addr;
     int ret;
 
     /* Index Process Table by PID to Find Corresponding Process Table Entry */
@@ -266,18 +319,85 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx,
         return 1;
     }
     prtbe_addr = (pate.dw1 & PATE1_R_PRTB) + offset;
-    prtbe0 = ldq_phys(cs->as, prtbe_addr);
+
+    if (cpu->vhyp) {
+        prtbe0 = ldq_phys(cs->as, prtbe_addr);
+    } else {
+        /*
+         * Process table addresses are subject to partition-scoped
+         * translation
+         *
+         * On a Radix host, the partition-scoped page table for LPID=0
+         * is only used to translate the effective addresses of the
+         * process table entries.
+         */
+        ret = ppc_radix64_partition_scoped_xlate(cpu, 0, eaddr, prtbe_addr,
+                                                 pate, &h_raddr, &h_prot,
+                                                 &h_page_size, 1, 1);
+        if (ret) {
+            return ret;
+        }
+        prtbe0 = ldq_phys(cs->as, h_raddr);
+    }
 
     /* Walk Radix Tree from Process Table Entry to Convert EA to RA */
     *g_page_size = PRTBE_R_GET_RTS(prtbe0);
-    ret = ppc_radix64_walk_tree(cs->as, eaddr & R_EADDR_MASK,
-                                prtbe0 & PRTBE_R_RPDB, prtbe0 & PRTBE_R_RPDS,
-                                g_raddr, g_page_size, &pte, &fault_cause,
-                                &pte_addr);
-
-    if (ret ||
-        ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, g_prot, false)) {
-        /* No valid pte or access denied due to protection */
+    base_addr = prtbe0 & PRTBE_R_RPDB;
+    nls = prtbe0 & PRTBE_R_RPDS;
+    if (msr_hv || cpu->vhyp) {
+        /*
+         * Can treat process table addresses as real addresses
+         */
+        ret = ppc_radix64_walk_tree(cs->as, eaddr & R_EADDR_MASK, base_addr,
+                                    nls, g_raddr, g_page_size, &pte,
+                                    &fault_cause, &pte_addr);
+        if (ret) {
+            /* No valid PTE */
+            if (cause_excp) {
+                ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause);
+            }
+            return ret;
+        }
+    } else {
+        uint64_t rpn, mask;
+
+        index = (eaddr & R_EADDR_MASK) >> (*g_page_size - nls); /* Shift */
+        index &= ((1UL << nls) - 1);                            /* Mask */
+        pte_addr = base_addr + (index * sizeof(pte));
+
+        /*
+         * Each process table address is subject to a partition-scoped
+         * translation
+         */
+        do {
+            ret = ppc_radix64_partition_scoped_xlate(cpu, 0, eaddr, pte_addr,
+                                                     pate, &h_raddr, &h_prot,
+                                                     &h_page_size, 1, 1);
+            if (ret) {
+                return ret;
+            }
+
+            ret = ppc_radix64_next_level(cs->as, eaddr & R_EADDR_MASK, &h_raddr,
+                                         &nls, g_page_size, &pte, &fault_cause);
+            if (ret) {
+                /* No valid pte */
+                if (cause_excp) {
+                    ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause);
+                }
+                return ret;
+            }
+            pte_addr = h_raddr;
+        } while (!(pte & R_PTE_LEAF));
+
+        rpn = pte & R_PTE_RPN;
+        mask = (1UL << *g_page_size) - 1;
+
+        /* Or high bits of rpn and low bits to ea to form whole real addr */
+        *g_raddr = (rpn & ~mask) | (eaddr & mask);
+    }
+
+    if (ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, g_prot, false)) {
+        /* Access denied due to protection */
         if (cause_excp) {
             ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause);
         }
@@ -289,11 +409,29 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx,
     return 0;
 }
 
+/*
+ * Radix tree translation is a 2 steps translation process:
+ *
+ * 1. Process-scoped translation:   Guest Eff Addr  -> Guest Real Addr
+ * 2. Partition-scoped translation: Guest Real Addr -> Host Real Addr
+ *
+ *                                  MSR[HV]
+ *              +-------------+----------------+---------------+
+ *              |             |     HV = 0     |     HV = 1    |
+ *              +-------------+----------------+---------------+
+ *              | Relocation  |    Partition   |      No       |
+ *              | = Off       |     Scoped     |  Translation  |
+ *  Relocation  +-------------+----------------+---------------+
+ *              | Relocation  |   Partition &  |    Process    |
+ *              | = On        | Process Scoped |    Scoped     |
+ *              +-------------+----------------+---------------+
+ */
 static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx,
                              bool relocation,
                              hwaddr *raddr, int *psizep, int *protp,
                              bool cause_excp)
 {
+    CPUPPCState *env = &cpu->env;
     uint64_t lpid = 0, pid = 0;
     ppc_v3_pate_t pate;
     int psize, prot;
@@ -325,11 +463,6 @@ static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx,
             }
             return 1;
         }
-        /* We don't support guest mode yet */
-        if (lpid != 0) {
-            error_report("PowerNV guest support Unimplemented");
-            exit(1);
-        }
     }
 
     *psizep = INT_MAX;
@@ -340,6 +473,8 @@ static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx,
      *
      * - Translates an effective address to a host real address in
      *   quadrants 0 and 3 when HV=1.
+     *
+     * - Translates an effective address to a guest real address.
      */
     if (relocation) {
         int ret = ppc_radix64_process_scoped_xlate(cpu, rwx, eaddr, pid,
@@ -354,7 +489,30 @@ static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx,
         g_raddr = eaddr & R_EADDR_MASK;
     }
 
-    *raddr = g_raddr;
+    if (cpu->vhyp) {
+        *raddr = g_raddr;
+    } else {
+        /*
+         * Perform partition-scoped translation if !HV or HV access to
+         * quadrants 1 or 2. Translates a guest real address to a host
+         * real address.
+         */
+        if (lpid || !msr_hv) {
+            int ret;
+
+            ret = ppc_radix64_partition_scoped_xlate(cpu, rwx, eaddr, g_raddr,
+                                                     pate, raddr, &prot, &psize,
+                                                     0, cause_excp);
+            if (ret) {
+                return ret;
+            }
+            *psizep = MIN(*psizep, psize);
+            *protp &= prot;
+        } else {
+            *raddr = g_raddr;
+        }
+    }
+
     return 0;
 }
 
-- 
2.26.2



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

* [PULL 16/18] spapr_nvdimm.c: make 'label-size' mandatory
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (14 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 15/18] target/ppc: Add support for Radix " David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 17/18] spapr_nvdimm: Tweak error messages David Gibson
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, Daniel Henrique Barboza, qemu-devel, npiggin, groug,
	qemu-ppc, clg, David Gibson

From: Daniel Henrique Barboza <danielhb413@gmail.com>

The pseries machine does not support NVDIMM modules without label.
Attempting to do so, even if the overall block size is aligned with
256MB, will seg fault the guest kernel during NVDIMM probe. This
can be avoided by forcing 'label-size' to always be present for
sPAPR NVDIMMs.

The verification was put before the alignment check because the
presence of label-size affects the alignment calculation, so
it's not optimal to warn the user about an alignment error,
then about the lack of label-size, then about a new alignment
error when the user sets a label-size.

Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20200413203628.31636-1-danielhb413@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_nvdimm.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index 25be8082d7..9abcdcc26b 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -37,6 +37,12 @@ void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
     QemuUUID uuid;
     int ret;
 
+    if (object_property_get_int(OBJECT(nvdimm), NVDIMM_LABEL_SIZE_PROP,
+                                &error_abort) == 0) {
+        error_setg(errp, "NVDIMM device requires label-size to be set");
+        return;
+    }
+
     if (size % SPAPR_MINIMUM_SCM_BLOCK_SIZE) {
         error_setg(errp, "NVDIMM memory size excluding the label area"
                    " must be a multiple of %" PRIu64 "MB",
-- 
2.26.2



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

* [PULL 17/18] spapr_nvdimm: Tweak error messages
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (15 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 16/18] spapr_nvdimm.c: make 'label-size' mandatory David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  5:02 ` [PULL 18/18] target-ppc: fix rlwimi, rlwinm, rlwnm for Clang-9 David Gibson
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, David Gibson

The restrictions here (which are checked at pre-plug time) are PAPR
specific, rather than being inherent to the NVDIMM devices.  Adjust the
error messages to be clearer about this.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_nvdimm.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index 9abcdcc26b..81410aa63f 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -39,13 +39,13 @@ void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
 
     if (object_property_get_int(OBJECT(nvdimm), NVDIMM_LABEL_SIZE_PROP,
                                 &error_abort) == 0) {
-        error_setg(errp, "NVDIMM device requires label-size to be set");
+        error_setg(errp, "PAPR requires NVDIMM devices to have label-size set");
         return;
     }
 
     if (size % SPAPR_MINIMUM_SCM_BLOCK_SIZE) {
-        error_setg(errp, "NVDIMM memory size excluding the label area"
-                   " must be a multiple of %" PRIu64 "MB",
+        error_setg(errp, "PAPR requires NVDIMM memory size (excluding label)"
+                   " to be a multiple of %" PRIu64 "MB",
                    SPAPR_MINIMUM_SCM_BLOCK_SIZE / MiB);
         return;
     }
-- 
2.26.2



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

* [PULL 18/18] target-ppc: fix rlwimi, rlwinm, rlwnm for Clang-9
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (16 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 17/18] spapr_nvdimm: Tweak error messages David Gibson
@ 2020-05-07  5:02 ` David Gibson
  2020-05-07  6:00 ` [PULL 00/18] ppc-for-5.1 queue 20200507 no-reply
  2020-05-07 13:29 ` Peter Maydell
  19 siblings, 0 replies; 21+ messages in thread
From: David Gibson @ 2020-05-07  5:02 UTC (permalink / raw)
  To: peter.maydell
  Cc: aik, qemu-devel, npiggin, groug, qemu-ppc, clg, Daniele Buono,
	David Gibson

From: Daniele Buono <dbuono@linux.vnet.ibm.com>

Starting with Clang v9, -Wtype-limits is implemented and triggers a
few "result of comparison is always true" errors when compiling PPC32
targets.

The comparisons seem to be necessary only on PPC64, since the
else branch in PPC32 only has a "g_assert_not_reached();" in all cases.

This patch restructures the code so that the actual if/else is done on a
local flag variable, that is set accordingly for PPC64, and always
true for PPC32.

Signed-off-by: Daniele Buono <dbuono@linux.vnet.ibm.com>
Message-Id: <20200505183818.32688-2-dbuono@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/translate.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 807d14faaa..338529879f 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -1882,6 +1882,7 @@ static void gen_rlwimi(DisasContext *ctx)
         tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
     } else {
         target_ulong mask;
+        bool mask_in_32b = true;
         TCGv t1;
 
 #if defined(TARGET_PPC64)
@@ -1890,8 +1891,13 @@ static void gen_rlwimi(DisasContext *ctx)
 #endif
         mask = MASK(mb, me);
 
+#if defined(TARGET_PPC64)
+        if (mask > 0xffffffffu) {
+            mask_in_32b = false;
+        }
+#endif
         t1 = tcg_temp_new();
-        if (mask <= 0xffffffffu) {
+        if (mask_in_32b) {
             TCGv_i32 t0 = tcg_temp_new_i32();
             tcg_gen_trunc_tl_i32(t0, t_rs);
             tcg_gen_rotli_i32(t0, t0, sh);
@@ -1933,12 +1939,18 @@ static void gen_rlwinm(DisasContext *ctx)
         tcg_gen_extract_tl(t_ra, t_rs, rsh, len);
     } else {
         target_ulong mask;
+        bool mask_in_32b = true;
 #if defined(TARGET_PPC64)
         mb += 32;
         me += 32;
 #endif
         mask = MASK(mb, me);
-        if (mask <= 0xffffffffu) {
+#if defined(TARGET_PPC64)
+        if (mask > 0xffffffffu) {
+            mask_in_32b = false;
+        }
+#endif
+        if (mask_in_32b) {
             if (sh == 0) {
                 tcg_gen_andi_tl(t_ra, t_rs, mask);
             } else {
@@ -1973,6 +1985,7 @@ static void gen_rlwnm(DisasContext *ctx)
     uint32_t mb = MB(ctx->opcode);
     uint32_t me = ME(ctx->opcode);
     target_ulong mask;
+    bool mask_in_32b = true;
 
 #if defined(TARGET_PPC64)
     mb += 32;
@@ -1980,7 +1993,12 @@ static void gen_rlwnm(DisasContext *ctx)
 #endif
     mask = MASK(mb, me);
 
-    if (mask <= 0xffffffffu) {
+#if defined(TARGET_PPC64)
+    if (mask > 0xffffffffu) {
+        mask_in_32b = false;
+    }
+#endif
+    if (mask_in_32b) {
         TCGv_i32 t0 = tcg_temp_new_i32();
         TCGv_i32 t1 = tcg_temp_new_i32();
         tcg_gen_trunc_tl_i32(t0, t_rb);
-- 
2.26.2



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

* Re: [PULL 00/18] ppc-for-5.1 queue 20200507
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (17 preceding siblings ...)
  2020-05-07  5:02 ` [PULL 18/18] target-ppc: fix rlwimi, rlwinm, rlwnm for Clang-9 David Gibson
@ 2020-05-07  6:00 ` no-reply
  2020-05-07 13:29 ` Peter Maydell
  19 siblings, 0 replies; 21+ messages in thread
From: no-reply @ 2020-05-07  6:00 UTC (permalink / raw)
  To: david
  Cc: peter.maydell, aik, qemu-devel, npiggin, groug, qemu-ppc, clg, david

Patchew URL: https://patchew.org/QEMU/20200507050228.802395-1-david@gibson.dropbear.id.au/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20200507050228.802395-1-david@gibson.dropbear.id.au
Subject: [PULL 00/18] ppc-for-5.1 queue 20200507
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
2d7cf2f target-ppc: fix rlwimi, rlwinm, rlwnm for Clang-9
8a40c99 spapr_nvdimm: Tweak error messages
c711884 spapr_nvdimm.c: make 'label-size' mandatory
3b966ed target/ppc: Add support for Radix partition-scoped translation
841c68d target/ppc: Rework ppc_radix64_walk_tree() for partition-scoped translation
a6648da target/ppc: Extend ppc_radix64_check_prot() with a 'partition_scoped' bool
ba64285 target/ppc: Introduce ppc_radix64_xlate() for Radix tree translation
12ffc72 spapr: Don't allow unplug of NVLink2 devices
b807de2 target/ppc: Assert if HV mode is set when running under a pseries machine
b921172 target/ppc: Introduce a relocation bool in ppc_radix64_handle_mmu_fault()
0f1ea37 target/ppc: Enforce that the root page directory size must be at least 5
0265feb spapr: Drop CAS reboot flag
660bb29 spapr/cas: Separate CAS handling from rebuilding the FDT
ae65da6 spapr: Simplify selection of radix/hash during CAS
d9869ed ppc/pnv: Add support for NMI interface
f0ed65a ppc/spapr: tweak change system reset helper
d8a29c1 spapr: Don't check capabilities removed between CAS calls
a1a2597 target/ppc: Improve syscall exception logging

=== OUTPUT BEGIN ===
1/18 Checking commit a1a2597979cf (target/ppc: Improve syscall exception logging)
ERROR: code indent should never use tabs
#42: FILE: target/ppc/excp_helper.c:73:
+^I^I  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64$

ERROR: code indent should never use tabs
#43: FILE: target/ppc/excp_helper.c:74:
+^I^I  " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64$

ERROR: code indent should never use tabs
#44: FILE: target/ppc/excp_helper.c:75:
+^I^I  " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64$

ERROR: code indent should never use tabs
#47: FILE: target/ppc/excp_helper.c:78:
+^I^I  ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6),$

ERROR: code indent should never use tabs
#48: FILE: target/ppc/excp_helper.c:79:
+^I^I  ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),$

ERROR: code indent should never use tabs
#49: FILE: target/ppc/excp_helper.c:80:
+^I^I  ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),$

ERROR: code indent should never use tabs
#50: FILE: target/ppc/excp_helper.c:81:
+^I^I  ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),$

ERROR: code indent should never use tabs
#51: FILE: target/ppc/excp_helper.c:82:
+^I^I  env->nip);$

total: 8 errors, 0 warnings, 47 lines checked

Patch 1/18 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

2/18 Checking commit d8a29c16840a (spapr: Don't check capabilities removed between CAS calls)
3/18 Checking commit f0ed65adc034 (ppc/spapr: tweak change system reset helper)
4/18 Checking commit d9869ed76eb9 (ppc/pnv: Add support for NMI interface)
5/18 Checking commit ae65da61eb6b (spapr: Simplify selection of radix/hash during CAS)
6/18 Checking commit 660bb297151b (spapr/cas: Separate CAS handling from rebuilding the FDT)
7/18 Checking commit 0265febed9dd (spapr: Drop CAS reboot flag)
8/18 Checking commit 0f1ea37bf8e0 (target/ppc: Enforce that the root page directory size must be at least 5)
9/18 Checking commit b92117299180 (target/ppc: Introduce a relocation bool in ppc_radix64_handle_mmu_fault())
10/18 Checking commit b807de27aab6 (target/ppc: Assert if HV mode is set when running under a pseries machine)
11/18 Checking commit 12ffc7216fdb (spapr: Don't allow unplug of NVLink2 devices)
12/18 Checking commit ba64285771b1 (target/ppc: Introduce ppc_radix64_xlate() for Radix tree translation)
13/18 Checking commit a6648da481a2 (target/ppc: Extend ppc_radix64_check_prot() with a 'partition_scoped' bool)
14/18 Checking commit 841c68de3923 (target/ppc: Rework ppc_radix64_walk_tree() for partition-scoped translation)
15/18 Checking commit 3b966ed8381d (target/ppc: Add support for Radix partition-scoped translation)
16/18 Checking commit c7118842415d (spapr_nvdimm.c: make 'label-size' mandatory)
17/18 Checking commit 8a40c9943f6e (spapr_nvdimm: Tweak error messages)
18/18 Checking commit 2d7cf2f3ab64 (target-ppc: fix rlwimi, rlwinm, rlwnm for Clang-9)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20200507050228.802395-1-david@gibson.dropbear.id.au/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [PULL 00/18] ppc-for-5.1 queue 20200507
  2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
                   ` (18 preceding siblings ...)
  2020-05-07  6:00 ` [PULL 00/18] ppc-for-5.1 queue 20200507 no-reply
@ 2020-05-07 13:29 ` Peter Maydell
  19 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2020-05-07 13:29 UTC (permalink / raw)
  To: David Gibson
  Cc: Alexey Kardashevskiy, QEMU Developers, Nicholas Piggin,
	Greg Kurz, qemu-ppc, Cédric Le Goater

On Thu, 7 May 2020 at 06:04, David Gibson <david@gibson.dropbear.id.au> wrote:
>
> The following changes since commit 570a9214827e3d42f7173c4d4c9f045b99834cf0:
>
>   Merge remote-tracking branch 'remotes/alistair/tags/pull-reg-to-apply-20200505' into staging (2020-05-06 15:38:02 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/dgibson/qemu.git tags/ppc-for-5.1-20200507
>
> for you to fetch changes up to c4f6a4a3dd5f2aa15329b8158de25f50b5ba3252:
>
>   target-ppc: fix rlwimi, rlwinm, rlwnm for Clang-9 (2020-05-07 11:10:50 +1000)
>
> ----------------------------------------------------------------
> ppc patch queue for 2020-04-07
>
> First pull request for qemu-5.1.  This includes:
>  * Removal of all remaining cases where we had CAS triggered reboots
>  * A number of improvements to NMI injection
>  * Support for partition scoped radix translation in softmmu
>  * Some fixes for NVDIMM handling
>  * A handful of other minor fixes
>

Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.1
for any user-visible changes.

-- PMM


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

end of thread, other threads:[~2020-05-07 13:31 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-07  5:02 [PULL 00/18] ppc-for-5.1 queue 20200507 David Gibson
2020-05-07  5:02 ` [PULL 01/18] target/ppc: Improve syscall exception logging David Gibson
2020-05-07  5:02 ` [PULL 02/18] spapr: Don't check capabilities removed between CAS calls David Gibson
2020-05-07  5:02 ` [PULL 03/18] ppc/spapr: tweak change system reset helper David Gibson
2020-05-07  5:02 ` [PULL 04/18] ppc/pnv: Add support for NMI interface David Gibson
2020-05-07  5:02 ` [PULL 05/18] spapr: Simplify selection of radix/hash during CAS David Gibson
2020-05-07  5:02 ` [PULL 06/18] spapr/cas: Separate CAS handling from rebuilding the FDT David Gibson
2020-05-07  5:02 ` [PULL 07/18] spapr: Drop CAS reboot flag David Gibson
2020-05-07  5:02 ` [PULL 08/18] target/ppc: Enforce that the root page directory size must be at least 5 David Gibson
2020-05-07  5:02 ` [PULL 09/18] target/ppc: Introduce a relocation bool in ppc_radix64_handle_mmu_fault() David Gibson
2020-05-07  5:02 ` [PULL 10/18] target/ppc: Assert if HV mode is set when running under a pseries machine David Gibson
2020-05-07  5:02 ` [PULL 11/18] spapr: Don't allow unplug of NVLink2 devices David Gibson
2020-05-07  5:02 ` [PULL 12/18] target/ppc: Introduce ppc_radix64_xlate() for Radix tree translation David Gibson
2020-05-07  5:02 ` [PULL 13/18] target/ppc: Extend ppc_radix64_check_prot() with a 'partition_scoped' bool David Gibson
2020-05-07  5:02 ` [PULL 14/18] target/ppc: Rework ppc_radix64_walk_tree() for partition-scoped translation David Gibson
2020-05-07  5:02 ` [PULL 15/18] target/ppc: Add support for Radix " David Gibson
2020-05-07  5:02 ` [PULL 16/18] spapr_nvdimm.c: make 'label-size' mandatory David Gibson
2020-05-07  5:02 ` [PULL 17/18] spapr_nvdimm: Tweak error messages David Gibson
2020-05-07  5:02 ` [PULL 18/18] target-ppc: fix rlwimi, rlwinm, rlwnm for Clang-9 David Gibson
2020-05-07  6:00 ` [PULL 00/18] ppc-for-5.1 queue 20200507 no-reply
2020-05-07 13:29 ` Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).