All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 00/53] ppc-for-4.2 queue 20191004
@ 2019-10-04  9:36 David Gibson
  2019-10-04  9:36 ` [PULL 01/53] pseries: do not allow memory-less/cpu-less NUMA node David Gibson
                   ` (53 more replies)
  0 siblings, 54 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:36 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

The following changes since commit 4f59102571fce49af180cfc6d4cdd2b5df7bdb14:

  Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-oct-01-2019' into staging (2019-10-01 16:21:42 +0100)

are available in the Git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-4.2-20191004

for you to fetch changes up to 1aba8716c8335e88b8c358002a6e1ac89f7dd258:

  ppc/pnv: Remove the XICSFabric Interface from the POWER9 machine (2019-10-04 19:08:23 +1000)

----------------------------------------------------------------
ppc patch queue 2019-10-04

Here's the next batch of ppc and spapr patches.  Includes:
  * Fist part of a large cleanup to irq infrastructure
  * Recreate the full FDT at CAS time, instead of making a difficult
    to follow set of updates.  This will help us move towards
    eliminating CAS reboots altogether
  * No longer provide RTAS blob to SLOF - SLOF can include it just as
    well itself, since guests will generally need to relocate it with
    a call to instantiate-rtas
  * A number of DFP fixes and cleanups from Mark Cave-Ayland
  * Assorted bugfixes
  * Several new small devices for powernv

----------------------------------------------------------------
Alexey Kardashevskiy (8):
      ppc/kvm: Skip writing DPDES back when in run time state
      spapr: Fixes a leak in CAS
      spapr: Skip leading zeroes from memory@ DT node names
      spapr: Do not put empty properties for -kernel/-initrd/-append
      spapr: Stop providing RTAS blob
      pseries: Update SLOF firmware image
      spapr-pci: Stop providing assigned-addresses
      spapr: Render full FDT on ibm,client-architecture-support

Balamuruhan S (4):
      hw/ppc/pnv: fix checkpatch.pl coding style warnings
      hw/ppc/pnv_xscom: retrieve homer/occ base address from PBA BARs
      hw/ppc/pnv_occ: add sram device model for occ common area
      hw/ppc/pnv_homer: add PowerNV homer device model

Cédric Le Goater (5):
      ppc/pnv: fix "bmc" node name in DT
      spapr/irq: Introduce an ics_irq_free() helper
      spapr/irq: Only claim VALID interrupts at the KVM level
      spapr/xive: skip partially initialized vCPUs in presenter
      ppc/pnv: Remove the XICSFabric Interface from the POWER9 machine

David Gibson (22):
      spapr: Simplify handling of pre ISA 3.0 guest workaround handling
      spapr: Move handling of special NVLink numa node from reset to init
      xics: Minor fixes for XICSFabric interface
      xics: Eliminate 'reject', 'resend' and 'eoi' class hooks
      xics: Rename misleading ics_simple_*() functions
      xics: Eliminate reset hook
      xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
      xics: Create sPAPR specific ICS subtype
      spapr: Fold spapr_phb_lsi_qirq() into its single caller
      spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper
      spapr: Clarify and fix handling of nr_irqs
      spapr: Eliminate nr_irqs parameter to SpaprIrq::init
      spapr: Fix indexing of XICS irqs
      spapr: Simplify spapr_qirq() handling
      spapr: Eliminate SpaprIrq:get_nodename method
      spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()
      spapr: Handle freeing of multiple irqs in frontend only
      spapr, xics, xive: Better use of assert()s on irq claim/free paths
      xive: Improve irq claim/free path
      spapr: Use less cryptic representation of which irq backends are supported
      spapr: Add return value to spapr_irq_check()
      spapr: Eliminate SpaprIrq::init hook

Greg Kurz (2):
      spapr-tpm-proxy: Drop misleading check
      spapr: Report kvm_irqchip_in_kernel() in 'info pic'

Laurent Vivier (1):
      pseries: do not allow memory-less/cpu-less NUMA node

Mark Cave-Ayland (8):
      target/ppc: introduce get_dfp{64,128}() helper functions
      target/ppc: introduce set_dfp{64,128}() helper functions
      target/ppc: update {get,set}_dfp{64,128}() helper functions to read/write DFP numbers correctly
      target/ppc: introduce dfp_finalize_decimal{64,128}() helper functions
      target/ppc: change struct PPC_DFP decimal storage from uint64[2] to ppc_vsr_t
      target/ppc: use existing VsrD() macro to eliminate HI_IDX and LO_IDX from dfp_helper.c
      target/ppc: remove unnecessary if() around calls to set_dfp{64,128}() in DFP macros
      target/ppc: use Vsr macros in BCD helpers

Paul A. Clarke (3):
      ppc: Add support for 'mffscrn','mffscrni' instructions
      ppc: Add support for 'mffsce' instruction
      ppc: Use FPSCR defines instead of constants

 MAINTAINERS                        |   2 -
 Makefile                           |   2 +-
 configure                          |   6 +-
 hw/char/spapr_vty.c                |   3 +-
 hw/intc/spapr_xive.c               |  26 +--
 hw/intc/spapr_xive_kvm.c           |  48 ++++-
 hw/intc/trace-events               |  10 +-
 hw/intc/xics.c                     | 210 +++++++-------------
 hw/intc/xics_kvm.c                 |   8 +
 hw/intc/xics_spapr.c               |  48 ++++-
 hw/intc/xive.c                     |   8 +
 hw/net/spapr_llan.c                |   3 +-
 hw/ppc/Makefile.objs               |   1 +
 hw/ppc/pnv.c                       | 118 +++++++----
 hw/ppc/pnv_bmc.c                   |   5 +-
 hw/ppc/pnv_homer.c                 | 272 +++++++++++++++++++++++++
 hw/ppc/pnv_occ.c                   |  78 ++++++++
 hw/ppc/pnv_psi.c                   |   6 +-
 hw/ppc/pnv_xscom.c                 |  34 +++-
 hw/ppc/spapr.c                     | 219 ++++++++-------------
 hw/ppc/spapr_hcall.c               |   9 +-
 hw/ppc/spapr_irq.c                 | 345 +++++++++++++-------------------
 hw/ppc/spapr_pci.c                 |  45 +----
 hw/ppc/spapr_rtas.c                |  41 ----
 hw/ppc/spapr_tpm_proxy.c           |   2 +-
 hw/ppc/spapr_vio.c                 |   3 +-
 hw/ppc/trace-events                |   4 -
 include/hw/pci-host/spapr.h        |   7 -
 include/hw/ppc/pnv.h               |  21 ++
 include/hw/ppc/pnv_homer.h         |  53 +++++
 include/hw/ppc/pnv_occ.h           |   3 +
 include/hw/ppc/spapr.h             |   4 +-
 include/hw/ppc/spapr_irq.h         |  27 +--
 include/hw/ppc/spapr_vio.h         |   5 +-
 include/hw/ppc/spapr_xive.h        |   4 +-
 include/hw/ppc/xics.h              |  38 ++--
 include/hw/ppc/xics_spapr.h        |   4 +-
 include/hw/ppc/xive.h              |   2 +-
 pc-bios/README                     |   2 +-
 pc-bios/slof.bin                   | Bin 930656 -> 930640 bytes
 pc-bios/spapr-rtas.bin             | Bin 20 -> 0 bytes
 pc-bios/spapr-rtas/Makefile        |  27 ---
 pc-bios/spapr-rtas/spapr-rtas.S    |  37 ----
 roms/SLOF                          |   2 +-
 target/ppc/cpu.h                   |  10 +-
 target/ppc/dfp_helper.c            | 394 ++++++++++++++++++-------------------
 target/ppc/fpu_helper.c            | 122 ++++++------
 target/ppc/helper.h                |   2 +-
 target/ppc/int_helper.c            |  72 +++----
 target/ppc/internal.h              |   3 +
 target/ppc/kvm.c                   |   5 +
 target/ppc/translate/fp-impl.inc.c |  99 +++++++++-
 target/ppc/translate/fp-ops.inc.c  |   6 +
 target/ppc/translate_init.inc.c    |   9 +-
 54 files changed, 1421 insertions(+), 1093 deletions(-)
 create mode 100644 hw/ppc/pnv_homer.c
 create mode 100644 include/hw/ppc/pnv_homer.h
 delete mode 100644 pc-bios/spapr-rtas.bin
 delete mode 100644 pc-bios/spapr-rtas/Makefile
 delete mode 100644 pc-bios/spapr-rtas/spapr-rtas.S


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

* [PULL 01/53] pseries: do not allow memory-less/cpu-less NUMA node
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
@ 2019-10-04  9:36 ` David Gibson
  2019-10-04  9:36 ` [PULL 02/53] ppc/pnv: fix "bmc" node name in DT David Gibson
                   ` (52 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:36 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Laurent Vivier <lvivier@redhat.com>

When we hotplug a CPU on memory-less/cpu-less node, the linux kernel
crashes.

This happens because linux kernel needs to know the NUMA topology at
start to be able to initialize the distance lookup table.

On pseries, the topology is provided by the firmware via the existing
CPUs and memory information. Thus a node without memory and CPU cannot be
discovered by the kernel.

To avoid the kernel crash, do not allow to start pseries with empty
nodes.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Message-Id: <20190830161345.22436-1-lvivier@redhat.com>
[dwg: Rework to cope with movement of numa state from globals to MachineState]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 08a2a5a770..f976d76eca 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2854,6 +2854,39 @@ static void spapr_machine_init(MachineState *machine)
     /* init CPUs */
     spapr_init_cpus(spapr);
 
+    /*
+     * check we don't have a memory-less/cpu-less NUMA node
+     * Firmware relies on the existing memory/cpu topology to provide the
+     * NUMA topology to the kernel.
+     * And the linux kernel needs to know the NUMA topology at start
+     * to be able to hotplug CPUs later.
+     */
+    if (machine->numa_state->num_nodes) {
+        for (i = 0; i < machine->numa_state->num_nodes; ++i) {
+            /* check for memory-less node */
+            if (machine->numa_state->nodes[i].node_mem == 0) {
+                CPUState *cs;
+                int found = 0;
+                /* check for cpu-less node */
+                CPU_FOREACH(cs) {
+                    PowerPCCPU *cpu = POWERPC_CPU(cs);
+                    if (cpu->node_id == i) {
+                        found = 1;
+                        break;
+                    }
+                }
+                /* memory-less and cpu-less node */
+                if (!found) {
+                    error_report(
+                       "Memory-less/cpu-less nodes are not supported (node %d)",
+                                 i);
+                    exit(1);
+                }
+            }
+        }
+
+    }
+
     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)) {
-- 
2.21.0



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

* [PULL 02/53] ppc/pnv: fix "bmc" node name in DT
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
  2019-10-04  9:36 ` [PULL 01/53] pseries: do not allow memory-less/cpu-less NUMA node David Gibson
@ 2019-10-04  9:36 ` David Gibson
  2019-10-04  9:36 ` [PULL 03/53] spapr-tpm-proxy: Drop misleading check David Gibson
                   ` (51 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:36 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

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

Fixes the dtc output :

ERROR (node_name_chars): //bmc: Bad character '/' in node name
Warning (avoid_unnecessary_addr_size): /bmc: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20190902092932.20200-1-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv_bmc.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index e5eb6e5a70..dc5e918cb7 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -77,13 +77,10 @@ void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt)
     const struct ipmi_sdr_compact *sdr;
     uint16_t nextrec;
 
-    offset = fdt_add_subnode(fdt, 0, "/bmc");
+    offset = fdt_add_subnode(fdt, 0, "bmc");
     _FDT(offset);
 
     _FDT((fdt_setprop_string(fdt, offset, "name", "bmc")));
-    _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0x1)));
-    _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 0x0)));
-
     offset = fdt_add_subnode(fdt, offset, "sensors");
     _FDT(offset);
 
-- 
2.21.0



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

* [PULL 03/53] spapr-tpm-proxy: Drop misleading check
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
  2019-10-04  9:36 ` [PULL 01/53] pseries: do not allow memory-less/cpu-less NUMA node David Gibson
  2019-10-04  9:36 ` [PULL 02/53] ppc/pnv: fix "bmc" node name in DT David Gibson
@ 2019-10-04  9:36 ` David Gibson
  2019-10-04  9:36 ` [PULL 04/53] hw/ppc/pnv: fix checkpatch.pl coding style warnings David Gibson
                   ` (50 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:36 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, Michael Roth, aik, qemu-devel, groug, qemu-ppc, clg,
	David Gibson

From: Greg Kurz <groug@kaod.org>

Coverity is reporting in CID 1405304 that tpm_execute() may pass a NULL
tpm_proxy->host_path pointer to open(). This is based on the fact that
h_tpm_comm() does a NULL check on tpm_proxy->host_path and then passes
tpm_proxy to tpm_execute().

The check in h_tpm_comm() is abusive actually since a spapr-proxy-tpm
requires a non NULL host_path property, as checked during realize.

Fixes: 0fb6bd073230
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <156805260916.1779401.11054185183758185247.stgit@bahia.lan>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_tpm_proxy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_tpm_proxy.c b/hw/ppc/spapr_tpm_proxy.c
index b835d25be6..ca1caec113 100644
--- a/hw/ppc/spapr_tpm_proxy.c
+++ b/hw/ppc/spapr_tpm_proxy.c
@@ -114,7 +114,7 @@ static target_ulong h_tpm_comm(PowerPCCPU *cpu,
         return H_FUNCTION;
     }
 
-    trace_spapr_h_tpm_comm(tpm_proxy->host_path ?: "null", op);
+    trace_spapr_h_tpm_comm(tpm_proxy->host_path, op);
 
     switch (op) {
     case TPM_COMM_OP_EXECUTE:
-- 
2.21.0



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

* [PULL 04/53] hw/ppc/pnv: fix checkpatch.pl coding style warnings
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (2 preceding siblings ...)
  2019-10-04  9:36 ` [PULL 03/53] spapr-tpm-proxy: Drop misleading check David Gibson
@ 2019-10-04  9:36 ` David Gibson
  2019-10-04  9:36 ` [PULL 05/53] spapr: Report kvm_irqchip_in_kernel() in 'info pic' David Gibson
                   ` (49 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:36 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, Balamuruhan S,
	David Gibson

From: Balamuruhan S <bala24@linux.ibm.com>

There were few trailing comments after `/*` instead in
new line and line more than 80 character, these fixes are
trivial and doesn't change any logic in code.

Signed-off-by: Balamuruhan S <bala24@linux.ibm.com>
Message-Id: <20190911142925.19197-5-bala24@linux.ibm.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c | 49 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 32 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 3f08db7b9e..13126d675e 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -187,7 +187,8 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
 
     _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq)));
     _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq)));
-    _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", cpu->hash64_opts->slb_size)));
+    _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size",
+                           cpu->hash64_opts->slb_size)));
     _FDT((fdt_setprop_string(fdt, offset, "status", "okay")));
     _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0)));
 
@@ -200,19 +201,23 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
                            segs, sizeof(segs))));
     }
 
-    /* Advertise VMX/VSX (vector extensions) if available
+    /*
+     * Advertise VMX/VSX (vector extensions) if available
      *   0 / no property == no vector extensions
      *   1               == VMX / Altivec available
-     *   2               == VSX available */
+     *   2               == VSX available
+     */
     if (env->insns_flags & PPC_ALTIVEC) {
         uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
 
         _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));
     }
 
-    /* Advertise DFP (Decimal Floating Point) if available
+    /*
+     * Advertise DFP (Decimal Floating Point) if available
      *   0 / no property == no DFP
-     *   1               == DFP available */
+     *   1               == DFP available
+     */
     if (env->insns_flags2 & PPC2_DFP) {
         _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
     }
@@ -424,7 +429,8 @@ static int pnv_dt_isa_device(DeviceState *dev, void *opaque)
     return 0;
 }
 
-/* The default LPC bus of a multichip system is on chip 0. It's
+/*
+ * The default LPC bus of a multichip system is on chip 0. It's
  * recognized by the firmware (skiboot) using a "primary" property.
  */
 static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
@@ -442,8 +448,10 @@ static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
     assert(phandle > 0);
     _FDT((fdt_setprop_cell(fdt, isa_offset, "phandle", phandle)));
 
-    /* ISA devices are not necessarily parented to the ISA bus so we
-     * can not use object_child_foreach() */
+    /*
+     * ISA devices are not necessarily parented to the ISA bus so we
+     * can not use object_child_foreach()
+     */
     qbus_walk_children(BUS(pnv->isa_bus), pnv_dt_isa_device, NULL, NULL, NULL,
                        &args);
 }
@@ -545,7 +553,8 @@ static void pnv_reset(MachineState *machine)
 
     qemu_devices_reset();
 
-    /* OpenPOWER systems have a BMC, which can be defined on the
+    /*
+     * OpenPOWER systems have a BMC, which can be defined on the
      * command line with:
      *
      *   -device ipmi-bmc-sim,id=bmc0
@@ -705,7 +714,8 @@ static void pnv_init(MachineState *machine)
 
         pnv->chips[i] = PNV_CHIP(chip);
 
-        /* TODO: put all the memory in one node on chip 0 until we find a
+        /*
+         * TODO: put all the memory in one node on chip 0 until we find a
          * way to specify different ranges for each chip
          */
         if (i == 0) {
@@ -732,8 +742,10 @@ static void pnv_init(MachineState *machine)
     /* Create an RTC ISA device too */
     mc146818_rtc_init(pnv->isa_bus, 2000, NULL);
 
-    /* OpenPOWER systems use a IPMI SEL Event message to notify the
-     * host to powerdown */
+    /*
+     * OpenPOWER systems use a IPMI SEL Event message to notify the
+     * host to powerdown
+     */
     pnv->powerdown_notifier.notify = pnv_powerdown_notify;
     qemu_register_powerdown_notifier(&pnv->powerdown_notifier);
 }
@@ -803,7 +815,8 @@ static void pnv_chip_power9_intc_create(PnvChip *chip, PowerPCCPU *cpu,
     pnv_cpu->intc = obj;
 }
 
-/* Allowed core identifiers on a POWER8 Processor Chip :
+/*
+ * Allowed core identifiers on a POWER8 Processor Chip :
  *
  * <EX0 reserved>
  *  EX1  - Venice only
@@ -923,8 +936,10 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
                                             (uint64_t) PNV_XSCOM_BASE(chip),
                                             PNV_XSCOM_LPC_BASE);
 
-    /* Interrupt Management Area. This is the memory region holding
-     * all the Interrupt Control Presenter (ICP) registers */
+    /*
+     * Interrupt Management Area. This is the memory region holding
+     * all the Interrupt Control Presenter (ICP) registers
+     */
     pnv_chip_icp_realize(chip8, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -1404,8 +1419,8 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
     mc->init = pnv_init;
     mc->reset = pnv_reset;
     mc->max_cpus = MAX_CPUS;
-    mc->block_default_type = IF_IDE; /* Pnv provides a AHCI device for
-                                      * storage */
+    /* Pnv provides a AHCI device for storage */
+    mc->block_default_type = IF_IDE;
     mc->no_parallel = 1;
     mc->default_boot_order = NULL;
     /*
-- 
2.21.0



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

* [PULL 05/53] spapr: Report kvm_irqchip_in_kernel() in 'info pic'
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (3 preceding siblings ...)
  2019-10-04  9:36 ` [PULL 04/53] hw/ppc/pnv: fix checkpatch.pl coding style warnings David Gibson
@ 2019-10-04  9:36 ` David Gibson
  2019-10-04  9:37 ` [PULL 06/53] hw/ppc/pnv_xscom: retrieve homer/occ base address from PBA BARs David Gibson
                   ` (48 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:36 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

Unless the machine was started with kernel-irqchip=on, we cannot easily
tell if we're actually using an in-kernel or an emulated irqchip. This
information is important enough that it is worth printing it in 'info
pic'.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <156829860985.2073005.5893493824873412773.stgit@bahia.tls.ibm.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f976d76eca..2725b139a7 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -81,6 +81,8 @@
 #include "hw/mem/memory-device.h"
 #include "hw/ppc/spapr_tpm_proxy.h"
 
+#include "monitor/monitor.h"
+
 #include <libfdt.h>
 
 /* SLOF memory layout:
@@ -4354,6 +4356,8 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj,
     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
 
     spapr->irq->print_info(spapr, mon);
+    monitor_printf(mon, "irqchip: %s\n",
+                   kvm_irqchip_in_kernel() ? "in-kernel" : "emulated");
 }
 
 int spapr_get_vcpu_id(PowerPCCPU *cpu)
-- 
2.21.0



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

* [PULL 06/53] hw/ppc/pnv_xscom: retrieve homer/occ base address from PBA BARs
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (4 preceding siblings ...)
  2019-10-04  9:36 ` [PULL 05/53] spapr: Report kvm_irqchip_in_kernel() in 'info pic' David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 07/53] hw/ppc/pnv_occ: add sram device model for occ common area David Gibson
                   ` (47 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, Balamuruhan S,
	David Gibson

From: Balamuruhan S <bala24@linux.ibm.com>

During PowerNV boot skiboot populates the device tree by
retrieving base address of homer/occ common area from
PBA BARs and prd ipoll mask by accessing xscom read/write
accesses.

Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Balamuruhan S <bala24@linux.ibm.com>
Message-Id: <20190912093056.4516-2-bala24@linux.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv_xscom.c   | 34 ++++++++++++++++++++++++++++++----
 include/hw/ppc/pnv.h | 18 ++++++++++++++++++
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index 67aab98fef..f01d788a65 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -36,6 +36,16 @@
 #define PRD_P9_IPOLL_REG_MASK           0x000F0033
 #define PRD_P9_IPOLL_REG_STATUS         0x000F0034
 
+/* PBA BARs */
+#define P8_PBA_BAR0                     0x2013f00
+#define P8_PBA_BAR2                     0x2013f02
+#define P8_PBA_BARMASK0                 0x2013f04
+#define P8_PBA_BARMASK2                 0x2013f06
+#define P9_PBA_BAR0                     0x5012b00
+#define P9_PBA_BAR2                     0x5012b02
+#define P9_PBA_BARMASK0                 0x5012b04
+#define P9_PBA_BARMASK2                 0x5012b06
+
 static void xscom_complete(CPUState *cs, uint64_t hmer_bits)
 {
     /*
@@ -74,6 +84,26 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
     case 0x18002:       /* ECID2 */
         return 0;
 
+    case P9_PBA_BAR0:
+        return PNV9_HOMER_BASE(chip);
+    case P8_PBA_BAR0:
+        return PNV_HOMER_BASE(chip);
+
+    case P9_PBA_BARMASK0: /* P9 homer region size */
+        return PNV9_HOMER_SIZE;
+    case P8_PBA_BARMASK0: /* P8 homer region size */
+        return PNV_HOMER_SIZE;
+
+    case P9_PBA_BAR2: /* P9 occ common area */
+        return PNV9_OCC_COMMON_AREA(chip);
+    case P8_PBA_BAR2: /* P8 occ common area */
+        return PNV_OCC_COMMON_AREA(chip);
+
+    case P9_PBA_BARMASK2: /* P9 occ common area size */
+        return PNV9_OCC_COMMON_AREA_SIZE;
+    case P8_PBA_BARMASK2: /* P8 occ common area size */
+        return PNV_OCC_COMMON_AREA_SIZE;
+
     case 0x1010c00:     /* PIBAM FIR */
     case 0x1010c03:     /* PIBAM FIR MASK */
 
@@ -93,13 +123,9 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
     case 0x2020009:     /* ADU stuff, error register */
     case 0x202000f:     /* ADU stuff, receive status register*/
         return 0;
-    case 0x2013f00:     /* PBA stuff */
     case 0x2013f01:     /* PBA stuff */
-    case 0x2013f02:     /* PBA stuff */
     case 0x2013f03:     /* PBA stuff */
-    case 0x2013f04:     /* PBA stuff */
     case 0x2013f05:     /* PBA stuff */
-    case 0x2013f06:     /* PBA stuff */
     case 0x2013f07:     /* PBA stuff */
         return 0;
     case 0x2013028:     /* CAPP stuff */
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index fb123edc4e..63a4b7b6a7 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -198,6 +198,16 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
 #define PNV_XSCOM_BASE(chip)                                            \
     (0x0003fc0000000000ull + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE)
 
+#define PNV_OCC_COMMON_AREA_SIZE    0x0000000000700000ull
+#define PNV_OCC_COMMON_AREA(chip)                                       \
+    (0x7fff800000ull + ((uint64_t)PNV_CHIP_INDEX(chip) * \
+                         PNV_OCC_COMMON_AREA_SIZE))
+
+#define PNV_HOMER_SIZE              0x0000000000300000ull
+#define PNV_HOMER_BASE(chip)                                            \
+    (0x7ffd800000ull + ((uint64_t)PNV_CHIP_INDEX(chip)) * PNV_HOMER_SIZE)
+
+
 /*
  * XSCOM 0x20109CA defines the ICP BAR:
  *
@@ -256,4 +266,12 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
 #define PNV9_XSCOM_SIZE              0x0000000400000000ull
 #define PNV9_XSCOM_BASE(chip)        PNV9_CHIP_BASE(chip, 0x00603fc00000000ull)
 
+#define PNV9_OCC_COMMON_AREA_SIZE    0x0000000000700000ull
+#define PNV9_OCC_COMMON_AREA(chip)                                      \
+    (0x203fff800000ull + ((uint64_t)PNV_CHIP_INDEX(chip) * \
+                           PNV9_OCC_COMMON_AREA_SIZE))
+
+#define PNV9_HOMER_SIZE              0x0000000000300000ull
+#define PNV9_HOMER_BASE(chip)                                           \
+    (0x203ffd800000ull + ((uint64_t)PNV_CHIP_INDEX(chip)) * PNV9_HOMER_SIZE)
 #endif /* PPC_PNV_H */
-- 
2.21.0



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

* [PULL 07/53] hw/ppc/pnv_occ: add sram device model for occ common area
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (5 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 06/53] hw/ppc/pnv_xscom: retrieve homer/occ base address from PBA BARs David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 08/53] hw/ppc/pnv_homer: add PowerNV homer device model David Gibson
                   ` (46 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, Balamuruhan S,
	David Gibson

From: Balamuruhan S <bala24@linux.ibm.com>

emulate occ common area region with occ sram device model which
occ and skiboot uses it to communicate regarding sensors, slw
and HWMON in PowerNV emulated host.

Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Balamuruhan S <bala24@linux.ibm.com>
Message-Id: <20190912093056.4516-3-bala24@linux.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c             |  8 +++++
 hw/ppc/pnv_occ.c         | 78 ++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/pnv_occ.h |  3 ++
 3 files changed, 89 insertions(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 13126d675e..09d2d7c026 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -953,6 +953,10 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
         return;
     }
     pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip8->occ.xscom_regs);
+
+    /* OCC SRAM model */
+    memory_region_add_subregion(get_system_memory(), PNV_OCC_COMMON_AREA(chip),
+                                &chip8->occ.sram_regs);
 }
 
 static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
@@ -1141,6 +1145,10 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
         return;
     }
     pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
+
+    /* OCC SRAM model */
+    memory_region_add_subregion(get_system_memory(), PNV9_OCC_COMMON_AREA(chip),
+                                &chip9->occ.sram_regs);
 }
 
 static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
index 8bead2c930..785653bb67 100644
--- a/hw/ppc/pnv_occ.c
+++ b/hw/ppc/pnv_occ.c
@@ -30,6 +30,24 @@
 #define OCB_OCI_OCCMISC_AND     0x4021
 #define OCB_OCI_OCCMISC_OR      0x4022
 
+/* OCC sensors */
+#define OCC_SENSOR_DATA_BLOCK_OFFSET          0x580000
+#define OCC_SENSOR_DATA_VALID                 0x580001
+#define OCC_SENSOR_DATA_VERSION               0x580002
+#define OCC_SENSOR_DATA_READING_VERSION       0x580004
+#define OCC_SENSOR_DATA_NR_SENSORS            0x580008
+#define OCC_SENSOR_DATA_NAMES_OFFSET          0x580010
+#define OCC_SENSOR_DATA_READING_PING_OFFSET   0x580014
+#define OCC_SENSOR_DATA_READING_PONG_OFFSET   0x58000c
+#define OCC_SENSOR_DATA_NAME_LENGTH           0x58000d
+#define OCC_SENSOR_NAME_STRUCTURE_TYPE        0x580023
+#define OCC_SENSOR_LOC_CORE                   0x580022
+#define OCC_SENSOR_LOC_GPU                    0x580020
+#define OCC_SENSOR_TYPE_POWER                 0x580003
+#define OCC_SENSOR_NAME                       0x580005
+#define HWMON_SENSORS_MASK                    0x58001e
+#define SLW_IMAGE_BASE                        0x0
+
 static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
 {
     bool irq_state;
@@ -82,6 +100,48 @@ static void pnv_occ_power8_xscom_write(void *opaque, hwaddr addr,
     }
 }
 
+static uint64_t pnv_occ_common_area_read(void *opaque, hwaddr addr,
+                                         unsigned width)
+{
+    switch (addr) {
+    /*
+     * occ-sensor sanity check that asserts the sensor
+     * header block
+     */
+    case OCC_SENSOR_DATA_BLOCK_OFFSET:
+    case OCC_SENSOR_DATA_VALID:
+    case OCC_SENSOR_DATA_VERSION:
+    case OCC_SENSOR_DATA_READING_VERSION:
+    case OCC_SENSOR_DATA_NR_SENSORS:
+    case OCC_SENSOR_DATA_NAMES_OFFSET:
+    case OCC_SENSOR_DATA_READING_PING_OFFSET:
+    case OCC_SENSOR_DATA_READING_PONG_OFFSET:
+    case OCC_SENSOR_NAME_STRUCTURE_TYPE:
+        return 1;
+    case OCC_SENSOR_DATA_NAME_LENGTH:
+        return 0x30;
+    case OCC_SENSOR_LOC_CORE:
+        return 0x0040;
+    case OCC_SENSOR_TYPE_POWER:
+        return 0x0080;
+    case OCC_SENSOR_NAME:
+        return 0x1000;
+    case HWMON_SENSORS_MASK:
+    case OCC_SENSOR_LOC_GPU:
+        return 0x8e00;
+    case SLW_IMAGE_BASE:
+        return 0x1000000000000000;
+    }
+    return 0;
+}
+
+static void pnv_occ_common_area_write(void *opaque, hwaddr addr,
+                                             uint64_t val, unsigned width)
+{
+    /* callback function defined to occ common area write */
+    return;
+}
+
 static const MemoryRegionOps pnv_occ_power8_xscom_ops = {
     .read = pnv_occ_power8_xscom_read,
     .write = pnv_occ_power8_xscom_write,
@@ -92,12 +152,24 @@ static const MemoryRegionOps pnv_occ_power8_xscom_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
+const MemoryRegionOps pnv_occ_sram_ops = {
+    .read = pnv_occ_common_area_read,
+    .write = pnv_occ_common_area_write,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 8,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 8,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
 static void pnv_occ_power8_class_init(ObjectClass *klass, void *data)
 {
     PnvOCCClass *poc = PNV_OCC_CLASS(klass);
 
     poc->xscom_size = PNV_XSCOM_OCC_SIZE;
+    poc->sram_size = PNV_OCC_COMMON_AREA_SIZE;
     poc->xscom_ops = &pnv_occ_power8_xscom_ops;
+    poc->sram_ops = &pnv_occ_sram_ops;
     poc->psi_irq = PSIHB_IRQ_OCC;
 }
 
@@ -168,7 +240,9 @@ static void pnv_occ_power9_class_init(ObjectClass *klass, void *data)
     PnvOCCClass *poc = PNV_OCC_CLASS(klass);
 
     poc->xscom_size = PNV9_XSCOM_OCC_SIZE;
+    poc->sram_size = PNV9_OCC_COMMON_AREA_SIZE;
     poc->xscom_ops = &pnv_occ_power9_xscom_ops;
+    poc->sram_ops = &pnv_occ_sram_ops;
     poc->psi_irq = PSIHB9_IRQ_OCC;
 }
 
@@ -199,6 +273,10 @@ static void pnv_occ_realize(DeviceState *dev, Error **errp)
     /* XScom region for OCC registers */
     pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), poc->xscom_ops,
                           occ, "xscom-occ", poc->xscom_size);
+
+    /* XScom region for OCC SRAM registers */
+    pnv_xscom_region_init(&occ->sram_regs, OBJECT(dev), poc->sram_ops,
+                          occ, "occ-common-area", poc->sram_size);
 }
 
 static void pnv_occ_class_init(ObjectClass *klass, void *data)
diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h
index ed0709bfc0..66b0989be6 100644
--- a/include/hw/ppc/pnv_occ.h
+++ b/include/hw/ppc/pnv_occ.h
@@ -38,6 +38,7 @@ typedef struct PnvOCC {
     PnvPsi *psi;
 
     MemoryRegion xscom_regs;
+    MemoryRegion sram_regs;
 } PnvOCC;
 
 #define PNV_OCC_CLASS(klass) \
@@ -49,7 +50,9 @@ typedef struct PnvOCCClass {
     DeviceClass parent_class;
 
     int xscom_size;
+    int sram_size;
     const MemoryRegionOps *xscom_ops;
+    const MemoryRegionOps *sram_ops;
     int psi_irq;
 } PnvOCCClass;
 
-- 
2.21.0



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

* [PULL 08/53] hw/ppc/pnv_homer: add PowerNV homer device model
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (6 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 07/53] hw/ppc/pnv_occ: add sram device model for occ common area David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 09/53] spapr/irq: Introduce an ics_irq_free() helper David Gibson
                   ` (45 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, Balamuruhan S,
	David Gibson

From: Balamuruhan S <bala24@linux.ibm.com>

add PnvHomer device model to emulate homer memory access
for pstate table, occ-sensors, slw, occ static and dynamic
values for Power8 and Power9 chips.

Signed-off-by: Balamuruhan S <bala24@linux.ibm.com>
Message-Id: <20190912093056.4516-4-bala24@linux.ibm.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/Makefile.objs       |   1 +
 hw/ppc/pnv.c               |  30 ++++
 hw/ppc/pnv_homer.c         | 272 +++++++++++++++++++++++++++++++++++++
 include/hw/ppc/pnv.h       |   3 +
 include/hw/ppc/pnv_homer.h |  53 ++++++++
 5 files changed, 359 insertions(+)
 create mode 100644 hw/ppc/pnv_homer.c
 create mode 100644 include/hw/ppc/pnv_homer.h

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 2c4e1c8de0..580bb4f0dd 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -9,6 +9,7 @@ obj-$(CONFIG_PSERIES) += spapr_tpm_proxy.o
 obj-$(CONFIG_SPAPR_RNG) +=  spapr_rng.o
 # IBM PowerNV
 obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o pnv_psi.o pnv_occ.o pnv_bmc.o
+obj-$(CONFIG_POWERNV) += pnv_homer.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o spapr_pci_nvlink2.o
 endif
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 09d2d7c026..77a86c6a23 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -860,6 +860,11 @@ static void pnv_chip_power8_instance_init(Object *obj)
                             TYPE_PNV8_OCC, &error_abort, NULL);
     object_property_add_const_link(OBJECT(&chip8->occ), "psi",
                                    OBJECT(&chip8->psi), &error_abort);
+
+    object_initialize_child(obj, "homer",  &chip8->homer, sizeof(chip8->homer),
+                            TYPE_PNV8_HOMER, &error_abort, NULL);
+    object_property_add_const_link(OBJECT(&chip8->homer), "chip", obj,
+                                   &error_abort);
 }
 
 static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp)
@@ -957,6 +962,16 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
     /* OCC SRAM model */
     memory_region_add_subregion(get_system_memory(), PNV_OCC_COMMON_AREA(chip),
                                 &chip8->occ.sram_regs);
+
+    /* HOMER */
+    object_property_set_bool(OBJECT(&chip8->homer), true, "realized",
+                             &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(), PNV_HOMER_BASE(chip),
+                                &chip8->homer.regs);
 }
 
 static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
@@ -1039,6 +1054,11 @@ static void pnv_chip_power9_instance_init(Object *obj)
                             TYPE_PNV9_OCC, &error_abort, NULL);
     object_property_add_const_link(OBJECT(&chip9->occ), "psi",
                                    OBJECT(&chip9->psi), &error_abort);
+
+    object_initialize_child(obj, "homer",  &chip9->homer, sizeof(chip9->homer),
+                            TYPE_PNV9_HOMER, &error_abort, NULL);
+    object_property_add_const_link(OBJECT(&chip9->homer), "chip", obj,
+                                   &error_abort);
 }
 
 static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp)
@@ -1149,6 +1169,16 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
     /* OCC SRAM model */
     memory_region_add_subregion(get_system_memory(), PNV9_OCC_COMMON_AREA(chip),
                                 &chip9->occ.sram_regs);
+
+    /* HOMER */
+    object_property_set_bool(OBJECT(&chip9->homer), true, "realized",
+                             &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(), PNV9_HOMER_BASE(chip),
+                                &chip9->homer.regs);
 }
 
 static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c
new file mode 100644
index 0000000000..cc881a3b32
--- /dev/null
+++ b/hw/ppc/pnv_homer.c
@@ -0,0 +1,272 @@
+/*
+ * QEMU PowerPC PowerNV Emulation of a few HOMER related registers
+ *
+ * Copyright (c) 2019, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "exec/hwaddr.h"
+#include "exec/memory.h"
+#include "sysemu/cpus.h"
+#include "hw/qdev-core.h"
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_homer.h"
+
+
+static bool core_max_array(PnvHomer *homer, hwaddr addr)
+{
+    int i;
+    PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer);
+
+    for (i = 0; i <= homer->chip->nr_cores; i++) {
+        if (addr == (hmrc->core_max_base + i)) {
+            return true;
+       }
+    }
+    return false;
+}
+
+/* P8 Pstate table */
+
+#define PNV8_OCC_PSTATE_VERSION          0x1f8001
+#define PNV8_OCC_PSTATE_MIN              0x1f8003
+#define PNV8_OCC_PSTATE_VALID            0x1f8000
+#define PNV8_OCC_PSTATE_THROTTLE         0x1f8002
+#define PNV8_OCC_PSTATE_NOM              0x1f8004
+#define PNV8_OCC_PSTATE_TURBO            0x1f8005
+#define PNV8_OCC_PSTATE_ULTRA_TURBO      0x1f8006
+#define PNV8_OCC_PSTATE_DATA             0x1f8008
+#define PNV8_OCC_PSTATE_ID_ZERO          0x1f8010
+#define PNV8_OCC_PSTATE_ID_ONE           0x1f8018
+#define PNV8_OCC_PSTATE_ID_TWO           0x1f8020
+#define PNV8_OCC_VDD_VOLTAGE_IDENTIFIER  0x1f8012
+#define PNV8_OCC_VCS_VOLTAGE_IDENTIFIER  0x1f8013
+#define PNV8_OCC_PSTATE_ZERO_FREQUENCY   0x1f8014
+#define PNV8_OCC_PSTATE_ONE_FREQUENCY    0x1f801c
+#define PNV8_OCC_PSTATE_TWO_FREQUENCY    0x1f8024
+#define PNV8_CORE_MAX_BASE               0x1f8810
+
+
+static uint64_t pnv_power8_homer_read(void *opaque, hwaddr addr,
+                                      unsigned size)
+{
+    PnvHomer *homer = PNV_HOMER(opaque);
+
+    switch (addr) {
+    case PNV8_OCC_PSTATE_VERSION:
+    case PNV8_OCC_PSTATE_MIN:
+    case PNV8_OCC_PSTATE_ID_ZERO:
+        return 0;
+    case PNV8_OCC_PSTATE_VALID:
+    case PNV8_OCC_PSTATE_THROTTLE:
+    case PNV8_OCC_PSTATE_NOM:
+    case PNV8_OCC_PSTATE_TURBO:
+    case PNV8_OCC_PSTATE_ID_ONE:
+    case PNV8_OCC_VDD_VOLTAGE_IDENTIFIER:
+    case PNV8_OCC_VCS_VOLTAGE_IDENTIFIER:
+        return 1;
+    case PNV8_OCC_PSTATE_ULTRA_TURBO:
+    case PNV8_OCC_PSTATE_ID_TWO:
+        return 2;
+    case PNV8_OCC_PSTATE_DATA:
+        return 0x1000000000000000;
+    /* P8 frequency for 0, 1, and 2 pstates */
+    case PNV8_OCC_PSTATE_ZERO_FREQUENCY:
+    case PNV8_OCC_PSTATE_ONE_FREQUENCY:
+    case PNV8_OCC_PSTATE_TWO_FREQUENCY:
+        return 3000;
+    }
+    /* pstate table core max array */
+    if (core_max_array(homer, addr)) {
+        return 1;
+    }
+    return 0;
+}
+
+static void pnv_power8_homer_write(void *opaque, hwaddr addr,
+                                   uint64_t val, unsigned size)
+{
+    /* callback function defined to homer write */
+    return;
+}
+
+static const MemoryRegionOps pnv_power8_homer_ops = {
+    .read = pnv_power8_homer_read,
+    .write = pnv_power8_homer_write,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 8,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 8,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void pnv_homer_power8_class_init(ObjectClass *klass, void *data)
+{
+    PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
+
+    homer->homer_size = PNV_HOMER_SIZE;
+    homer->homer_ops = &pnv_power8_homer_ops;
+    homer->core_max_base = PNV8_CORE_MAX_BASE;
+}
+
+static const TypeInfo pnv_homer_power8_type_info = {
+    .name          = TYPE_PNV8_HOMER,
+    .parent        = TYPE_PNV_HOMER,
+    .instance_size = sizeof(PnvHomer),
+    .class_init    = pnv_homer_power8_class_init,
+};
+
+/* P9 Pstate table */
+
+#define PNV9_OCC_PSTATE_ID_ZERO          0xe2018
+#define PNV9_OCC_PSTATE_ID_ONE           0xe2020
+#define PNV9_OCC_PSTATE_ID_TWO           0xe2028
+#define PNV9_OCC_PSTATE_DATA             0xe2000
+#define PNV9_OCC_PSTATE_DATA_AREA        0xe2008
+#define PNV9_OCC_PSTATE_MIN              0xe2003
+#define PNV9_OCC_PSTATE_NOM              0xe2004
+#define PNV9_OCC_PSTATE_TURBO            0xe2005
+#define PNV9_OCC_PSTATE_ULTRA_TURBO      0xe2818
+#define PNV9_OCC_MAX_PSTATE_ULTRA_TURBO  0xe2006
+#define PNV9_OCC_PSTATE_MAJOR_VERSION    0xe2001
+#define PNV9_OCC_OPAL_RUNTIME_DATA       0xe2b85
+#define PNV9_CHIP_HOMER_IMAGE_POINTER    0x200008
+#define PNV9_CHIP_HOMER_BASE             0x0
+#define PNV9_OCC_PSTATE_ZERO_FREQUENCY   0xe201c
+#define PNV9_OCC_PSTATE_ONE_FREQUENCY    0xe2024
+#define PNV9_OCC_PSTATE_TWO_FREQUENCY    0xe202c
+#define PNV9_OCC_ROLE_MASTER_OR_SLAVE    0xe2002
+#define PNV9_CORE_MAX_BASE               0xe2819
+
+
+static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr,
+                                      unsigned size)
+{
+    PnvHomer *homer = PNV_HOMER(opaque);
+
+    switch (addr) {
+    case PNV9_OCC_MAX_PSTATE_ULTRA_TURBO:
+    case PNV9_OCC_PSTATE_ID_ZERO:
+        return 0;
+    case PNV9_OCC_PSTATE_DATA:
+    case PNV9_OCC_ROLE_MASTER_OR_SLAVE:
+    case PNV9_OCC_PSTATE_NOM:
+    case PNV9_OCC_PSTATE_TURBO:
+    case PNV9_OCC_PSTATE_ID_ONE:
+    case PNV9_OCC_PSTATE_ULTRA_TURBO:
+    case PNV9_OCC_OPAL_RUNTIME_DATA:
+        return 1;
+    case PNV9_OCC_PSTATE_MIN:
+    case PNV9_OCC_PSTATE_ID_TWO:
+        return 2;
+
+    /* 3000 khz frequency for 0, 1, and 2 pstates */
+    case PNV9_OCC_PSTATE_ZERO_FREQUENCY:
+    case PNV9_OCC_PSTATE_ONE_FREQUENCY:
+    case PNV9_OCC_PSTATE_TWO_FREQUENCY:
+        return 3000;
+    case PNV9_OCC_PSTATE_MAJOR_VERSION:
+        return 0x90;
+    case PNV9_CHIP_HOMER_BASE:
+    case PNV9_OCC_PSTATE_DATA_AREA:
+    case PNV9_CHIP_HOMER_IMAGE_POINTER:
+        return 0x1000000000000000;
+    }
+    /* pstate table core max array */
+    if (core_max_array(homer, addr)) {
+        return 1;
+    }
+    return 0;
+}
+
+static void pnv_power9_homer_write(void *opaque, hwaddr addr,
+                                   uint64_t val, unsigned size)
+{
+    /* callback function defined to homer write */
+    return;
+}
+
+static const MemoryRegionOps pnv_power9_homer_ops = {
+    .read = pnv_power9_homer_read,
+    .write = pnv_power9_homer_write,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 8,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 8,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void pnv_homer_power9_class_init(ObjectClass *klass, void *data)
+{
+    PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
+
+    homer->homer_size = PNV9_HOMER_SIZE;
+    homer->homer_ops = &pnv_power9_homer_ops;
+    homer->core_max_base = PNV9_CORE_MAX_BASE;
+}
+
+static const TypeInfo pnv_homer_power9_type_info = {
+    .name          = TYPE_PNV9_HOMER,
+    .parent        = TYPE_PNV_HOMER,
+    .instance_size = sizeof(PnvHomer),
+    .class_init    = pnv_homer_power9_class_init,
+};
+
+static void pnv_homer_realize(DeviceState *dev, Error **errp)
+{
+    PnvHomer *homer = PNV_HOMER(dev);
+    PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer);
+    Object *obj;
+    Error *local_err = NULL;
+
+    obj = object_property_get_link(OBJECT(dev), "chip", &local_err);
+    if (!obj) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "required link 'chip' not found: ");
+        return;
+    }
+    homer->chip = PNV_CHIP(obj);
+    /* homer region */
+    memory_region_init_io(&homer->regs, OBJECT(dev),
+                          hmrc->homer_ops, homer, "homer-main-memory",
+                          hmrc->homer_size);
+}
+
+static void pnv_homer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = pnv_homer_realize;
+    dc->desc = "PowerNV HOMER Memory";
+}
+
+static const TypeInfo pnv_homer_type_info = {
+    .name          = TYPE_PNV_HOMER,
+    .parent        = TYPE_DEVICE,
+    .instance_size = sizeof(PnvHomer),
+    .class_init    = pnv_homer_class_init,
+    .class_size    = sizeof(PnvHomerClass),
+    .abstract      = true,
+};
+
+static void pnv_homer_register_types(void)
+{
+    type_register_static(&pnv_homer_type_info);
+    type_register_static(&pnv_homer_power8_type_info);
+    type_register_static(&pnv_homer_power9_type_info);
+}
+
+type_init(pnv_homer_register_types);
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 63a4b7b6a7..1cdbe55bf8 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -26,6 +26,7 @@
 #include "hw/ppc/pnv_lpc.h"
 #include "hw/ppc/pnv_psi.h"
 #include "hw/ppc/pnv_occ.h"
+#include "hw/ppc/pnv_homer.h"
 #include "hw/ppc/pnv_xive.h"
 #include "hw/ppc/pnv_core.h"
 
@@ -76,6 +77,7 @@ typedef struct Pnv8Chip {
     PnvLpcController lpc;
     Pnv8Psi      psi;
     PnvOCC       occ;
+    PnvHomer     homer;
 } Pnv8Chip;
 
 #define TYPE_PNV9_CHIP "pnv9-chip"
@@ -90,6 +92,7 @@ typedef struct Pnv9Chip {
     Pnv9Psi      psi;
     PnvLpcController lpc;
     PnvOCC       occ;
+    PnvHomer     homer;
 
     uint32_t     nr_quads;
     PnvQuad      *quads;
diff --git a/include/hw/ppc/pnv_homer.h b/include/hw/ppc/pnv_homer.h
new file mode 100644
index 0000000000..abaec43c2d
--- /dev/null
+++ b/include/hw/ppc/pnv_homer.h
@@ -0,0 +1,53 @@
+/*
+ * QEMU PowerPC PowerNV Emulation of a few HOMER related registers
+ *
+ * Copyright (c) 2019, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PPC_PNV_HOMER_H
+#define PPC_PNV_HOMER_H
+
+#include "hw/ppc/pnv.h"
+
+#define TYPE_PNV_HOMER "pnv-homer"
+#define PNV_HOMER(obj) OBJECT_CHECK(PnvHomer, (obj), TYPE_PNV_HOMER)
+#define TYPE_PNV8_HOMER TYPE_PNV_HOMER "-POWER8"
+#define PNV8_HOMER(obj) OBJECT_CHECK(PnvHomer, (obj), TYPE_PNV8_HOMER)
+#define TYPE_PNV9_HOMER TYPE_PNV_HOMER "-POWER9"
+#define PNV9_HOMER(obj) OBJECT_CHECK(PnvHomer, (obj), TYPE_PNV9_HOMER)
+
+typedef struct PnvHomer {
+    DeviceState parent;
+
+    struct PnvChip *chip;
+    MemoryRegion regs;
+} PnvHomer;
+
+#define PNV_HOMER_CLASS(klass)   \
+     OBJECT_CLASS_CHECK(PnvHomerClass, (klass), TYPE_PNV_HOMER)
+#define PNV_HOMER_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(PnvHomerClass, (obj), TYPE_PNV_HOMER)
+
+typedef struct PnvHomerClass {
+    DeviceClass parent_class;
+
+    int homer_size;
+    const MemoryRegionOps *homer_ops;
+
+    hwaddr core_max_base;
+} PnvHomerClass;
+
+#endif /* PPC_PNV_HOMER_H */
-- 
2.21.0



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

* [PULL 09/53] spapr/irq: Introduce an ics_irq_free() helper
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (7 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 08/53] hw/ppc/pnv_homer: add PowerNV homer device model David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 10/53] spapr/irq: Only claim VALID interrupts at the KVM level David Gibson
                   ` (44 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

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

It will help us to discard interrupt numbers which have not been
claimed in the next patch.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20190911133937.2716-2-clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_irq.c    | 9 +++------
 include/hw/ppc/xics.h | 5 +++++
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 06fe2432ba..d8f46b6797 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -114,9 +114,6 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
     xics_spapr_init(spapr);
 }
 
-#define ICS_IRQ_FREE(ics, srcno)   \
-    (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
-
 static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
                                 Error **errp)
 {
@@ -129,7 +126,7 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
         return -1;
     }
 
-    if (!ICS_IRQ_FREE(ics, irq - ics->offset)) {
+    if (!ics_irq_free(ics, irq - ics->offset)) {
         error_setg(errp, "IRQ %d is not free", irq);
         return -1;
     }
@@ -147,7 +144,7 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
     if (ics_valid_irq(ics, irq)) {
         trace_spapr_irq_free(0, irq, num);
         for (i = srcno; i < srcno + num; ++i) {
-            if (ICS_IRQ_FREE(ics, i)) {
+            if (ics_irq_free(ics, i)) {
                 trace_spapr_irq_free_warn(0, i);
             }
             memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
@@ -767,7 +764,7 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)
             return -1;
         }
         for (i = first; i < first + num; ++i) {
-            if (!ICS_IRQ_FREE(ics, i)) {
+            if (!ics_irq_free(ics, i)) {
                 break;
             }
         }
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index f2a8d6a4b4..64a2c8862a 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -179,6 +179,11 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
                            uint8_t priority, uint8_t saved_priority);
 void ics_simple_set_irq(void *opaque, int srcno, int val);
 
+static inline bool ics_irq_free(ICSState *ics, uint32_t srcno)
+{
+    return !(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK);
+}
+
 void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
 void icp_pic_print_info(ICPState *icp, Monitor *mon);
 void ics_pic_print_info(ICSState *ics, Monitor *mon);
-- 
2.21.0



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

* [PULL 10/53] spapr/irq: Only claim VALID interrupts at the KVM level
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (8 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 09/53] spapr/irq: Introduce an ics_irq_free() helper David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 11/53] ppc: Add support for 'mffscrn','mffscrni' instructions David Gibson
                   ` (43 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

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

A typical pseries VM with 16 vCPUs, one disk, one network adapater
uses less than 100 interrupts but the whole IRQ number space of the
QEMU machine is allocated at reset time and it is 8K wide. This is
wasting a considerable amount of interrupt numbers in the global IRQ
space which has 1M interrupts per socket on a POWER9.

To optimise the HW resources, only request at the KVM level interrupts
which have been claimed by the guest. This will help to increase the
maximum number of VMs per system and also help supporting nested guests
using the XIVE interrupt mode.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20190911133937.2716-3-clg@kaod.org>
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <156942766014.1274533.10792048853177121231.stgit@bahia.lan>
[dwg: Folded in fix up from Greg Kurz]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive_kvm.c | 40 +++++++++++++++++++++++++++++++++++++---
 hw/intc/xics_kvm.c       |  8 ++++++++
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 17af4d19f5..2006f96aec 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -255,11 +255,16 @@ void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
 
 static void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp)
 {
+    SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
     int i;
 
     for (i = 0; i < xsrc->nr_irqs; i++) {
         Error *local_err = NULL;
 
+        if (!xive_eas_is_valid(&xive->eat[i])) {
+            continue;
+        }
+
         kvmppc_xive_source_reset_one(xsrc, i, &local_err);
         if (local_err) {
             error_propagate(errp, local_err);
@@ -328,11 +333,18 @@ uint64_t kvmppc_xive_esb_rw(XiveSource *xsrc, int srcno, uint32_t offset,
 
 static void kvmppc_xive_source_get_state(XiveSource *xsrc)
 {
+    SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
     int i;
 
     for (i = 0; i < xsrc->nr_irqs; i++) {
+        uint8_t pq;
+
+        if (!xive_eas_is_valid(&xive->eat[i])) {
+            continue;
+        }
+
         /* Perform a load without side effect to retrieve the PQ bits */
-        uint8_t pq = xive_esb_read(xsrc, i, XIVE_ESB_GET);
+        pq = xive_esb_read(xsrc, i, XIVE_ESB_GET);
 
         /* and save PQ locally */
         xive_source_esb_set(xsrc, i, pq);
@@ -521,9 +533,14 @@ static void kvmppc_xive_change_state_handler(void *opaque, int running,
      */
     if (running) {
         for (i = 0; i < xsrc->nr_irqs; i++) {
-            uint8_t pq = xive_source_esb_get(xsrc, i);
+            uint8_t pq;
             uint8_t old_pq;
 
+            if (!xive_eas_is_valid(&xive->eat[i])) {
+                continue;
+            }
+
+            pq = xive_source_esb_get(xsrc, i);
             old_pq = xive_esb_read(xsrc, i, XIVE_ESB_SET_PQ_00 + (pq << 8));
 
             /*
@@ -545,7 +562,13 @@ static void kvmppc_xive_change_state_handler(void *opaque, int running,
      * migration is in progress.
      */
     for (i = 0; i < xsrc->nr_irqs; i++) {
-        uint8_t pq = xive_esb_read(xsrc, i, XIVE_ESB_GET);
+        uint8_t pq;
+
+        if (!xive_eas_is_valid(&xive->eat[i])) {
+            continue;
+        }
+
+        pq = xive_esb_read(xsrc, i, XIVE_ESB_GET);
 
         /*
          * PQ is set to PENDING to possibly catch a triggered
@@ -655,6 +678,17 @@ int kvmppc_xive_post_load(SpaprXive *xive, int version_id)
             continue;
         }
 
+        /*
+         * We can only restore the source config if the source has been
+         * previously set in KVM. Since we don't do that for all interrupts
+         * at reset time anymore, let's do it now.
+         */
+        kvmppc_xive_source_reset_one(&xive->source, i, &local_err);
+        if (local_err) {
+            error_report_err(local_err);
+            return -1;
+        }
+
         kvmppc_xive_set_source_config(xive, i, &xive->eat[i], &local_err);
         if (local_err) {
             error_report_err(local_err);
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index a4d2e876cc..ba90d6dc96 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -190,6 +190,10 @@ void ics_get_kvm_state(ICSState *ics)
     for (i = 0; i < ics->nr_irqs; i++) {
         ICSIRQState *irq = &ics->irqs[i];
 
+        if (ics_irq_free(ics, i)) {
+            continue;
+        }
+
         kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
                           i + ics->offset, &state, false, &error_fatal);
 
@@ -301,6 +305,10 @@ int ics_set_kvm_state(ICSState *ics, Error **errp)
         Error *local_err = NULL;
         int ret;
 
+        if (ics_irq_free(ics, i)) {
+            continue;
+        }
+
         ret = ics_set_kvm_state_one(ics, i, &local_err);
         if (ret < 0) {
             error_propagate(errp, local_err);
-- 
2.21.0



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

* [PULL 11/53] ppc: Add support for 'mffscrn','mffscrni' instructions
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (9 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 10/53] spapr/irq: Only claim VALID interrupts at the KVM level David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 12/53] ppc: Add support for 'mffsce' instruction David Gibson
                   ` (42 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, qemu-devel, groug, qemu-ppc,
	clg, David Gibson, Paul A. Clarke

From: "Paul A. Clarke" <pc@us.ibm.com>

ISA 3.0B added a set of Floating-Point Status and Control Register (FPSCR)
instructions: mffsce, mffscdrn, mffscdrni, mffscrn, mffscrni, mffsl.
This patch adds support for 'mffscrn' and 'mffscrni' instructions.

'mffscrn' and 'mffscrni' are similar to 'mffsl', except they do not return
the status bits (FI, FR, FPRF) and they also set the rounding mode in the
FPSCR.

On CPUs without support for 'mffscrn'/'mffscrni' (below ISA 3.0), the
instructions will execute identically to 'mffs'.

Signed-off-by: Paul A. Clarke <pc@us.ibm.com>
Message-Id: <1568817081-1345-1-git-send-email-pc@us.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/cpu.h                   |  9 +++-
 target/ppc/dfp_helper.c            |  2 +-
 target/ppc/internal.h              |  3 ++
 target/ppc/translate/fp-impl.inc.c | 69 +++++++++++++++++++++++++++++-
 target/ppc/translate/fp-ops.inc.c  |  4 ++
 5 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index eaee1a5575..a23c6455b9 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -559,6 +559,9 @@ enum {
 
 /*****************************************************************************/
 /* Floating point status and control register                                */
+#define FPSCR_DRN2   34 /* Decimal Floating-Point rounding control           */
+#define FPSCR_DRN1   33 /* Decimal Floating-Point rounding control           */
+#define FPSCR_DRN0   32 /* Decimal Floating-Point rounding control           */
 #define FPSCR_FX     31 /* Floating-point exception summary                  */
 #define FPSCR_FEX    30 /* Floating-point enabled exception summary          */
 #define FPSCR_VX     29 /* Floating-point invalid operation exception summ.  */
@@ -592,6 +595,7 @@ enum {
 #define FPSCR_NI     2  /* Floating-point non-IEEE mode                      */
 #define FPSCR_RN1    1
 #define FPSCR_RN0    0  /* Floating-point rounding control                   */
+#define fpscr_drn    (((env->fpscr) & FP_DRN) >> FPSCR_DRN0)
 #define fpscr_fex    (((env->fpscr) >> FPSCR_FEX)    & 0x1)
 #define fpscr_vx     (((env->fpscr) >> FPSCR_VX)     & 0x1)
 #define fpscr_ox     (((env->fpscr) >> FPSCR_OX)     & 0x1)
@@ -627,6 +631,10 @@ enum {
 #define fpscr_eex (((env->fpscr) >> FPSCR_XX) & ((env->fpscr) >> FPSCR_XE) &  \
                    0x1F)
 
+#define FP_DRN2         (1ull << FPSCR_DRN2)
+#define FP_DRN1         (1ull << FPSCR_DRN1)
+#define FP_DRN0         (1ull << FPSCR_DRN0)
+#define FP_DRN          (FP_DRN2 | FP_DRN1 | FP_DRN0)
 #define FP_FX           (1ull << FPSCR_FX)
 #define FP_FEX          (1ull << FPSCR_FEX)
 #define FP_VX           (1ull << FPSCR_VX)
@@ -662,7 +670,6 @@ enum {
 #define FP_RN0          (1ull << FPSCR_RN0)
 #define FP_RN           (FP_RN1 | FP_RN0)
 
-#define FP_MODE         FP_RN
 #define FP_ENABLES      (FP_VE | FP_OE | FP_UE | FP_ZE | FP_XE)
 #define FP_STATUS       (FP_FR | FP_FI | FP_FPRF)
 
diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index f102177572..da8e08a35c 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -48,7 +48,7 @@ static void dfp_prepare_rounding_mode(decContext *context, uint64_t fpscr)
 {
     enum rounding rnd;
 
-    switch ((fpscr >> 32) & 0x7) {
+    switch ((fpscr & FP_DRN) >> FPSCR_DRN0) {
     case 0:
         rnd = DEC_ROUND_HALF_EVEN;
         break;
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index d3d327e548..15d655b356 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -157,6 +157,9 @@ EXTRACT_HELPER(FPL, 25, 1);
 EXTRACT_HELPER(FPFLM, 17, 8);
 EXTRACT_HELPER(FPW, 16, 1);
 
+/* mffscrni */
+EXTRACT_HELPER(RM, 11, 2);
+
 /* addpcis */
 EXTRACT_HELPER_SPLIT_3(DX, 10, 6, 6, 5, 16, 1, 1, 0, 0)
 #if defined(TARGET_PPC64)
diff --git a/target/ppc/translate/fp-impl.inc.c b/target/ppc/translate/fp-impl.inc.c
index 7cd9d8db05..75f9523b07 100644
--- a/target/ppc/translate/fp-impl.inc.c
+++ b/target/ppc/translate/fp-impl.inc.c
@@ -634,11 +634,78 @@ static void gen_mffsl(DisasContext *ctx)
     gen_reset_fpstatus();
     tcg_gen_extu_tl_i64(t0, cpu_fpscr);
     /* Mask everything except mode, status, and enables.  */
-    tcg_gen_andi_i64(t0, t0, FP_MODE | FP_STATUS | FP_ENABLES);
+    tcg_gen_andi_i64(t0, t0, FP_DRN | FP_STATUS | FP_ENABLES | FP_RN);
     set_fpr(rD(ctx->opcode), t0);
     tcg_temp_free_i64(t0);
 }
 
+static void gen_helper_mffscrn(DisasContext *ctx, TCGv_i64 t1)
+{
+    TCGv_i64 t0 = tcg_temp_new_i64();
+    TCGv_i32 mask = tcg_const_i32(0x0001);
+
+    gen_reset_fpstatus();
+    tcg_gen_extu_tl_i64(t0, cpu_fpscr);
+    tcg_gen_andi_i64(t0, t0, FP_DRN | FP_ENABLES | FP_RN);
+    set_fpr(rD(ctx->opcode), t0);
+
+    /* Mask FPSCR value to clear RN.  */
+    tcg_gen_andi_i64(t0, t0, ~FP_RN);
+
+    /* Merge RN into FPSCR value.  */
+    tcg_gen_or_i64(t0, t0, t1);
+
+    gen_helper_store_fpscr(cpu_env, t0, mask);
+
+    tcg_temp_free_i32(mask);
+    tcg_temp_free_i64(t0);
+}
+
+/* mffscrn */
+static void gen_mffscrn(DisasContext *ctx)
+{
+    TCGv_i64 t1;
+
+    if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) {
+        return gen_mffs(ctx);
+    }
+
+    if (unlikely(!ctx->fpu_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_FPU);
+        return;
+    }
+
+    t1 = tcg_temp_new_i64();
+    get_fpr(t1, rB(ctx->opcode));
+    /* Mask FRB to get just RN.  */
+    tcg_gen_andi_i64(t1, t1, FP_RN);
+
+    gen_helper_mffscrn(ctx, t1);
+
+    tcg_temp_free_i64(t1);
+}
+
+/* mffscrni */
+static void gen_mffscrni(DisasContext *ctx)
+{
+    TCGv_i64 t1;
+
+    if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) {
+        return gen_mffs(ctx);
+    }
+
+    if (unlikely(!ctx->fpu_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_FPU);
+        return;
+    }
+
+    t1 = tcg_const_i64((uint64_t)RM(ctx->opcode));
+
+    gen_helper_mffscrn(ctx, t1);
+
+    tcg_temp_free_i64(t1);
+}
+
 /* mtfsb0 */
 static void gen_mtfsb0(DisasContext *ctx)
 {
diff --git a/target/ppc/translate/fp-ops.inc.c b/target/ppc/translate/fp-ops.inc.c
index 88ebc2526c..f2bcf0e67b 100644
--- a/target/ppc/translate/fp-ops.inc.c
+++ b/target/ppc/translate/fp-ops.inc.c
@@ -107,6 +107,10 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
 GEN_HANDLER_E_2(mffs, 0x3F, 0x07, 0x12, 0x00, 0x00000000, PPC_FLOAT, PPC_NONE),
 GEN_HANDLER_E_2(mffsl, 0x3F, 0x07, 0x12, 0x18, 0x00000000, PPC_FLOAT,
     PPC2_ISA300),
+GEN_HANDLER_E_2(mffscrn, 0x3F, 0x07, 0x12, 0x16, 0x00000000, PPC_FLOAT,
+    PPC_NONE),
+GEN_HANDLER_E_2(mffscrni, 0x3F, 0x07, 0x12, 0x17, 0x00000000, PPC_FLOAT,
+    PPC_NONE),
 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT),
-- 
2.21.0



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

* [PULL 12/53] ppc: Add support for 'mffsce' instruction
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (10 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 11/53] ppc: Add support for 'mffscrn','mffscrni' instructions David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 13/53] ppc: Use FPSCR defines instead of constants David Gibson
                   ` (41 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, qemu-devel, groug, qemu-ppc,
	clg, David Gibson, Paul A. Clarke

From: "Paul A. Clarke" <pc@us.ibm.com>

ISA 3.0B added a set of Floating-Point Status and Control Register (FPSCR)
instructions: mffsce, mffscdrn, mffscdrni, mffscrn, mffscrni, mffsl.
This patch adds support for 'mffsce' instruction.

'mffsce' is identical to 'mffs', except that it also clears the exception
enable bits in the FPSCR.

On CPUs without support for 'mffsce' (below ISA 3.0), the
instruction will execute identically to 'mffs'.

Signed-off-by: Paul A. Clarke <pc@us.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <1568817082-1384-1-git-send-email-pc@us.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/translate/fp-impl.inc.c | 30 ++++++++++++++++++++++++++++++
 target/ppc/translate/fp-ops.inc.c  |  2 ++
 2 files changed, 32 insertions(+)

diff --git a/target/ppc/translate/fp-impl.inc.c b/target/ppc/translate/fp-impl.inc.c
index 75f9523b07..d8e27bf4d5 100644
--- a/target/ppc/translate/fp-impl.inc.c
+++ b/target/ppc/translate/fp-impl.inc.c
@@ -639,6 +639,36 @@ static void gen_mffsl(DisasContext *ctx)
     tcg_temp_free_i64(t0);
 }
 
+/* mffsce */
+static void gen_mffsce(DisasContext *ctx)
+{
+    TCGv_i64 t0;
+    TCGv_i32 mask;
+
+    if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) {
+        return gen_mffs(ctx);
+    }
+
+    if (unlikely(!ctx->fpu_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_FPU);
+        return;
+    }
+
+    t0 = tcg_temp_new_i64();
+
+    gen_reset_fpstatus();
+    tcg_gen_extu_tl_i64(t0, cpu_fpscr);
+    set_fpr(rD(ctx->opcode), t0);
+
+    /* Clear exception enable bits in the FPSCR.  */
+    tcg_gen_andi_i64(t0, t0, ~FP_ENABLES);
+    mask = tcg_const_i32(0x0003);
+    gen_helper_store_fpscr(cpu_env, t0, mask);
+
+    tcg_temp_free_i32(mask);
+    tcg_temp_free_i64(t0);
+}
+
 static void gen_helper_mffscrn(DisasContext *ctx, TCGv_i64 t1)
 {
     TCGv_i64 t0 = tcg_temp_new_i64();
diff --git a/target/ppc/translate/fp-ops.inc.c b/target/ppc/translate/fp-ops.inc.c
index f2bcf0e67b..88fab65628 100644
--- a/target/ppc/translate/fp-ops.inc.c
+++ b/target/ppc/translate/fp-ops.inc.c
@@ -105,6 +105,8 @@ GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207),
 GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207),
 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
 GEN_HANDLER_E_2(mffs, 0x3F, 0x07, 0x12, 0x00, 0x00000000, PPC_FLOAT, PPC_NONE),
+GEN_HANDLER_E_2(mffsce, 0x3F, 0x07, 0x12, 0x01, 0x00000000, PPC_FLOAT,
+    PPC2_ISA300),
 GEN_HANDLER_E_2(mffsl, 0x3F, 0x07, 0x12, 0x18, 0x00000000, PPC_FLOAT,
     PPC2_ISA300),
 GEN_HANDLER_E_2(mffscrn, 0x3F, 0x07, 0x12, 0x16, 0x00000000, PPC_FLOAT,
-- 
2.21.0



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

* [PULL 13/53] ppc: Use FPSCR defines instead of constants
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (11 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 12/53] ppc: Add support for 'mffsce' instruction David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 14/53] ppc/kvm: Skip writing DPDES back when in run time state David Gibson
                   ` (40 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, qemu-devel, groug, qemu-ppc,
	clg, David Gibson, Paul A. Clarke

From: "Paul A. Clarke" <pc@us.ibm.com>

There are FPSCR-related defines in target/ppc/cpu.h which can be used in
place of constants and explicit shifts which arguably improve the code a
bit in places.

Signed-off-by: Paul A. Clarke <pc@us.ibm.com>
Message-Id: <1568817169-1721-1-git-send-email-pc@us.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/dfp_helper.c |   8 +--
 target/ppc/fpu_helper.c | 122 ++++++++++++++++++++--------------------
 2 files changed, 65 insertions(+), 65 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index da8e08a35c..753399177c 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -220,8 +220,8 @@ static void dfp_set_FPRF_from_FRT_with_context(struct PPC_DFP *dfp,
     default:
         assert(0); /* should never get here */
     }
-    dfp->env->fpscr &= ~(0x1F << 12);
-    dfp->env->fpscr |= (fprf << 12);
+    dfp->env->fpscr &= ~FP_FPRF;
+    dfp->env->fpscr |= (fprf << FPSCR_FPRF);
 }
 
 static void dfp_set_FPRF_from_FRT(struct PPC_DFP *dfp)
@@ -369,8 +369,8 @@ static void dfp_set_CRBF_from_T(struct PPC_DFP *dfp)
 
 static void dfp_set_FPCC_from_CRBF(struct PPC_DFP *dfp)
 {
-    dfp->env->fpscr &= ~(0xF << 12);
-    dfp->env->fpscr |= (dfp->crbf << 12);
+    dfp->env->fpscr &= ~FP_FPCC;
+    dfp->env->fpscr |= (dfp->crbf << FPSCR_FPCC);
 }
 
 static inline void dfp_makeQNaN(decNumber *dn)
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 4b1a2e6178..dc383242f7 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -180,7 +180,7 @@ static void set_fprf_from_class(CPUPPCState *env, int class)
     };
     bool isneg = class & is_neg;
 
-    env->fpscr &= ~(0x1F << FPSCR_FPRF);
+    env->fpscr &= ~FP_FPRF;
     env->fpscr |= fprf[ctz32(class)][isneg] << FPSCR_FPRF;
 }
 
@@ -199,12 +199,12 @@ COMPUTE_FPRF(float128)
 static void finish_invalid_op_excp(CPUPPCState *env, int op, uintptr_t retaddr)
 {
     /* Update the floating-point invalid operation summary */
-    env->fpscr |= 1 << FPSCR_VX;
+    env->fpscr |= FP_VX;
     /* Update the floating-point exception summary */
     env->fpscr |= FP_FX;
     if (fpscr_ve != 0) {
         /* Update the floating-point enabled exception summary */
-        env->fpscr |= 1 << FPSCR_FEX;
+        env->fpscr |= FP_FEX;
         if (fp_exceptions_enabled(env)) {
             raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
                                    POWERPC_EXCP_FP | op, retaddr);
@@ -215,11 +215,11 @@ static void finish_invalid_op_excp(CPUPPCState *env, int op, uintptr_t retaddr)
 static void finish_invalid_op_arith(CPUPPCState *env, int op,
                                     bool set_fpcc, uintptr_t retaddr)
 {
-    env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
+    env->fpscr &= ~(FP_FR | FP_FI);
     if (fpscr_ve == 0) {
         if (set_fpcc) {
-            env->fpscr &= ~(0xF << FPSCR_FPCC);
-            env->fpscr |= 0x11 << FPSCR_FPCC;
+            env->fpscr &= ~FP_FPCC;
+            env->fpscr |= (FP_C | FP_FU);
         }
     }
     finish_invalid_op_excp(env, op, retaddr);
@@ -228,7 +228,7 @@ static void finish_invalid_op_arith(CPUPPCState *env, int op,
 /* Signalling NaN */
 static void float_invalid_op_vxsnan(CPUPPCState *env, uintptr_t retaddr)
 {
-    env->fpscr |= 1 << FPSCR_VXSNAN;
+    env->fpscr |= FP_VXSNAN;
     finish_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, retaddr);
 }
 
@@ -236,7 +236,7 @@ static void float_invalid_op_vxsnan(CPUPPCState *env, uintptr_t retaddr)
 static void float_invalid_op_vxisi(CPUPPCState *env, bool set_fpcc,
                                    uintptr_t retaddr)
 {
-    env->fpscr |= 1 << FPSCR_VXISI;
+    env->fpscr |= FP_VXISI;
     finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXISI, set_fpcc, retaddr);
 }
 
@@ -244,7 +244,7 @@ static void float_invalid_op_vxisi(CPUPPCState *env, bool set_fpcc,
 static void float_invalid_op_vxidi(CPUPPCState *env, bool set_fpcc,
                                    uintptr_t retaddr)
 {
-    env->fpscr |= 1 << FPSCR_VXIDI;
+    env->fpscr |= FP_VXIDI;
     finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXIDI, set_fpcc, retaddr);
 }
 
@@ -252,7 +252,7 @@ static void float_invalid_op_vxidi(CPUPPCState *env, bool set_fpcc,
 static void float_invalid_op_vxzdz(CPUPPCState *env, bool set_fpcc,
                                    uintptr_t retaddr)
 {
-    env->fpscr |= 1 << FPSCR_VXZDZ;
+    env->fpscr |= FP_VXZDZ;
     finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXZDZ, set_fpcc, retaddr);
 }
 
@@ -260,7 +260,7 @@ static void float_invalid_op_vxzdz(CPUPPCState *env, bool set_fpcc,
 static void float_invalid_op_vximz(CPUPPCState *env, bool set_fpcc,
                                    uintptr_t retaddr)
 {
-    env->fpscr |= 1 << FPSCR_VXIMZ;
+    env->fpscr |= FP_VXIMZ;
     finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXIMZ, set_fpcc, retaddr);
 }
 
@@ -268,7 +268,7 @@ static void float_invalid_op_vximz(CPUPPCState *env, bool set_fpcc,
 static void float_invalid_op_vxsqrt(CPUPPCState *env, bool set_fpcc,
                                     uintptr_t retaddr)
 {
-    env->fpscr |= 1 << FPSCR_VXSQRT;
+    env->fpscr |= FP_VXSQRT;
     finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXSQRT, set_fpcc, retaddr);
 }
 
@@ -276,13 +276,13 @@ static void float_invalid_op_vxsqrt(CPUPPCState *env, bool set_fpcc,
 static void float_invalid_op_vxvc(CPUPPCState *env, bool set_fpcc,
                                   uintptr_t retaddr)
 {
-    env->fpscr |= 1 << FPSCR_VXVC;
+    env->fpscr |= FP_VXVC;
     if (set_fpcc) {
-        env->fpscr &= ~(0xF << FPSCR_FPCC);
-        env->fpscr |= 0x11 << FPSCR_FPCC;
+        env->fpscr &= ~FP_FPCC;
+        env->fpscr |= (FP_C | FP_FU);
     }
     /* Update the floating-point invalid operation summary */
-    env->fpscr |= 1 << FPSCR_VX;
+    env->fpscr |= FP_VX;
     /* Update the floating-point exception summary */
     env->fpscr |= FP_FX;
     /* We must update the target FPR before raising the exception */
@@ -292,7 +292,7 @@ static void float_invalid_op_vxvc(CPUPPCState *env, bool set_fpcc,
         cs->exception_index = POWERPC_EXCP_PROGRAM;
         env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;
         /* Update the floating-point enabled exception summary */
-        env->fpscr |= 1 << FPSCR_FEX;
+        env->fpscr |= FP_FEX;
         /* Exception is differed */
     }
 }
@@ -301,12 +301,12 @@ static void float_invalid_op_vxvc(CPUPPCState *env, bool set_fpcc,
 static void float_invalid_op_vxcvi(CPUPPCState *env, bool set_fpcc,
                                    uintptr_t retaddr)
 {
-    env->fpscr |= 1 << FPSCR_VXCVI;
-    env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
+    env->fpscr |= FP_VXCVI;
+    env->fpscr &= ~(FP_FR | FP_FI);
     if (fpscr_ve == 0) {
         if (set_fpcc) {
-            env->fpscr &= ~(0xF << FPSCR_FPCC);
-            env->fpscr |= 0x11 << FPSCR_FPCC;
+            env->fpscr &= ~FP_FPCC;
+            env->fpscr |= (FP_C | FP_FU);
         }
     }
     finish_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, retaddr);
@@ -314,13 +314,13 @@ static void float_invalid_op_vxcvi(CPUPPCState *env, bool set_fpcc,
 
 static inline void float_zero_divide_excp(CPUPPCState *env, uintptr_t raddr)
 {
-    env->fpscr |= 1 << FPSCR_ZX;
-    env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
+    env->fpscr |= FP_ZX;
+    env->fpscr &= ~(FP_FR | FP_FI);
     /* Update the floating-point exception summary */
     env->fpscr |= FP_FX;
     if (fpscr_ze != 0) {
         /* Update the floating-point enabled exception summary */
-        env->fpscr |= 1 << FPSCR_FEX;
+        env->fpscr |= FP_FEX;
         if (fp_exceptions_enabled(env)) {
             raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
                                    POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX,
@@ -333,19 +333,19 @@ static inline void float_overflow_excp(CPUPPCState *env)
 {
     CPUState *cs = env_cpu(env);
 
-    env->fpscr |= 1 << FPSCR_OX;
+    env->fpscr |= FP_OX;
     /* Update the floating-point exception summary */
     env->fpscr |= FP_FX;
     if (fpscr_oe != 0) {
         /* XXX: should adjust the result */
         /* Update the floating-point enabled exception summary */
-        env->fpscr |= 1 << FPSCR_FEX;
+        env->fpscr |= FP_FEX;
         /* We must update the target FPR before raising the exception */
         cs->exception_index = POWERPC_EXCP_PROGRAM;
         env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX;
     } else {
-        env->fpscr |= 1 << FPSCR_XX;
-        env->fpscr |= 1 << FPSCR_FI;
+        env->fpscr |= FP_XX;
+        env->fpscr |= FP_FI;
     }
 }
 
@@ -353,13 +353,13 @@ static inline void float_underflow_excp(CPUPPCState *env)
 {
     CPUState *cs = env_cpu(env);
 
-    env->fpscr |= 1 << FPSCR_UX;
+    env->fpscr |= FP_UX;
     /* Update the floating-point exception summary */
     env->fpscr |= FP_FX;
     if (fpscr_ue != 0) {
         /* XXX: should adjust the result */
         /* Update the floating-point enabled exception summary */
-        env->fpscr |= 1 << FPSCR_FEX;
+        env->fpscr |= FP_FEX;
         /* We must update the target FPR before raising the exception */
         cs->exception_index = POWERPC_EXCP_PROGRAM;
         env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX;
@@ -370,13 +370,13 @@ static inline void float_inexact_excp(CPUPPCState *env)
 {
     CPUState *cs = env_cpu(env);
 
-    env->fpscr |= 1 << FPSCR_FI;
-    env->fpscr |= 1 << FPSCR_XX;
+    env->fpscr |= FP_FI;
+    env->fpscr |= FP_XX;
     /* Update the floating-point exception summary */
     env->fpscr |= FP_FX;
     if (fpscr_xe != 0) {
         /* Update the floating-point enabled exception summary */
-        env->fpscr |= 1 << FPSCR_FEX;
+        env->fpscr |= FP_FEX;
         /* We must update the target FPR before raising the exception */
         cs->exception_index = POWERPC_EXCP_PROGRAM;
         env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX;
@@ -433,7 +433,7 @@ void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit)
         case FPSCR_VXCVI:
             if (!fpscr_ix) {
                 /* Set VX bit to zero */
-                env->fpscr &= ~(1 << FPSCR_VX);
+                env->fpscr &= ~FP_VX;
             }
             break;
         case FPSCR_OX:
@@ -447,7 +447,7 @@ void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit)
         case FPSCR_XE:
             if (!fpscr_eex) {
                 /* Set the FEX bit */
-                env->fpscr &= ~(1 << FPSCR_FEX);
+                env->fpscr &= ~FP_FEX;
             }
             break;
         default:
@@ -504,7 +504,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
         case FPSCR_VXSOFT:
         case FPSCR_VXSQRT:
         case FPSCR_VXCVI:
-            env->fpscr |= 1 << FPSCR_VX;
+            env->fpscr |= FP_VX;
             env->fpscr |= FP_FX;
             if (fpscr_ve != 0) {
                 goto raise_ve;
@@ -580,7 +580,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
             break;
         raise_excp:
             /* Update the floating-point enabled exception summary */
-            env->fpscr |= 1 << FPSCR_FEX;
+            env->fpscr |= FP_FEX;
             /* We have to update Rc1 before raising the exception */
             cs->exception_index = POWERPC_EXCP_PROGRAM;
             break;
@@ -596,8 +596,8 @@ void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
 
     prev = env->fpscr;
     new = (target_ulong)arg;
-    new &= ~0x60000000LL;
-    new |= prev & 0x60000000LL;
+    new &= ~(FP_FEX | FP_VX);
+    new |= prev & (FP_FEX | FP_VX);
     for (i = 0; i < sizeof(target_ulong) * 2; i++) {
         if (mask & (1 << i)) {
             env->fpscr &= ~(0xFLL << (4 * i));
@@ -606,17 +606,17 @@ void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
     }
     /* Update VX and FEX */
     if (fpscr_ix != 0) {
-        env->fpscr |= 1 << FPSCR_VX;
+        env->fpscr |= FP_VX;
     } else {
-        env->fpscr &= ~(1 << FPSCR_VX);
+        env->fpscr &= ~FP_VX;
     }
     if ((fpscr_ex & fpscr_eex) != 0) {
-        env->fpscr |= 1 << FPSCR_FEX;
+        env->fpscr |= FP_FEX;
         cs->exception_index = POWERPC_EXCP_PROGRAM;
         /* XXX: we should compute it properly */
         env->error_code = POWERPC_EXCP_FP;
     } else {
-        env->fpscr &= ~(1 << FPSCR_FEX);
+        env->fpscr &= ~FP_FEX;
     }
     fpscr_set_rounding_mode(env);
 }
@@ -639,7 +639,7 @@ static void do_float_check_status(CPUPPCState *env, uintptr_t raddr)
     if (status & float_flag_inexact) {
         float_inexact_excp(env);
     } else {
-        env->fpscr &= ~(1 << FPSCR_FI); /* clear the FPSCR[FI] bit */
+        env->fpscr &= ~FP_FI; /* clear the FPSCR[FI] bit */
     }
 
     if (cs->exception_index == POWERPC_EXCP_PROGRAM &&
@@ -1138,8 +1138,8 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
         ret = 0x02UL;
     }
 
-    env->fpscr &= ~(0x0F << FPSCR_FPRF);
-    env->fpscr |= ret << FPSCR_FPRF;
+    env->fpscr &= ~FP_FPCC;
+    env->fpscr |= ret << FPSCR_FPCC;
     env->crf[crfD] = ret;
     if (unlikely(ret == 0x01UL
                  && (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
@@ -1169,9 +1169,9 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
         ret = 0x02UL;
     }
 
-    env->fpscr &= ~(0x0F << FPSCR_FPRF);
-    env->fpscr |= ret << FPSCR_FPRF;
-    env->crf[crfD] = ret;
+    env->fpscr &= ~FP_FPCC;
+    env->fpscr |= ret << FPSCR_FPCC;
+    env->crf[crfD] = (uint32_t) ret;
     if (unlikely(ret == 0x01UL)) {
         float_invalid_op_vxvc(env, 1, GETPC());
         if (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
@@ -2431,8 +2431,8 @@ void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode,
         }
     }
 
-    env->fpscr &= ~(0x0F << FPSCR_FPRF);
-    env->fpscr |= cc << FPSCR_FPRF;
+    env->fpscr &= ~FP_FPCC;
+    env->fpscr |= cc << FPSCR_FPCC;
     env->crf[BF(opcode)] = cc;
 
     do_float_check_status(env, GETPC());
@@ -2460,8 +2460,8 @@ void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode,
         }
     }
 
-    env->fpscr &= ~(0x0F << FPSCR_FPRF);
-    env->fpscr |= cc << FPSCR_FPRF;
+    env->fpscr &= ~FP_FPCC;
+    env->fpscr |= cc << FPSCR_FPCC;
     env->crf[BF(opcode)] = cc;
 
     do_float_check_status(env, GETPC());
@@ -2505,8 +2505,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode,                      \
         cc |= CRF_EQ;                                                    \
     }                                                                    \
                                                                          \
-    env->fpscr &= ~(0x0F << FPSCR_FPRF);                                 \
-    env->fpscr |= cc << FPSCR_FPRF;                                      \
+    env->fpscr &= ~FP_FPCC;                                              \
+    env->fpscr |= cc << FPSCR_FPCC;                                      \
     env->crf[BF(opcode)] = cc;                                           \
                                                                          \
     do_float_check_status(env, GETPC());                                 \
@@ -2553,8 +2553,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode,                     \
         cc |= CRF_EQ;                                                   \
     }                                                                   \
                                                                         \
-    env->fpscr &= ~(0x0F << FPSCR_FPRF);                                \
-    env->fpscr |= cc << FPSCR_FPRF;                                     \
+    env->fpscr &= ~FP_FPCC;                                             \
+    env->fpscr |= cc << FPSCR_FPCC;                                     \
     env->crf[BF(opcode)] = cc;                                          \
                                                                         \
     do_float_check_status(env, GETPC());                                \
@@ -3242,8 +3242,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)         \
                                                             \
         if (scrf) {                                         \
             cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT;  \
-            env->fpscr &= ~(0x0F << FPSCR_FPRF);            \
-            env->fpscr |= cc << FPSCR_FPRF;                 \
+            env->fpscr &= ~FP_FPCC;                         \
+            env->fpscr |= cc << FPSCR_FPCC;                 \
             env->crf[BF(opcode)] = cc;                      \
         } else {                                            \
             t.tfld = match ? fld_max : 0;                   \
@@ -3286,8 +3286,8 @@ void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb)
                              &env->fp_status), &env->fp_status);
 
     cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT | not_sp << CRF_SO_BIT;
-    env->fpscr &= ~(0x0F << FPSCR_FPRF);
-    env->fpscr |= cc << FPSCR_FPRF;
+    env->fpscr &= ~FP_FPCC;
+    env->fpscr |= cc << FPSCR_FPCC;
     env->crf[BF(opcode)] = cc;
 }
 
-- 
2.21.0



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

* [PULL 14/53] ppc/kvm: Skip writing DPDES back when in run time state
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (12 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 13/53] ppc: Use FPSCR defines instead of constants David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 15/53] spapr: Simplify handling of pre ISA 3.0 guest workaround handling David Gibson
                   ` (39 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

On POWER8 systems the Directed Privileged Door-bell Exception State
register (DPDES) stores doorbell pending status, one bit per a thread
of a core, set by "msgsndp" instruction. The register is shared among
threads of the same core and KVM on POWER9 emulates it in a similar way
(POWER9 does not have DPDES).

DPDES is shared but QEMU assumes all SPRs are per thread so the only safe
way to write DPDES back to VCPU before running a guest is doing so
while all threads are pulled out of the guest so DPDES cannot change.
There is only one situation when this condition is met: incoming migration
when all threads are stopped. Otherwise any QEMU HMP/QMP command causing
kvm_arch_put_registers() (for example printing registers or dumping memory)
can clobber DPDES in a race with other vcpu threads.

This changes DPDES handling so it is not written to KVM at runtime.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Message-Id: <20190923084110.34643-1-aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/kvm.c                | 5 +++++
 target/ppc/translate_init.inc.c | 9 ++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 8c5b1f25cc..820724cc7d 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -993,6 +993,10 @@ int kvm_arch_put_registers(CPUState *cs, int level)
         }
 
         kvm_set_one_reg(cs, KVM_REG_PPC_TB_OFFSET, &env->tb_env->tb_offset);
+
+        if (level > KVM_PUT_RUNTIME_STATE) {
+            kvm_put_one_spr(cs, KVM_REG_PPC_DPDES, SPR_DPDES);
+        }
 #endif /* TARGET_PPC64 */
     }
 
@@ -1297,6 +1301,7 @@ int kvm_arch_get_registers(CPUState *cs)
         }
 
         kvm_get_one_reg(cs, KVM_REG_PPC_TB_OFFSET, &env->tb_env->tb_offset);
+        kvm_get_one_spr(cs, KVM_REG_PPC_DPDES, SPR_DPDES);
 #endif
     }
 
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 0fb11c7ac6..ba726dec4d 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -8200,11 +8200,10 @@ static void gen_spr_power8_dpdes(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     /* Directed Privileged Door-bell Exception State, used for IPI */
-    spr_register_kvm_hv(env, SPR_DPDES, "DPDES",
-                        SPR_NOACCESS, SPR_NOACCESS,
-                        &spr_read_generic, SPR_NOACCESS,
-                        &spr_read_generic, &spr_write_generic,
-                        KVM_REG_PPC_DPDES, 0x00000000);
+    spr_register(env, SPR_DPDES, "DPDES",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, SPR_NOACCESS,
+                 0x00000000);
 #endif
 }
 
-- 
2.21.0



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

* [PULL 15/53] spapr: Simplify handling of pre ISA 3.0 guest workaround handling
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (13 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 14/53] ppc/kvm: Skip writing DPDES back when in run time state David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 16/53] spapr: Move handling of special NVLink numa node from reset to init David Gibson
                   ` (38 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

Certain old guest versions don't understand the radix MMU introduced with
POWER ISA 3.0, but incorrectly select it if presented with the option at
CAS time.  We workaround this in qemu by explicitly excluding the radix
(and other ISA 3.0 linked) options if the guest doesn't explicitly note
support for ISA 3.0.

This is handled by the 'cas_legacy_guest_workaround' flag, which is pretty
vague.  Rename it to 'cas_pre_isa3_guest' to be clearer about what it's for.

In addition, we unnecessarily call spapr_populate_pa_features() with
different options when initially constructing the device tree and when
adjusting it at CAS time.  At the initial construct time cas_pre_isa3_guest
is already false, so we can still use the flag, rather than explicitly
overriding it to be false at the callsite.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 hw/ppc/spapr.c         | 10 ++++------
 hw/ppc/spapr_hcall.c   |  3 +--
 include/hw/ppc/spapr.h |  2 +-
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 2725b139a7..b906ac6547 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -220,8 +220,7 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
 /* Populate the "ibm,pa-features" property */
 static void spapr_populate_pa_features(SpaprMachineState *spapr,
                                        PowerPCCPU *cpu,
-                                       void *fdt, int offset,
-                                       bool legacy_guest)
+                                       void *fdt, int offset)
 {
     uint8_t pa_features_206[] = { 6, 0,
         0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
@@ -287,7 +286,7 @@ static void spapr_populate_pa_features(SpaprMachineState *spapr,
     if ((spapr_get_cap(spapr, SPAPR_CAP_HTM) != 0) && pa_size > 24) {
         pa_features[24] |= 0x80;    /* Transactional memory support */
     }
-    if (legacy_guest && pa_size > 40) {
+    if (spapr->cas_pre_isa3_guest && pa_size > 40) {
         /* Workaround for broken kernels that attempt (guest) radix
          * mode when they can't handle it, if they see the radix bit set
          * in pa-features. So hide it from them. */
@@ -350,8 +349,7 @@ static int spapr_fixup_cpu_dt(void *fdt, SpaprMachineState *spapr)
             return ret;
         }
 
-        spapr_populate_pa_features(spapr, cpu, fdt, offset,
-                                   spapr->cas_legacy_guest_workaround);
+        spapr_populate_pa_features(spapr, cpu, fdt, offset);
     }
     return ret;
 }
@@ -553,7 +551,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
                           page_sizes_prop, page_sizes_prop_size)));
     }
 
-    spapr_populate_pa_features(spapr, cpu, fdt, offset, false);
+    spapr_populate_pa_features(spapr, cpu, fdt, offset);
 
     _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
                            cs->cpu_index / vcpus_per_socket)));
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 23e4bdb829..3d3a67149a 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1765,8 +1765,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
             exit(EXIT_FAILURE);
         }
     }
-    spapr->cas_legacy_guest_workaround = !spapr_ovec_test(ov1_guest,
-                                                          OV1_PPC_3_00);
+    spapr->cas_pre_isa3_guest = !spapr_ovec_test(ov1_guest, OV1_PPC_3_00);
     spapr_ovec_cleanup(ov1_guest);
     if (!spapr->cas_reboot) {
         /* If spapr_machine_reset() did not set up a HPT but one is necessary
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 03111fd55b..dfec8e8e76 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -175,7 +175,7 @@ struct SpaprMachineState {
 
     /* ibm,client-architecture-support option negotiation */
     bool cas_reboot;
-    bool cas_legacy_guest_workaround;
+    bool cas_pre_isa3_guest;
     SpaprOptionVector *ov5;         /* QEMU-supported option vectors */
     SpaprOptionVector *ov5_cas;     /* negotiated (via CAS) option vectors */
     uint32_t max_compat_pvr;
-- 
2.21.0



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

* [PULL 16/53] spapr: Move handling of special NVLink numa node from reset to init
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (14 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 15/53] spapr: Simplify handling of pre ISA 3.0 guest workaround handling David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 17/53] spapr: Fixes a leak in CAS David Gibson
                   ` (37 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

The number of NUMA nodes in the system is fixed from the command line.
Therefore, there's no need to recalculate it at reset time, and we can
determine the special gpu_numa_id value used for NVLink2 devices at init
time.

This simplifies the reset path a bit which will make further improvements
easier.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Tested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 hw/ppc/spapr.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b906ac6547..7c3a443776 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1739,16 +1739,6 @@ static void spapr_machine_reset(MachineState *machine)
         spapr_setup_hpt_and_vrma(spapr);
     }
 
-    /*
-     * NVLink2-connected GPU RAM needs to be placed on a separate NUMA node.
-     * We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is
-     * called from vPHB reset handler so we initialize the counter here.
-     * If no NUMA is configured from the QEMU side, we start from 1 as GPU RAM
-     * must be equally distant from any other node.
-     * The final value of spapr->gpu_numa_id is going to be written to
-     * max-associativity-domains in spapr_build_fdt().
-     */
-    spapr->gpu_numa_id = MAX(1, machine->numa_state->num_nodes);
     qemu_devices_reset();
 
     /*
@@ -2887,6 +2877,17 @@ static void spapr_machine_init(MachineState *machine)
 
     }
 
+    /*
+     * NVLink2-connected GPU RAM needs to be placed on a separate NUMA node.
+     * We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is
+     * called from vPHB reset handler so we initialize the counter here.
+     * If no NUMA is configured from the QEMU side, we start from 1 as GPU RAM
+     * must be equally distant from any other node.
+     * The final value of spapr->gpu_numa_id is going to be written to
+     * max-associativity-domains in spapr_build_fdt().
+     */
+    spapr->gpu_numa_id = MAX(1, machine->numa_state->num_nodes);
+
     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)) {
-- 
2.21.0



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

* [PULL 17/53] spapr: Fixes a leak in CAS
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (15 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 16/53] spapr: Move handling of special NVLink numa node from reset to init David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 18/53] spapr: Skip leading zeroes from memory@ DT node names David Gibson
                   ` (36 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

Add a missing g_free(fdt) if the resulting tree is bigger
than the space allocated by SLOF.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/spapr.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 7c3a443776..c69c034183 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1026,6 +1026,7 @@ int spapr_h_cas_compose_response(SpaprMachineState *spapr,
     _FDT((fdt_pack(fdt)));
 
     if (fdt_totalsize(fdt) + sizeof(hdr) > size) {
+        g_free(fdt);
         trace_spapr_cas_failed(size);
         return -1;
     }
-- 
2.21.0



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

* [PULL 18/53] spapr: Skip leading zeroes from memory@ DT node names
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (16 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 17/53] spapr: Fixes a leak in CAS David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 19/53] spapr: Do not put empty properties for -kernel/-initrd/-append David Gibson
                   ` (35 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

The device tree build by QEMU at the machine reset time is used by SLOF
to build its internal device tree but the node names are not preserved
exactly so when QEMU provides a device tree update in response to H_CAS,
it might become tricky to match a node from the update blob to
the actual node in SLOF.

This removed leading zeroes from "memory@" nodes and makes
the DTC checker happy.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index c69c034183..42a5b8d2fd 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -388,7 +388,7 @@ static int spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start,
     mem_reg_property[0] = cpu_to_be64(start);
     mem_reg_property[1] = cpu_to_be64(size);
 
-    sprintf(mem_name, "memory@" TARGET_FMT_lx, start);
+    sprintf(mem_name, "memory@%" HWADDR_PRIx, start);
     off = fdt_add_subnode(fdt, 0, mem_name);
     _FDT(off);
     _FDT((fdt_setprop_string(fdt, off, "device_type", "memory")));
-- 
2.21.0



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

* [PULL 19/53] spapr: Do not put empty properties for -kernel/-initrd/-append
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (17 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 18/53] spapr: Skip leading zeroes from memory@ DT node names David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 20/53] spapr: Stop providing RTAS blob David Gibson
                   ` (34 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

We are going to use spapr_build_fdt() for the boot time FDT and as an
update for SLOF during handling of H_CAS. SLOF will apply all properties
from the QEMU's FDT which is usually ok unless there are properties
changed by grub or guest kernel. The properties are:
bootargs, linux,initrd-start, linux,initrd-end, linux,stdout-path,
linux,rtas-base, linux,rtas-entry. Resetting those during CAS will most
likely cause grub failure.

Don't create such properties if we're booting without "-kernel" and
"-initrd" so they won't get included into the DT update blob and
therefore the guest is more likely to boot successfully.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
[dwg: Tweaked commit message based on Greg Kurz's input]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 42a5b8d2fd..f1c57c21cc 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1179,11 +1179,16 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt)
 
     _FDT(chosen = fdt_add_subnode(fdt, 0, "chosen"));
 
-    _FDT(fdt_setprop_string(fdt, chosen, "bootargs", machine->kernel_cmdline));
-    _FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-start",
-                          spapr->initrd_base));
-    _FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-end",
-                          spapr->initrd_base + spapr->initrd_size));
+    if (machine->kernel_cmdline && machine->kernel_cmdline[0]) {
+        _FDT(fdt_setprop_string(fdt, chosen, "bootargs",
+                                machine->kernel_cmdline));
+    }
+    if (spapr->initrd_size) {
+        _FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-start",
+                              spapr->initrd_base));
+        _FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-end",
+                              spapr->initrd_base + spapr->initrd_size));
+    }
 
     if (spapr->kernel_size) {
         uint64_t kprop[2] = { cpu_to_be64(KERNEL_LOAD_ADDR),
-- 
2.21.0



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

* [PULL 20/53] spapr: Stop providing RTAS blob
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (18 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 19/53] spapr: Do not put empty properties for -kernel/-initrd/-append David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 21/53] pseries: Update SLOF firmware image David Gibson
                   ` (33 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

SLOF implements one itself so let's remove it from QEMU. It is one less
image and simpler setup as the RTAS blob never stays in its initial place
anyway as the guest OS always decides where to put it.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 MAINTAINERS                     |   2 --
 Makefile                        |   2 +-
 configure                       |   6 +----
 hw/ppc/spapr.c                  |  32 ++-----------------------
 hw/ppc/spapr_rtas.c             |  41 --------------------------------
 include/hw/ppc/spapr.h          |   2 --
 pc-bios/spapr-rtas.bin          | Bin 20 -> 0 bytes
 pc-bios/spapr-rtas/Makefile     |  27 ---------------------
 pc-bios/spapr-rtas/spapr-rtas.S |  37 ----------------------------
 9 files changed, 4 insertions(+), 145 deletions(-)
 delete mode 100644 pc-bios/spapr-rtas.bin
 delete mode 100644 pc-bios/spapr-rtas/Makefile
 delete mode 100644 pc-bios/spapr-rtas/spapr-rtas.S

diff --git a/MAINTAINERS b/MAINTAINERS
index 21264eae9c..3ca814850e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1077,8 +1077,6 @@ F: hw/*/spapr*
 F: include/hw/*/spapr*
 F: hw/*/xics*
 F: include/hw/*/xics*
-F: pc-bios/spapr-rtas/*
-F: pc-bios/spapr-rtas.bin
 F: pc-bios/slof.bin
 F: docs/specs/ppc-spapr-hcalls.txt
 F: docs/specs/ppc-spapr-hotplug.txt
diff --git a/Makefile b/Makefile
index 8da33595ed..30f0abfb42 100644
--- a/Makefile
+++ b/Makefile
@@ -769,7 +769,7 @@ qemu-nsis.bmp \
 bamboo.dtb canyonlands.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
 multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin pvh.bin \
 s390-ccw.img s390-netboot.img \
-spapr-rtas.bin slof.bin skiboot.lid \
+slof.bin skiboot.lid \
 palcode-clipper \
 u-boot.e500 u-boot-sam460-20100605.bin \
 qemu_vga.ndrv \
diff --git a/configure b/configure
index 8f8446f52b..08ca4bcb46 100755
--- a/configure
+++ b/configure
@@ -6166,9 +6166,6 @@ if { test "$cpu" = "i386" || test "$cpu" = "x86_64"; } && \
         fi
     done
 fi
-if test "$ARCH" = "ppc64" && test "$targetos" != "Darwin" ; then
-  roms="$roms spapr-rtas"
-fi
 
 # Only build s390-ccw bios if we're on s390x and the compiler has -march=z900
 if test "$cpu" = "s390x" ; then
@@ -7800,13 +7797,12 @@ fi
 DIRS="tests tests/tcg tests/tcg/lm32 tests/libqos tests/qapi-schema tests/qemu-iotests tests/vm"
 DIRS="$DIRS tests/fp tests/qgraph"
 DIRS="$DIRS docs docs/interop fsdev scsi"
-DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
+DIRS="$DIRS pc-bios/optionrom pc-bios/s390-ccw"
 DIRS="$DIRS roms/seabios roms/vgabios"
 LINKS="Makefile"
 LINKS="$LINKS tests/tcg/lm32/Makefile po/Makefile"
 LINKS="$LINKS tests/tcg/Makefile.target tests/fp/Makefile"
 LINKS="$LINKS pc-bios/optionrom/Makefile pc-bios/keymaps"
-LINKS="$LINKS pc-bios/spapr-rtas/Makefile"
 LINKS="$LINKS pc-bios/s390-ccw/Makefile"
 LINKS="$LINKS roms/seabios/Makefile roms/vgabios/Makefile"
 LINKS="$LINKS pc-bios/qemu-icon.bmp"
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f1c57c21cc..3742a8cf06 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_SIZE           0x10000
 #define RTAS_MAX_ADDR           0x80000000 /* RTAS must stay below that */
 #define FW_MAX_SIZE             0x400000
 #define FW_FILE_NAME            "slof.bin"
@@ -1723,8 +1722,7 @@ static void spapr_machine_reset(MachineState *machine)
 {
     SpaprMachineState *spapr = SPAPR_MACHINE(machine);
     PowerPCCPU *first_ppc_cpu;
-    uint32_t rtas_limit;
-    hwaddr rtas_addr, fdt_addr;
+    hwaddr fdt_addr;
     void *fdt;
     int rc;
 
@@ -1788,14 +1786,10 @@ static void spapr_machine_reset(MachineState *machine)
      * or just below 2GB, whichever is lower, so that it can be
      * processed with 32-bit real mode code if necessary
      */
-    rtas_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR);
-    rtas_addr = rtas_limit - RTAS_MAX_SIZE;
-    fdt_addr = rtas_addr - FDT_MAX_SIZE;
+    fdt_addr = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FDT_MAX_SIZE;
 
     fdt = spapr_build_fdt(spapr);
 
-    spapr_load_rtas(spapr, fdt, rtas_addr);
-
     rc = fdt_pack(fdt);
 
     /* Should only fail if we've built a corrupted tree */
@@ -2955,28 +2949,6 @@ static void spapr_machine_init(MachineState *machine)
         spapr_create_lmb_dr_connectors(spapr);
     }
 
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
-    if (!filename) {
-        error_report("Could not find LPAR rtas '%s'", "spapr-rtas.bin");
-        exit(1);
-    }
-    spapr->rtas_size = get_image_size(filename);
-    if (spapr->rtas_size < 0) {
-        error_report("Could not get size of LPAR rtas '%s'", filename);
-        exit(1);
-    }
-    spapr->rtas_blob = g_malloc(spapr->rtas_size);
-    if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
-        error_report("Could not load LPAR rtas '%s'", filename);
-        exit(1);
-    }
-    if (spapr->rtas_size > RTAS_MAX_SIZE) {
-        error_report("RTAS too big ! 0x%zx bytes (max is 0x%x)",
-                     (size_t)spapr->rtas_size, RTAS_MAX_SIZE);
-        exit(1);
-    }
-    g_free(filename);
-
     /* Set up RTAS event infrastructure */
     spapr_events_init(spapr);
 
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index bee3835214..8d8d8cdfcb 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -477,47 +477,6 @@ void spapr_dt_rtas_tokens(void *fdt, int rtas)
     }
 }
 
-void spapr_load_rtas(SpaprMachineState *spapr, void *fdt, hwaddr addr)
-{
-    int rtas_node;
-    int ret;
-
-    /* Copy RTAS blob into guest RAM */
-    cpu_physical_memory_write(addr, spapr->rtas_blob, spapr->rtas_size);
-
-    ret = fdt_add_mem_rsv(fdt, addr, spapr->rtas_size);
-    if (ret < 0) {
-        error_report("Couldn't add RTAS reserve entry: %s",
-                     fdt_strerror(ret));
-        exit(1);
-    }
-
-    /* Update the device tree with the blob's location */
-    rtas_node = fdt_path_offset(fdt, "/rtas");
-    assert(rtas_node >= 0);
-
-    ret = fdt_setprop_cell(fdt, rtas_node, "linux,rtas-base", addr);
-    if (ret < 0) {
-        error_report("Couldn't add linux,rtas-base property: %s",
-                     fdt_strerror(ret));
-        exit(1);
-    }
-
-    ret = fdt_setprop_cell(fdt, rtas_node, "linux,rtas-entry", addr);
-    if (ret < 0) {
-        error_report("Couldn't add linux,rtas-entry property: %s",
-                     fdt_strerror(ret));
-        exit(1);
-    }
-
-    ret = fdt_setprop_cell(fdt, rtas_node, "rtas-size", spapr->rtas_size);
-    if (ret < 0) {
-        error_report("Couldn't add rtas-size property: %s",
-                     fdt_strerror(ret));
-        exit(1);
-    }
-}
-
 static void core_rtas_register_types(void)
 {
     spapr_rtas_register(RTAS_DISPLAY_CHARACTER, "display-character",
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index dfec8e8e76..cbd1a4c9f3 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -154,8 +154,6 @@ struct SpaprMachineState {
 
     hwaddr rma_size;
     int vrma_adjust;
-    ssize_t rtas_size;
-    void *rtas_blob;
     uint32_t fdt_size;
     uint32_t fdt_initial_size;
     void *fdt_blob;
diff --git a/pc-bios/spapr-rtas.bin b/pc-bios/spapr-rtas.bin
deleted file mode 100644
index fc24c8ed8b92a3a441aed6e2bd013b2ccece9229..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 20
bcmb<Pk*=^wU|>i{{=neEz@X&Uz@PvCJTV0q

diff --git a/pc-bios/spapr-rtas/Makefile b/pc-bios/spapr-rtas/Makefile
deleted file mode 100644
index 4b9bb12306..0000000000
--- a/pc-bios/spapr-rtas/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-all: build-all
-# Dummy command so that make thinks it has done something
-	@true
-
-include ../../config-host.mak
-include $(SRC_PATH)/rules.mak
-
-$(call set-vpath, $(SRC_PATH)/pc-bios/spapr-rtas)
-
-.PHONY : all clean build-all
-
-#CFLAGS += -I$(SRC_PATH)
-#QEMU_CFLAGS = $(CFLAGS)
-
-build-all: spapr-rtas.bin
-
-%.o: %.S
-	$(call quiet-command,$(CCAS) -mbig -c -o $@ $<,"CCAS","$(TARGET_DIR)$@")
-
-%.img: %.o
-	$(call quiet-command,$(CC) -nostdlib -mbig -o $@ $<,"Building","$(TARGET_DIR)$@")
-
-%.bin: %.img
-	$(call quiet-command,$(OBJCOPY) -O binary -j .text $< $@,"Building","$(TARGET_DIR)$@")
-
-clean:
-	rm -f *.o *.d *.img *.bin *~
diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
deleted file mode 100644
index 903bec2150..0000000000
--- a/pc-bios/spapr-rtas/spapr-rtas.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
- *
- * Trivial in-partition RTAS implementation, based on a hypercall
- *
- * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-
-#define KVMPPC_HCALL_BASE       0xf000
-#define KVMPPC_H_RTAS           (KVMPPC_HCALL_BASE + 0x0)
-
-.globl	_start
-_start:
-	mr	4,3
-	lis	3,KVMPPC_H_RTAS@h
-	ori	3,3,KVMPPC_H_RTAS@l
-	sc	1
-	blr
-- 
2.21.0



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

* [PULL 21/53] pseries: Update SLOF firmware image
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (19 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 20/53] spapr: Stop providing RTAS blob David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 22/53] target/ppc: introduce get_dfp{64, 128}() helper functions David Gibson
                   ` (32 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

This fixes USB host bus adapter name in the device tree to match QEMU's
one.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 pc-bios/README   |   2 +-
 pc-bios/slof.bin | Bin 930656 -> 930640 bytes
 roms/SLOF        |   2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pc-bios/README b/pc-bios/README
index ad78f6dc49..0b0b5d42ad 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -17,7 +17,7 @@
 - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
   implementation for certain IBM POWER hardware.  The sources are at
   https://github.com/aik/SLOF, and the image currently in qemu is
-  built from git tag qemu-slof-20190827.
+  built from git tag qemu-slof-20190911.
 
 - sgabios (the Serial Graphics Adapter option ROM) provides a means for
   legacy x86 software to communicate with an attached serial console as
diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin
index a3a3e4933278461a08c8b58ad0da6741bb6b3d1b..2af0c5d5fc0c6aa06c34016f6deb767700ad4d3f 100644
GIT binary patch
delta 329
zcmaFx%;Lf`iwWjp0qL0~x=G2&#>pnBrpZQziG``Tr3RA~8D-fNBsm4eR3;XP@Lb<`
zv*14z0Hypk-dkiZfUL>D&@^rH1cxn57Qv|n3WkOXMh1qK3WjD@MkZE9hP+$~Zs7`H
zsYS(^`FRSq3g}jXb=Nq1A0=CN`+p8bAZ7w$W*}w(Vpbq#+y0+}ed9$bjjSK(%0kNn
zO^x%LuLq|Ec!*A#>F(@orJyl=tsb9j`}14uK+FNeoIuP4#N6AT-{P5Yo3n!f44A#A
cH*Di|V=q=xC@oG>+J1K%Z+#8Rvgsum0R3EcBme*a

delta 345
zcmccc%;Lc_iwWjp3F(<7x~YjqMuuhv28o7-W`(J_r3RA~8D-fNBstW@%qJFz@LZZ%
z`13y$0Hypk-dkiZfUL>F!q{;01cxn57LKLq3P$D%Mh1qK3WjD@#^zQAmb_dFZs7`H
zsYS(^`FRSq3g}jXb=Nq1A0=CN`+p8bAZ7w$W*}w(Vpbq#+y0+}ed9$bN9!%GngbU&
zADehRaI;IBl7`udz3$G=Rtg%^=j!pvwm-kc4#XTl%n8I?K+L`U`7NFaw>f7pfB|##
t^oDJ`ZsJM`rNv1~3PvfV1qvytWtqvTx_ODYsoT$P<E^h@VfK2g4FEIEd71zK

diff --git a/roms/SLOF b/roms/SLOF
index ea221600a1..bcc3c4e5c2 160000
--- a/roms/SLOF
+++ b/roms/SLOF
@@ -1 +1 @@
-Subproject commit ea221600a116883137ef90b2b7ab7d2472bc4f10
+Subproject commit bcc3c4e5c21a015f4680894c4ec978a90d4a2d69
-- 
2.21.0



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

* [PULL 22/53] target/ppc: introduce get_dfp{64, 128}() helper functions
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (20 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 21/53] pseries: Update SLOF firmware image David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 23/53] target/ppc: introduce set_dfp{64, " David Gibson
                   ` (31 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, Mark Cave-Ayland, qemu-devel,
	groug, qemu-ppc, clg, David Gibson

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

The existing functions (now incorrectly) assume that the MSB and LSB of DFP
numbers are stored as consecutive 64-bit words in memory. Instead of accessing
the DFP numbers directly, introduce get_dfp{64,128}() helper functions to ease
the switch to the correct representation.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190926185801.11176-2-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/dfp_helper.c | 52 ++++++++++++++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 13 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 753399177c..e4369ebe9b 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -36,6 +36,17 @@
 #define LO_IDX 0
 #endif
 
+static void get_dfp64(uint64_t *dst, uint64_t *dfp)
+{
+    dst[0] = dfp[0];
+}
+
+static void get_dfp128(uint64_t *dst, uint64_t *dfp)
+{
+    dst[0] = dfp[HI_IDX];
+    dst[1] = dfp[LO_IDX];
+}
+
 struct PPC_DFP {
     CPUPPCState *env;
     uint64_t t64[2], a64[2], b64[2];
@@ -129,7 +140,7 @@ static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a,
     dfp->env = env;
 
     if (a) {
-        dfp->a64[0] = *a;
+        get_dfp64(dfp->a64, a);
         decimal64ToNumber((decimal64 *)dfp->a64, &dfp->a);
     } else {
         dfp->a64[0] = 0;
@@ -137,7 +148,7 @@ static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a,
     }
 
     if (b) {
-        dfp->b64[0] = *b;
+        get_dfp64(dfp->b64, b);
         decimal64ToNumber((decimal64 *)dfp->b64, &dfp->b);
     } else {
         dfp->b64[0] = 0;
@@ -153,8 +164,7 @@ static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a,
     dfp->env = env;
 
     if (a) {
-        dfp->a64[0] = a[HI_IDX];
-        dfp->a64[1] = a[LO_IDX];
+        get_dfp128(dfp->a64, a);
         decimal128ToNumber((decimal128 *)dfp->a64, &dfp->a);
     } else {
         dfp->a64[0] = dfp->a64[1] = 0;
@@ -162,8 +172,7 @@ static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a,
     }
 
     if (b) {
-        dfp->b64[0] = b[HI_IDX];
-        dfp->b64[1] = b[LO_IDX];
+        get_dfp128(dfp->b64, b);
         decimal128ToNumber((decimal128 *)dfp->b64, &dfp->b);
     } else {
         dfp->b64[0] = dfp->b64[1] = 0;
@@ -617,10 +626,12 @@ uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b)         \
 {                                                                        \
     struct PPC_DFP dfp;                                                  \
     unsigned k;                                                          \
+    uint64_t a64;                                                        \
                                                                          \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                          \
                                                                          \
-    k = *a & 0x3F;                                                       \
+    get_dfp64(&a64, a);                                                  \
+    k = a64 & 0x3F;                                                      \
                                                                          \
     if (unlikely(decNumberIsSpecial(&dfp.b))) {                          \
         dfp.crbf = 1;                                                    \
@@ -817,11 +828,15 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,            \
                  uint64_t *b, uint32_t rmc)                             \
 {                                                                       \
     struct PPC_DFP dfp;                                                 \
-    int32_t ref_sig = *a & 0x3F;                                        \
+    uint64_t a64;                                                       \
+    int32_t ref_sig;                                                    \
     int32_t xmax = ((size) == 64) ? 369 : 6111;                         \
                                                                         \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                         \
                                                                         \
+    get_dfp64(&a64, a);                                                 \
+    ref_sig = a64 & 0x3f;                                               \
+                                                                        \
     _dfp_reround(rmc, ref_sig, xmax, &dfp);                             \
     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
                               &dfp.context);                            \
@@ -881,7 +896,12 @@ DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
 void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
 {
     struct PPC_DFP dfp;
-    uint32_t b_short = *b;
+    uint64_t b64;
+    uint32_t b_short;
+
+    get_dfp64(&b64, b);
+    b_short = (uint32_t)b64;
+
     dfp_prepare_decimal64(&dfp, 0, 0, env);
     decimal32ToNumber((decimal32 *)&b_short, &dfp.t);
     decimal64FromNumber((decimal64 *)t, &dfp.t, &dfp.context);
@@ -891,8 +911,10 @@ void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
 void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
 {
     struct PPC_DFP dfp;
+    uint64_t b64;
     dfp_prepare_decimal128(&dfp, 0, 0, env);
-    decimal64ToNumber((decimal64 *)b, &dfp.t);
+    get_dfp64(&b64, b);
+    decimal64ToNumber((decimal64 *)&b64, &dfp.t);
 
     dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
     dfp_set_FPRF_from_FRT(&dfp);
@@ -940,8 +962,10 @@ void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)                   \
 {                                                                              \
     struct PPC_DFP dfp;                                                        \
+    uint64_t b64;                                                              \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                                \
-    decNumberFromInt64(&dfp.t, (int64_t)(*b));                                 \
+    get_dfp64(&b64, b);                                                        \
+    decNumberFromInt64(&dfp.t, (int64_t)b64);                                  \
     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
     CFFIX_PPs(&dfp);                                                           \
                                                                                \
@@ -1183,10 +1207,12 @@ static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw)
 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
 {                                                                         \
     struct PPC_DFP dfp;                                                   \
-    uint64_t raw_qnan, raw_snan, raw_inf, max_exp;                        \
+    uint64_t raw_qnan, raw_snan, raw_inf, max_exp, a64;                   \
     int bias;                                                             \
-    int64_t exp = *((int64_t *)a);                                        \
+    int64_t exp;                                                          \
                                                                           \
+    get_dfp64(&a64, a);                                                   \
+    exp = (int64_t)a64;                                                   \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                           \
                                                                           \
     if ((size) == 64) {                                                   \
-- 
2.21.0



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

* [PULL 23/53] target/ppc: introduce set_dfp{64, 128}() helper functions
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (21 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 22/53] target/ppc: introduce get_dfp{64, 128}() helper functions David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 24/53] target/ppc: update {get, set}_dfp{64, 128}() helper functions to read/write DFP numbers correctly David Gibson
                   ` (30 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, Mark Cave-Ayland, qemu-devel,
	groug, qemu-ppc, clg, David Gibson

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

The existing functions (now incorrectly) assume that the MSB and LSB of DFP
numbers are stored as consecutive 64-bit words in memory. Instead of accessing
the DFP numbers directly, introduce set_dfp{64,128}() helper functions to ease
the switch to the correct representation.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190926185801.11176-3-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/dfp_helper.c | 90 ++++++++++++++++++++++-------------------
 1 file changed, 48 insertions(+), 42 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index e4369ebe9b..3923a072b2 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -47,6 +47,17 @@ static void get_dfp128(uint64_t *dst, uint64_t *dfp)
     dst[1] = dfp[LO_IDX];
 }
 
+static void set_dfp64(uint64_t *dfp, uint64_t *src)
+{
+    dfp[0] = src[0];
+}
+
+static void set_dfp128(uint64_t *dfp, uint64_t *src)
+{
+    dfp[0] = src[HI_IDX];
+    dfp[1] = src[LO_IDX];
+}
+
 struct PPC_DFP {
     CPUPPCState *env;
     uint64_t t64[2], a64[2], b64[2];
@@ -413,10 +424,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b)      \
     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
     postprocs(&dfp);                                                           \
     if (size == 64) {                                                          \
-        t[0] = dfp.t64[0];                                                     \
+        set_dfp64(t, dfp.t64);                                                 \
     } else if (size == 128) {                                                  \
-        t[0] = dfp.t64[HI_IDX];                                                \
-        t[1] = dfp.t64[LO_IDX];                                                \
+        set_dfp128(t, dfp.t64);                                                \
     }                                                                          \
 }
 
@@ -735,10 +745,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b,            \
     QUA_PPs(&dfp);                                                      \
                                                                         \
     if (size == 64) {                                                   \
-        t[0] = dfp.t64[0];                                              \
+        set_dfp64(t, dfp.t64);                                          \
     } else if (size == 128) {                                           \
-        t[0] = dfp.t64[HI_IDX];                                         \
-        t[1] = dfp.t64[LO_IDX];                                         \
+        set_dfp128(t, dfp.t64);                                         \
     }                                                                   \
 }
 
@@ -759,10 +768,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,            \
     QUA_PPs(&dfp);                                                      \
                                                                         \
     if (size == 64) {                                                   \
-        t[0] = dfp.t64[0];                                              \
+        set_dfp64(t, dfp.t64);                                          \
     } else if (size == 128) {                                           \
-        t[0] = dfp.t64[HI_IDX];                                         \
-        t[1] = dfp.t64[LO_IDX];                                         \
+        set_dfp128(t, dfp.t64);                                         \
     }                                                                   \
 }
 
@@ -843,10 +851,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,            \
     QUA_PPs(&dfp);                                                      \
                                                                         \
     if (size == 64) {                                                   \
-        t[0] = dfp.t64[0];                                              \
+        set_dfp64(t, dfp.t64);                                          \
     } else if (size == 128) {                                           \
-        t[0] = dfp.t64[HI_IDX];                                         \
-        t[1] = dfp.t64[LO_IDX];                                         \
+        set_dfp128(t, dfp.t64);                                         \
     }                                                                   \
 }
 
@@ -867,10 +874,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b,                   \
     postprocs(&dfp);                                                           \
                                                                                \
     if (size == 64) {                                                          \
-        t[0] = dfp.t64[0];                                                     \
+        set_dfp64(t, dfp.t64);                                                 \
     } else if (size == 128) {                                                  \
-        t[0] = dfp.t64[HI_IDX];                                                \
-        t[1] = dfp.t64[LO_IDX];                                                \
+        set_dfp128(t, dfp.t64);                                                \
     }                                                                          \
 }
 
@@ -904,7 +910,8 @@ void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
 
     dfp_prepare_decimal64(&dfp, 0, 0, env);
     decimal32ToNumber((decimal32 *)&b_short, &dfp.t);
-    decimal64FromNumber((decimal64 *)t, &dfp.t, &dfp.context);
+    decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.t, &dfp.context);
+    set_dfp64(t, dfp.t64);
     dfp_set_FPRF_from_FRT(&dfp);
 }
 
@@ -920,14 +927,14 @@ void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
     dfp_set_FPRF_from_FRT(&dfp);
 
     decimal128FromNumber((decimal128 *)&dfp.t64, &dfp.t, &dfp.context);
-    t[0] = dfp.t64[HI_IDX];
-    t[1] = dfp.t64[LO_IDX];
+    set_dfp128(t, dfp.t64);
 }
 
 void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b)
 {
     struct PPC_DFP dfp;
     uint32_t t_short = 0;
+    uint64_t t64;
     dfp_prepare_decimal64(&dfp, 0, b, env);
     decimal32FromNumber((decimal32 *)&t_short, &dfp.b, &dfp.context);
     decimal32ToNumber((decimal32 *)&t_short, &dfp.t);
@@ -937,7 +944,8 @@ void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b)
     dfp_check_for_UX(&dfp);
     dfp_check_for_XX(&dfp);
 
-    *t = t_short;
+    t64 = (uint64_t)t_short;
+    set_dfp64(t, &t64);
 }
 
 void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
@@ -953,9 +961,9 @@ void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
     dfp_check_for_UX(&dfp);
     dfp_check_for_XX(&dfp);
 
+    dfp.t64[0] = dfp.t64[1] = 0;
     decimal64FromNumber((decimal64 *)dfp.t64, &dfp.t, &dfp.context);
-    t[0] = dfp.t64[0];
-    t[1] = 0;
+    set_dfp128(t, dfp.t64);
 }
 
 #define DFP_HELPER_CFFIX(op, size)                                             \
@@ -970,10 +978,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)                   \
     CFFIX_PPs(&dfp);                                                           \
                                                                                \
     if (size == 64) {                                                          \
-        t[0] = dfp.t64[0];                                                     \
+        set_dfp64(t, dfp.t64);                                                 \
     } else if (size == 128) {                                                  \
-        t[0] = dfp.t64[HI_IDX];                                                \
-        t[1] = dfp.t64[LO_IDX];                                                \
+        set_dfp128(t, dfp.t64);                                                \
     }                                                                          \
 }
 
@@ -1016,7 +1023,7 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)                  \
         }                                                                     \
     }                                                                         \
                                                                               \
-    *t = dfp.t64[0];                                                          \
+    set_dfp64(t, dfp.t64);                                                    \
 }
 
 DFP_HELPER_CTFIX(dctfix, 64)
@@ -1078,10 +1085,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \
     }                                                                     \
                                                                           \
     if (size == 64) {                                                     \
-        t[0] = dfp.t64[0];                                                \
+        set_dfp64(t, dfp.t64);                                            \
     } else if (size == 128) {                                             \
-        t[0] = dfp.t64[HI_IDX];                                           \
-        t[1] = dfp.t64[LO_IDX];                                           \
+        set_dfp128(t, dfp.t64);                                           \
     }                                                                     \
 }
 
@@ -1150,10 +1156,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s)     \
                               &dfp.context);                                 \
     dfp_set_FPRF_from_FRT(&dfp);                                             \
     if ((size) == 64) {                                                      \
-        t[0] = dfp.t64[0];                                                   \
+        set_dfp64(t, dfp.t64);                                               \
     } else if ((size) == 128) {                                              \
-        t[0] = dfp.t64[HI_IDX];                                              \
-        t[1] = dfp.t64[LO_IDX];                                              \
+        set_dfp128(t, dfp.t64);                                              \
     }                                                                        \
 }
 
@@ -1164,27 +1169,30 @@ DFP_HELPER_ENBCD(denbcdq, 128)
 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)   \
 {                                                              \
     struct PPC_DFP dfp;                                        \
+    uint64_t t64;                                              \
                                                                \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                \
                                                                \
     if (unlikely(decNumberIsSpecial(&dfp.b))) {                \
         if (decNumberIsInfinite(&dfp.b)) {                     \
-            *t = -1;                                           \
+            t64 = -1;                                          \
         } else if (decNumberIsSNaN(&dfp.b)) {                  \
-            *t = -3;                                           \
+            t64 = -3;                                          \
         } else if (decNumberIsQNaN(&dfp.b)) {                  \
-            *t = -2;                                           \
+            t64 = -2;                                          \
         } else {                                               \
             assert(0);                                         \
         }                                                      \
+        set_dfp64(t, &t64);                                    \
     } else {                                                   \
         if ((size) == 64) {                                    \
-            *t = dfp.b.exponent + 398;                         \
+            t64 = dfp.b.exponent + 398;                        \
         } else if ((size) == 128) {                            \
-            *t = dfp.b.exponent + 6176;                        \
+            t64 = dfp.b.exponent + 6176;                       \
         } else {                                               \
             assert(0);                                         \
         }                                                      \
+        set_dfp64(t, &t64);                                    \
     }                                                          \
 }
 
@@ -1251,10 +1259,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
                                   &dfp.context);                          \
     }                                                                     \
     if (size == 64) {                                                     \
-        t[0] = dfp.t64[0];                                                \
+        set_dfp64(t, dfp.t64);                                            \
     } else if (size == 128) {                                             \
-        t[0] = dfp.t64[HI_IDX];                                           \
-        t[1] = dfp.t64[LO_IDX];                                           \
+        set_dfp128(t, dfp.t64);                                           \
     }                                                                     \
 }
 
@@ -1344,10 +1351,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,        \
     }                                                               \
                                                                     \
     if ((size) == 64) {                                             \
-        t[0] = dfp.t64[0];                                          \
+        set_dfp64(t, dfp.t64);                                      \
     } else {                                                        \
-        t[0] = dfp.t64[HI_IDX];                                     \
-        t[1] = dfp.t64[LO_IDX];                                     \
+        set_dfp128(t, dfp.t64);                                     \
     }                                                               \
 }
 
-- 
2.21.0



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

* [PULL 24/53] target/ppc: update {get, set}_dfp{64, 128}() helper functions to read/write DFP numbers correctly
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (22 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 23/53] target/ppc: introduce set_dfp{64, " David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 25/53] target/ppc: introduce dfp_finalize_decimal{64, 128}() helper functions David Gibson
                   ` (29 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, Mark Cave-Ayland, qemu-devel,
	groug, qemu-ppc, clg, David Gibson

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Since commit ef96e3ae96 "target/ppc: move FP and VMX registers into aligned vsr
register array" FP registers are no longer stored consecutively in memory and so
the current method of combining FP register pairs into DFP numbers is incorrect.

Firstly update the definition of the dh_*_fprp defines in helper.h to reflect
that FP registers are now stored as part of an array of ppc_vsr_t elements
rather than plain uint64_t elements, and then introduce a new ppc_fprp_t type
which conceptually represents a DFP even-odd register pair to be consumed by the
DFP helper functions.

Finally update the new DFP {get,set}_dfp{64,128}() helper functions to convert
between DFP numbers and DFP even-odd register pairs correctly, making use of the
existing VsrD() macro to access the correct elements regardless of host endian.

Fixes: ef96e3ae96 "target/ppc: move FP and VMX registers into aligned vsr register array"
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190926185801.11176-4-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/cpu.h        |  1 +
 target/ppc/dfp_helper.c | 80 +++++++++++++++++++++--------------------
 target/ppc/helper.h     |  2 +-
 3 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index a23c6455b9..e3e82327b7 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -235,6 +235,7 @@ typedef union _ppc_vsr_t {
 } ppc_vsr_t;
 
 typedef ppc_vsr_t ppc_avr_t;
+typedef ppc_vsr_t ppc_fprp_t;
 
 #if !defined(CONFIG_USER_ONLY)
 /* Software TLB cache */
diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 3923a072b2..ab5e91d8ed 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -36,26 +36,26 @@
 #define LO_IDX 0
 #endif
 
-static void get_dfp64(uint64_t *dst, uint64_t *dfp)
+static void get_dfp64(uint64_t *dst, ppc_fprp_t *dfp)
 {
-    dst[0] = dfp[0];
+    dst[0] = dfp->VsrD(0);
 }
 
-static void get_dfp128(uint64_t *dst, uint64_t *dfp)
+static void get_dfp128(uint64_t *dst, ppc_fprp_t *dfp)
 {
-    dst[0] = dfp[HI_IDX];
-    dst[1] = dfp[LO_IDX];
+    dst[HI_IDX] = dfp[0].VsrD(0);
+    dst[LO_IDX] = dfp[1].VsrD(0);
 }
 
-static void set_dfp64(uint64_t *dfp, uint64_t *src)
+static void set_dfp64(ppc_fprp_t *dfp, uint64_t *src)
 {
-    dfp[0] = src[0];
+    dfp->VsrD(0) = src[0];
 }
 
-static void set_dfp128(uint64_t *dfp, uint64_t *src)
+static void set_dfp128(ppc_fprp_t *dfp, uint64_t *src)
 {
-    dfp[0] = src[HI_IDX];
-    dfp[1] = src[LO_IDX];
+    dfp[0].VsrD(0) = src[HI_IDX];
+    dfp[1].VsrD(0) = src[LO_IDX];
 }
 
 struct PPC_DFP {
@@ -143,8 +143,8 @@ static void dfp_set_round_mode_from_immediate(uint8_t r, uint8_t rmc,
     decContextSetRounding(&dfp->context, rnd);
 }
 
-static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a,
-                uint64_t *b, CPUPPCState *env)
+static void dfp_prepare_decimal64(struct PPC_DFP *dfp, ppc_fprp_t *a,
+                                  ppc_fprp_t *b, CPUPPCState *env)
 {
     decContextDefault(&dfp->context, DEC_INIT_DECIMAL64);
     dfp_prepare_rounding_mode(&dfp->context, env->fpscr);
@@ -167,8 +167,8 @@ static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a,
     }
 }
 
-static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a,
-                uint64_t *b, CPUPPCState *env)
+static void dfp_prepare_decimal128(struct PPC_DFP *dfp, ppc_fprp_t *a,
+                                   ppc_fprp_t *b, CPUPPCState *env)
 {
     decContextDefault(&dfp->context, DEC_INIT_DECIMAL128);
     dfp_prepare_rounding_mode(&dfp->context, env->fpscr);
@@ -416,7 +416,8 @@ static inline int dfp_get_digit(decNumber *dn, int n)
 }
 
 #define DFP_HELPER_TAB(op, dnop, postprocs, size)                              \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b)      \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,               \
+                 ppc_fprp_t *b)                                                \
 {                                                                              \
     struct PPC_DFP dfp;                                                        \
     dfp_prepare_decimal##size(&dfp, a, b, env);                                \
@@ -485,7 +486,7 @@ DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
 DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
 
 #define DFP_HELPER_BF_AB(op, dnop, postprocs, size)                            \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b)               \
+uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)           \
 {                                                                              \
     struct PPC_DFP dfp;                                                        \
     dfp_prepare_decimal##size(&dfp, a, b, env);                                \
@@ -517,7 +518,7 @@ DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
 DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
 
 #define DFP_HELPER_TSTDC(op, size)                                       \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm)        \
+uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)      \
 {                                                                        \
     struct PPC_DFP dfp;                                                  \
     int match = 0;                                                       \
@@ -545,7 +546,7 @@ DFP_HELPER_TSTDC(dtstdc, 64)
 DFP_HELPER_TSTDC(dtstdcq, 128)
 
 #define DFP_HELPER_TSTDG(op, size)                                       \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm)        \
+uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)      \
 {                                                                        \
     struct PPC_DFP dfp;                                                  \
     int minexp, maxexp, nzero_digits, nzero_idx, is_negative, is_zero,   \
@@ -600,7 +601,7 @@ DFP_HELPER_TSTDG(dtstdg, 64)
 DFP_HELPER_TSTDG(dtstdgq, 128)
 
 #define DFP_HELPER_TSTEX(op, size)                                       \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b)         \
+uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)     \
 {                                                                        \
     struct PPC_DFP dfp;                                                  \
     int expa, expb, a_is_special, b_is_special;                          \
@@ -632,7 +633,7 @@ DFP_HELPER_TSTEX(dtstex, 64)
 DFP_HELPER_TSTEX(dtstexq, 128)
 
 #define DFP_HELPER_TSTSF(op, size)                                       \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b)         \
+uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)     \
 {                                                                        \
     struct PPC_DFP dfp;                                                  \
     unsigned k;                                                          \
@@ -669,7 +670,7 @@ DFP_HELPER_TSTSF(dtstsf, 64)
 DFP_HELPER_TSTSF(dtstsfq, 128)
 
 #define DFP_HELPER_TSTSFI(op, size)                                     \
-uint32_t helper_##op(CPUPPCState *env, uint32_t a, uint64_t *b)         \
+uint32_t helper_##op(CPUPPCState *env, uint32_t a, ppc_fprp_t *b)       \
 {                                                                       \
     struct PPC_DFP dfp;                                                 \
     unsigned uim;                                                       \
@@ -729,7 +730,7 @@ static void dfp_quantize(uint8_t rmc, struct PPC_DFP *dfp)
 }
 
 #define DFP_HELPER_QUAI(op, size)                                       \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b,            \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,        \
                  uint32_t te, uint32_t rmc)                             \
 {                                                                       \
     struct PPC_DFP dfp;                                                 \
@@ -755,8 +756,8 @@ DFP_HELPER_QUAI(dquai, 64)
 DFP_HELPER_QUAI(dquaiq, 128)
 
 #define DFP_HELPER_QUA(op, size)                                        \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,            \
-                 uint64_t *b, uint32_t rmc)                             \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,        \
+                 ppc_fprp_t *b, uint32_t rmc)                           \
 {                                                                       \
     struct PPC_DFP dfp;                                                 \
                                                                         \
@@ -832,8 +833,8 @@ static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
 }
 
 #define DFP_HELPER_RRND(op, size)                                       \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,            \
-                 uint64_t *b, uint32_t rmc)                             \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,        \
+                 ppc_fprp_t *b, uint32_t rmc)                           \
 {                                                                       \
     struct PPC_DFP dfp;                                                 \
     uint64_t a64;                                                       \
@@ -861,7 +862,7 @@ DFP_HELPER_RRND(drrnd, 64)
 DFP_HELPER_RRND(drrndq, 128)
 
 #define DFP_HELPER_RINT(op, postprocs, size)                                   \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b,                   \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,               \
              uint32_t r, uint32_t rmc)                                         \
 {                                                                              \
     struct PPC_DFP dfp;                                                        \
@@ -899,7 +900,7 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
 DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
 
-void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
+void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
     struct PPC_DFP dfp;
     uint64_t b64;
@@ -915,7 +916,7 @@ void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
     dfp_set_FPRF_from_FRT(&dfp);
 }
 
-void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
+void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
     struct PPC_DFP dfp;
     uint64_t b64;
@@ -930,7 +931,7 @@ void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
     set_dfp128(t, dfp.t64);
 }
 
-void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b)
+void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
     struct PPC_DFP dfp;
     uint32_t t_short = 0;
@@ -948,7 +949,7 @@ void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b)
     set_dfp64(t, &t64);
 }
 
-void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
+void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
     struct PPC_DFP dfp;
     dfp_prepare_decimal128(&dfp, 0, b, env);
@@ -967,7 +968,7 @@ void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
 }
 
 #define DFP_HELPER_CFFIX(op, size)                                             \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)                   \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)               \
 {                                                                              \
     struct PPC_DFP dfp;                                                        \
     uint64_t b64;                                                              \
@@ -994,7 +995,7 @@ DFP_HELPER_CFFIX(dcffix, 64)
 DFP_HELPER_CFFIX(dcffixq, 128)
 
 #define DFP_HELPER_CTFIX(op, size)                                            \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)                  \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)              \
 {                                                                             \
     struct PPC_DFP dfp;                                                       \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                               \
@@ -1057,7 +1058,8 @@ static inline void dfp_set_sign_128(uint64_t *t, uint8_t sgn)
 }
 
 #define DFP_HELPER_DEDPD(op, size)                                        \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,          \
+                 uint32_t sp)                                             \
 {                                                                         \
     struct PPC_DFP dfp;                                                   \
     uint8_t digits[34];                                                   \
@@ -1105,7 +1107,8 @@ static inline uint8_t dfp_get_bcd_digit_128(uint64_t *t, unsigned n)
 }
 
 #define DFP_HELPER_ENBCD(op, size)                                           \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s)     \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,             \
+                 uint32_t s)                                                 \
 {                                                                            \
     struct PPC_DFP dfp;                                                      \
     uint8_t digits[32];                                                      \
@@ -1166,7 +1169,7 @@ DFP_HELPER_ENBCD(denbcd, 64)
 DFP_HELPER_ENBCD(denbcdq, 128)
 
 #define DFP_HELPER_XEX(op, size)                               \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)   \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
 {                                                              \
     struct PPC_DFP dfp;                                        \
     uint64_t t64;                                              \
@@ -1212,7 +1215,8 @@ static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw)
 }
 
 #define DFP_HELPER_IEX(op, size)                                          \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,          \
+                 ppc_fprp_t *b)                                           \
 {                                                                         \
     struct PPC_DFP dfp;                                                   \
     uint64_t raw_qnan, raw_snan, raw_inf, max_exp, a64;                   \
@@ -1309,7 +1313,7 @@ static void dfp_clear_lmd_from_g5msb(uint64_t *t)
 }
 
 #define DFP_HELPER_SHIFT(op, size, shift_left)                      \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,        \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,    \
                  uint32_t sh)                                       \
 {                                                                   \
     struct PPC_DFP dfp;                                             \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 54ea9b9500..f843814b8a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -686,7 +686,7 @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl)
 #endif
 
 #define dh_alias_fprp ptr
-#define dh_ctype_fprp uint64_t *
+#define dh_ctype_fprp ppc_fprp_t *
 #define dh_is_signed_fprp dh_is_signed_ptr
 
 DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
-- 
2.21.0



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

* [PULL 25/53] target/ppc: introduce dfp_finalize_decimal{64, 128}() helper functions
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (23 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 24/53] target/ppc: update {get, set}_dfp{64, 128}() helper functions to read/write DFP numbers correctly David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 26/53] target/ppc: change struct PPC_DFP decimal storage from uint64[2] to ppc_vsr_t David Gibson
                   ` (28 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, Mark Cave-Ayland, qemu-devel,
	groug, qemu-ppc, clg, David Gibson

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Most of the DFP helper functions call decimal{64,128}FromNumber() just before
returning in order to convert the decNumber stored in dfp.t64 back to a
Decimal{64,128} to write back to the FP registers.

Introduce new dfp_finalize_decimal{64,128}() helper functions which both enable
the parameter list to be reduced considerably, and also help minimise the
changes required in the next patch.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190926185801.11176-5-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/dfp_helper.c | 42 ++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index ab5e91d8ed..8e1ea2971a 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -191,6 +191,16 @@ static void dfp_prepare_decimal128(struct PPC_DFP *dfp, ppc_fprp_t *a,
     }
 }
 
+static void dfp_finalize_decimal64(struct PPC_DFP *dfp)
+{
+    decimal64FromNumber((decimal64 *)&dfp->t64, &dfp->t, &dfp->context);
+}
+
+static void dfp_finalize_decimal128(struct PPC_DFP *dfp)
+{
+    decimal128FromNumber((decimal128 *)&dfp->t64, &dfp->t, &dfp->context);
+}
+
 static void dfp_set_FPSCR_flag(struct PPC_DFP *dfp, uint64_t flag,
                 uint64_t enabled)
 {
@@ -422,7 +432,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,               \
     struct PPC_DFP dfp;                                                        \
     dfp_prepare_decimal##size(&dfp, a, b, env);                                \
     dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context);                                \
-    decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
+    dfp_finalize_decimal##size(&dfp);                                          \
     postprocs(&dfp);                                                           \
     if (size == 64) {                                                          \
         set_dfp64(t, dfp.t64);                                                 \
@@ -491,7 +501,7 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)           \
     struct PPC_DFP dfp;                                                        \
     dfp_prepare_decimal##size(&dfp, a, b, env);                                \
     dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context);                                \
-    decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
+    dfp_finalize_decimal##size(&dfp);                                          \
     postprocs(&dfp);                                                           \
     return dfp.crbf;                                                           \
 }
@@ -741,8 +751,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,        \
     dfp.a.exponent = (int32_t)((int8_t)(te << 3) >> 3);                 \
                                                                         \
     dfp_quantize(rmc, &dfp);                                            \
-    decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
-                              &dfp.context);                            \
+    dfp_finalize_decimal##size(&dfp);                                   \
     QUA_PPs(&dfp);                                                      \
                                                                         \
     if (size == 64) {                                                   \
@@ -764,8 +773,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,        \
     dfp_prepare_decimal##size(&dfp, a, b, env);                         \
                                                                         \
     dfp_quantize(rmc, &dfp);                                            \
-    decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
-                              &dfp.context);                            \
+    dfp_finalize_decimal##size(&dfp);                                   \
     QUA_PPs(&dfp);                                                      \
                                                                         \
     if (size == 64) {                                                   \
@@ -847,8 +855,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,        \
     ref_sig = a64 & 0x3f;                                               \
                                                                         \
     _dfp_reround(rmc, ref_sig, xmax, &dfp);                             \
-    decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
-                              &dfp.context);                            \
+    dfp_finalize_decimal##size(&dfp);                                   \
     QUA_PPs(&dfp);                                                      \
                                                                         \
     if (size == 64) {                                                   \
@@ -871,7 +878,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,               \
                                                                                \
     dfp_set_round_mode_from_immediate(r, rmc, &dfp);                           \
     decNumberToIntegralExact(&dfp.t, &dfp.b, &dfp.context);                    \
-    decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
+    dfp_finalize_decimal##size(&dfp);                                          \
     postprocs(&dfp);                                                           \
                                                                                \
     if (size == 64) {                                                          \
@@ -911,7 +918,7 @@ void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 
     dfp_prepare_decimal64(&dfp, 0, 0, env);
     decimal32ToNumber((decimal32 *)&b_short, &dfp.t);
-    decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.t, &dfp.context);
+    dfp_finalize_decimal64(&dfp);
     set_dfp64(t, dfp.t64);
     dfp_set_FPRF_from_FRT(&dfp);
 }
@@ -927,7 +934,7 @@ void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
     dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
     dfp_set_FPRF_from_FRT(&dfp);
 
-    decimal128FromNumber((decimal128 *)&dfp.t64, &dfp.t, &dfp.context);
+    dfp_finalize_decimal128(&dfp);
     set_dfp128(t, dfp.t64);
 }
 
@@ -963,7 +970,7 @@ void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
     dfp_check_for_XX(&dfp);
 
     dfp.t64[0] = dfp.t64[1] = 0;
-    decimal64FromNumber((decimal64 *)dfp.t64, &dfp.t, &dfp.context);
+    dfp_finalize_decimal64(&dfp);
     set_dfp128(t, dfp.t64);
 }
 
@@ -975,7 +982,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)               \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                                \
     get_dfp64(&b64, b);                                                        \
     decNumberFromInt64(&dfp.t, (int64_t)b64);                                  \
-    decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
+    dfp_finalize_decimal##size(&dfp);                                          \
     CFFIX_PPs(&dfp);                                                           \
                                                                                \
     if (size == 64) {                                                          \
@@ -1155,8 +1162,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,             \
     if (s && sgn)  {                                                         \
         dfp.t.bits |= DECNEG;                                                \
     }                                                                        \
-    decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,              \
-                              &dfp.context);                                 \
+    dfp_finalize_decimal##size(&dfp);                                        \
     dfp_set_FPRF_from_FRT(&dfp);                                             \
     if ((size) == 64) {                                                      \
         set_dfp64(t, dfp.t64);                                               \
@@ -1259,8 +1265,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,          \
             dfp.t.bits &= ~DECSPECIAL;                                    \
         }                                                                 \
         dfp.t.exponent = exp - bias;                                      \
-        decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,       \
-                                  &dfp.context);                          \
+        dfp_finalize_decimal##size(&dfp);                                 \
     }                                                                     \
     if (size == 64) {                                                     \
         set_dfp64(t, dfp.t64);                                            \
@@ -1340,8 +1345,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,    \
             dfp.t.digits = max_digits - 1;                          \
         }                                                           \
                                                                     \
-        decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
-                                  &dfp.context);                    \
+        dfp_finalize_decimal##size(&dfp);                           \
     } else {                                                        \
         if ((size) == 64) {                                         \
             dfp.t64[0] = dfp.a64[0] & 0xFFFC000000000000ULL;        \
-- 
2.21.0



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

* [PULL 26/53] target/ppc: change struct PPC_DFP decimal storage from uint64[2] to ppc_vsr_t
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (24 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 25/53] target/ppc: introduce dfp_finalize_decimal{64, 128}() helper functions David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 27/53] target/ppc: use existing VsrD() macro to eliminate HI_IDX and LO_IDX from dfp_helper.c David Gibson
                   ` (27 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, Mark Cave-Ayland, qemu-devel,
	groug, qemu-ppc, clg, David Gibson

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

There are several places in dfp_helper.c that access the decimal number
representations in struct PPC_DFP via HI_IDX and LO_IDX defines which are set
at the top of dfp_helper.c according to the host endian.

However we can instead switch to using ppc_vsr_t for decimal numbers and then
make subsequent use of the existing VsrD() macros to access the correct
element regardless of host endian. Note that 64-bit decimals are stored in the
LSB of ppc_vsr_t (equivalent to VsrD(1)).

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190926185801.11176-6-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/dfp_helper.c | 210 +++++++++++++++++++++-------------------
 1 file changed, 108 insertions(+), 102 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 8e1ea2971a..b72084d50a 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -36,31 +36,31 @@
 #define LO_IDX 0
 #endif
 
-static void get_dfp64(uint64_t *dst, ppc_fprp_t *dfp)
+static void get_dfp64(ppc_vsr_t *dst, ppc_fprp_t *dfp)
 {
-    dst[0] = dfp->VsrD(0);
+    dst->VsrD(1) = dfp->VsrD(0);
 }
 
-static void get_dfp128(uint64_t *dst, ppc_fprp_t *dfp)
+static void get_dfp128(ppc_vsr_t *dst, ppc_fprp_t *dfp)
 {
-    dst[HI_IDX] = dfp[0].VsrD(0);
-    dst[LO_IDX] = dfp[1].VsrD(0);
+    dst->VsrD(0) = dfp[0].VsrD(0);
+    dst->VsrD(1) = dfp[1].VsrD(0);
 }
 
-static void set_dfp64(ppc_fprp_t *dfp, uint64_t *src)
+static void set_dfp64(ppc_fprp_t *dfp, ppc_vsr_t *src)
 {
-    dfp->VsrD(0) = src[0];
+    dfp->VsrD(0) = src->VsrD(1);
 }
 
-static void set_dfp128(ppc_fprp_t *dfp, uint64_t *src)
+static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src)
 {
-    dfp[0].VsrD(0) = src[HI_IDX];
-    dfp[1].VsrD(0) = src[LO_IDX];
+    dfp[0].VsrD(0) = src->VsrD(0);
+    dfp[1].VsrD(0) = src->VsrD(1);
 }
 
 struct PPC_DFP {
     CPUPPCState *env;
-    uint64_t t64[2], a64[2], b64[2];
+    ppc_vsr_t vt, va, vb;
     decNumber t, a, b;
     decContext context;
     uint8_t crbf;
@@ -151,18 +151,18 @@ static void dfp_prepare_decimal64(struct PPC_DFP *dfp, ppc_fprp_t *a,
     dfp->env = env;
 
     if (a) {
-        get_dfp64(dfp->a64, a);
-        decimal64ToNumber((decimal64 *)dfp->a64, &dfp->a);
+        get_dfp64(&dfp->va, a);
+        decimal64ToNumber((decimal64 *)&dfp->va.VsrD(1), &dfp->a);
     } else {
-        dfp->a64[0] = 0;
+        dfp->va.VsrD(1) = 0;
         decNumberZero(&dfp->a);
     }
 
     if (b) {
-        get_dfp64(dfp->b64, b);
-        decimal64ToNumber((decimal64 *)dfp->b64, &dfp->b);
+        get_dfp64(&dfp->vb, b);
+        decimal64ToNumber((decimal64 *)&dfp->vb.VsrD(1), &dfp->b);
     } else {
-        dfp->b64[0] = 0;
+        dfp->vb.VsrD(1) = 0;
         decNumberZero(&dfp->b);
     }
 }
@@ -175,30 +175,30 @@ static void dfp_prepare_decimal128(struct PPC_DFP *dfp, ppc_fprp_t *a,
     dfp->env = env;
 
     if (a) {
-        get_dfp128(dfp->a64, a);
-        decimal128ToNumber((decimal128 *)dfp->a64, &dfp->a);
+        get_dfp128(&dfp->va, a);
+        decimal128ToNumber((decimal128 *)&dfp->va, &dfp->a);
     } else {
-        dfp->a64[0] = dfp->a64[1] = 0;
+        dfp->va.VsrD(0) = dfp->va.VsrD(1) = 0;
         decNumberZero(&dfp->a);
     }
 
     if (b) {
-        get_dfp128(dfp->b64, b);
-        decimal128ToNumber((decimal128 *)dfp->b64, &dfp->b);
+        get_dfp128(&dfp->vb, b);
+        decimal128ToNumber((decimal128 *)&dfp->vb, &dfp->b);
     } else {
-        dfp->b64[0] = dfp->b64[1] = 0;
+        dfp->vb.VsrD(0) = dfp->vb.VsrD(1) = 0;
         decNumberZero(&dfp->b);
     }
 }
 
 static void dfp_finalize_decimal64(struct PPC_DFP *dfp)
 {
-    decimal64FromNumber((decimal64 *)&dfp->t64, &dfp->t, &dfp->context);
+    decimal64FromNumber((decimal64 *)&dfp->vt.VsrD(1), &dfp->t, &dfp->context);
 }
 
 static void dfp_finalize_decimal128(struct PPC_DFP *dfp)
 {
-    decimal128FromNumber((decimal128 *)&dfp->t64, &dfp->t, &dfp->context);
+    decimal128FromNumber((decimal128 *)&dfp->vt, &dfp->t, &dfp->context);
 }
 
 static void dfp_set_FPSCR_flag(struct PPC_DFP *dfp, uint64_t flag,
@@ -435,9 +435,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,               \
     dfp_finalize_decimal##size(&dfp);                                          \
     postprocs(&dfp);                                                           \
     if (size == 64) {                                                          \
-        set_dfp64(t, dfp.t64);                                                 \
+        set_dfp64(t, &dfp.vt);                                                 \
     } else if (size == 128) {                                                  \
-        set_dfp128(t, dfp.t64);                                                \
+        set_dfp128(t, &dfp.vt);                                                \
     }                                                                          \
 }
 
@@ -647,12 +647,12 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)     \
 {                                                                        \
     struct PPC_DFP dfp;                                                  \
     unsigned k;                                                          \
-    uint64_t a64;                                                        \
+    ppc_vsr_t va;                                                        \
                                                                          \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                          \
                                                                          \
-    get_dfp64(&a64, a);                                                  \
-    k = a64 & 0x3F;                                                      \
+    get_dfp64(&va, a);                                                   \
+    k = va.VsrD(1) & 0x3F;                                               \
                                                                          \
     if (unlikely(decNumberIsSpecial(&dfp.b))) {                          \
         dfp.crbf = 1;                                                    \
@@ -755,9 +755,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,        \
     QUA_PPs(&dfp);                                                      \
                                                                         \
     if (size == 64) {                                                   \
-        set_dfp64(t, dfp.t64);                                          \
+        set_dfp64(t, &dfp.vt);                                          \
     } else if (size == 128) {                                           \
-        set_dfp128(t, dfp.t64);                                         \
+        set_dfp128(t, &dfp.vt);                                         \
     }                                                                   \
 }
 
@@ -777,9 +777,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,        \
     QUA_PPs(&dfp);                                                      \
                                                                         \
     if (size == 64) {                                                   \
-        set_dfp64(t, dfp.t64);                                          \
+        set_dfp64(t, &dfp.vt);                                          \
     } else if (size == 128) {                                           \
-        set_dfp128(t, dfp.t64);                                         \
+        set_dfp128(t, &dfp.vt);                                         \
     }                                                                   \
 }
 
@@ -845,23 +845,23 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,        \
                  ppc_fprp_t *b, uint32_t rmc)                           \
 {                                                                       \
     struct PPC_DFP dfp;                                                 \
-    uint64_t a64;                                                       \
+    ppc_vsr_t va;                                                       \
     int32_t ref_sig;                                                    \
     int32_t xmax = ((size) == 64) ? 369 : 6111;                         \
                                                                         \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                         \
                                                                         \
-    get_dfp64(&a64, a);                                                 \
-    ref_sig = a64 & 0x3f;                                               \
+    get_dfp64(&va, a);                                                  \
+    ref_sig = va.VsrD(1) & 0x3f;                                        \
                                                                         \
     _dfp_reround(rmc, ref_sig, xmax, &dfp);                             \
     dfp_finalize_decimal##size(&dfp);                                   \
     QUA_PPs(&dfp);                                                      \
                                                                         \
     if (size == 64) {                                                   \
-        set_dfp64(t, dfp.t64);                                          \
+        set_dfp64(t, &dfp.vt);                                          \
     } else if (size == 128) {                                           \
-        set_dfp128(t, dfp.t64);                                         \
+        set_dfp128(t, &dfp.vt);                                         \
     }                                                                   \
 }
 
@@ -882,9 +882,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,               \
     postprocs(&dfp);                                                           \
                                                                                \
     if (size == 64) {                                                          \
-        set_dfp64(t, dfp.t64);                                                 \
+        set_dfp64(t, &dfp.vt);                                                 \
     } else if (size == 128) {                                                  \
-        set_dfp128(t, dfp.t64);                                                \
+        set_dfp128(t, &dfp.vt);                                                \
     }                                                                          \
 }
 
@@ -910,39 +910,39 @@ DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
 void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
     struct PPC_DFP dfp;
-    uint64_t b64;
+    ppc_vsr_t vb;
     uint32_t b_short;
 
-    get_dfp64(&b64, b);
-    b_short = (uint32_t)b64;
+    get_dfp64(&vb, b);
+    b_short = (uint32_t)vb.VsrD(1);
 
     dfp_prepare_decimal64(&dfp, 0, 0, env);
     decimal32ToNumber((decimal32 *)&b_short, &dfp.t);
     dfp_finalize_decimal64(&dfp);
-    set_dfp64(t, dfp.t64);
+    set_dfp64(t, &dfp.vt);
     dfp_set_FPRF_from_FRT(&dfp);
 }
 
 void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
     struct PPC_DFP dfp;
-    uint64_t b64;
+    ppc_vsr_t vb;
     dfp_prepare_decimal128(&dfp, 0, 0, env);
-    get_dfp64(&b64, b);
-    decimal64ToNumber((decimal64 *)&b64, &dfp.t);
+    get_dfp64(&vb, b);
+    decimal64ToNumber((decimal64 *)&vb.VsrD(1), &dfp.t);
 
     dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
     dfp_set_FPRF_from_FRT(&dfp);
 
     dfp_finalize_decimal128(&dfp);
-    set_dfp128(t, dfp.t64);
+    set_dfp128(t, &dfp.vt);
 }
 
 void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
     struct PPC_DFP dfp;
     uint32_t t_short = 0;
-    uint64_t t64;
+    ppc_vsr_t vt;
     dfp_prepare_decimal64(&dfp, 0, b, env);
     decimal32FromNumber((decimal32 *)&t_short, &dfp.b, &dfp.context);
     decimal32ToNumber((decimal32 *)&t_short, &dfp.t);
@@ -952,16 +952,16 @@ void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
     dfp_check_for_UX(&dfp);
     dfp_check_for_XX(&dfp);
 
-    t64 = (uint64_t)t_short;
-    set_dfp64(t, &t64);
+    vt.VsrD(1) = (uint64_t)t_short;
+    set_dfp64(t, &vt);
 }
 
 void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
     struct PPC_DFP dfp;
     dfp_prepare_decimal128(&dfp, 0, b, env);
-    decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.b, &dfp.context);
-    decimal64ToNumber((decimal64 *)&dfp.t64, &dfp.t);
+    decimal64FromNumber((decimal64 *)&dfp.vt.VsrD(1), &dfp.b, &dfp.context);
+    decimal64ToNumber((decimal64 *)&dfp.vt.VsrD(1), &dfp.t);
 
     dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
     dfp_set_FPRF_from_FRT_long(&dfp);
@@ -969,26 +969,26 @@ void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
     dfp_check_for_UX(&dfp);
     dfp_check_for_XX(&dfp);
 
-    dfp.t64[0] = dfp.t64[1] = 0;
+    dfp.vt.VsrD(0) = dfp.vt.VsrD(1) = 0;
     dfp_finalize_decimal64(&dfp);
-    set_dfp128(t, dfp.t64);
+    set_dfp128(t, &dfp.vt);
 }
 
 #define DFP_HELPER_CFFIX(op, size)                                             \
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)               \
 {                                                                              \
     struct PPC_DFP dfp;                                                        \
-    uint64_t b64;                                                              \
+    ppc_vsr_t vb;                                                              \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                                \
-    get_dfp64(&b64, b);                                                        \
-    decNumberFromInt64(&dfp.t, (int64_t)b64);                                  \
+    get_dfp64(&vb, b);                                                         \
+    decNumberFromInt64(&dfp.t, (int64_t)vb.VsrD(1));                           \
     dfp_finalize_decimal##size(&dfp);                                          \
     CFFIX_PPs(&dfp);                                                           \
                                                                                \
     if (size == 64) {                                                          \
-        set_dfp64(t, dfp.t64);                                                 \
+        set_dfp64(t, &dfp.vt);                                                 \
     } else if (size == 128) {                                                  \
-        set_dfp128(t, dfp.t64);                                                \
+        set_dfp128(t, &dfp.vt);                                                \
     }                                                                          \
 }
 
@@ -1010,28 +1010,30 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)              \
     if (unlikely(decNumberIsSpecial(&dfp.b))) {                               \
         uint64_t invalid_flags = FP_VX | FP_VXCVI;                            \
         if (decNumberIsInfinite(&dfp.b)) {                                    \
-            dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
+            dfp.vt.VsrD(1) = decNumberIsNegative(&dfp.b) ? INT64_MIN :        \
+                                                           INT64_MAX;         \
         } else { /* NaN */                                                    \
-            dfp.t64[0] = INT64_MIN;                                           \
+            dfp.vt.VsrD(1) = INT64_MIN;                                       \
             if (decNumberIsSNaN(&dfp.b)) {                                    \
                 invalid_flags |= FP_VXSNAN;                                   \
             }                                                                 \
         }                                                                     \
         dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE);                       \
     } else if (unlikely(decNumberIsZero(&dfp.b))) {                           \
-        dfp.t64[0] = 0;                                                       \
+        dfp.vt.VsrD(1) = 0;                                                   \
     } else {                                                                  \
         decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context);               \
-        dfp.t64[0] = decNumberIntegralToInt64(&dfp.b, &dfp.context);          \
+        dfp.vt.VsrD(1) = decNumberIntegralToInt64(&dfp.b, &dfp.context);      \
         if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) {      \
-            dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
+            dfp.vt.VsrD(1) = decNumberIsNegative(&dfp.b) ? INT64_MIN :        \
+                                                           INT64_MAX;         \
             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE);                \
         } else {                                                              \
             dfp_check_for_XX(&dfp);                                           \
         }                                                                     \
     }                                                                         \
                                                                               \
-    set_dfp64(t, dfp.t64);                                                    \
+    set_dfp64(t, &dfp.vt);                                                    \
 }
 
 DFP_HELPER_CTFIX(dctfix, 64)
@@ -1075,11 +1077,11 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,          \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                           \
                                                                           \
     decNumberGetBCD(&dfp.b, digits);                                      \
-    dfp.t64[0] = dfp.t64[1] = 0;                                          \
+    dfp.vt.VsrD(0) = dfp.vt.VsrD(1) = 0;                                  \
     N = dfp.b.digits;                                                     \
                                                                           \
     for (i = 0; (i < N) && (i < (size)/4); i++) {                         \
-        dfp_set_bcd_digit_##size(dfp.t64, digits[N-i-1], i);              \
+        dfp_set_bcd_digit_##size(&dfp.vt.u64[0], digits[N - i - 1], i);   \
     }                                                                     \
                                                                           \
     if (sp & 2) {                                                         \
@@ -1090,13 +1092,13 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,          \
         } else {                                                          \
             sgn = ((sp & 1) ? 0xF : 0xC);                                 \
         }                                                                 \
-        dfp_set_sign_##size(dfp.t64, sgn);                                \
+        dfp_set_sign_##size(&dfp.vt.u64[0], sgn);                         \
     }                                                                     \
                                                                           \
     if (size == 64) {                                                     \
-        set_dfp64(t, dfp.t64);                                            \
+        set_dfp64(t, &dfp.vt);                                            \
     } else if (size == 128) {                                             \
-        set_dfp128(t, dfp.t64);                                           \
+        set_dfp128(t, &dfp.vt);                                           \
     }                                                                     \
 }
 
@@ -1126,7 +1128,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,             \
     decNumberZero(&dfp.t);                                                   \
                                                                              \
     if (s) {                                                                 \
-        uint8_t sgnNibble = dfp_get_bcd_digit_##size(dfp.b64, offset++);     \
+        uint8_t sgnNibble = dfp_get_bcd_digit_##size(&dfp.vb.u64[0],         \
+                                                     offset++);              \
         switch (sgnNibble) {                                                 \
         case 0xD:                                                            \
         case 0xB:                                                            \
@@ -1146,7 +1149,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,             \
                                                                              \
     while (offset < (size) / 4) {                                            \
         n++;                                                                 \
-        digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(dfp.b64, offset++); \
+        digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(&dfp.vb.u64[0],    \
+                                                          offset++);         \
         if (digits[(size) / 4 - n] > 10) {                                   \
             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);            \
             return;                                                          \
@@ -1165,9 +1169,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,             \
     dfp_finalize_decimal##size(&dfp);                                        \
     dfp_set_FPRF_from_FRT(&dfp);                                             \
     if ((size) == 64) {                                                      \
-        set_dfp64(t, dfp.t64);                                               \
+        set_dfp64(t, &dfp.vt);                                               \
     } else if ((size) == 128) {                                              \
-        set_dfp128(t, dfp.t64);                                              \
+        set_dfp128(t, &dfp.vt);                                              \
     }                                                                        \
 }
 
@@ -1178,30 +1182,30 @@ DFP_HELPER_ENBCD(denbcdq, 128)
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
 {                                                              \
     struct PPC_DFP dfp;                                        \
-    uint64_t t64;                                              \
+    ppc_vsr_t vt;                                              \
                                                                \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                \
                                                                \
     if (unlikely(decNumberIsSpecial(&dfp.b))) {                \
         if (decNumberIsInfinite(&dfp.b)) {                     \
-            t64 = -1;                                          \
+            vt.VsrD(1) = -1;                                   \
         } else if (decNumberIsSNaN(&dfp.b)) {                  \
-            t64 = -3;                                          \
+            vt.VsrD(1) = -3;                                   \
         } else if (decNumberIsQNaN(&dfp.b)) {                  \
-            t64 = -2;                                          \
+            vt.VsrD(1) = -2;                                   \
         } else {                                               \
             assert(0);                                         \
         }                                                      \
-        set_dfp64(t, &t64);                                    \
+        set_dfp64(t, &vt);                                     \
     } else {                                                   \
         if ((size) == 64) {                                    \
-            t64 = dfp.b.exponent + 398;                        \
+            vt.VsrD(1) = dfp.b.exponent + 398;                 \
         } else if ((size) == 128) {                            \
-            t64 = dfp.b.exponent + 6176;                       \
+            vt.VsrD(1) = dfp.b.exponent + 6176;                \
         } else {                                               \
             assert(0);                                         \
         }                                                      \
-        set_dfp64(t, &t64);                                    \
+        set_dfp64(t, &vt);                                     \
     }                                                          \
 }
 
@@ -1225,12 +1229,13 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,          \
                  ppc_fprp_t *b)                                           \
 {                                                                         \
     struct PPC_DFP dfp;                                                   \
-    uint64_t raw_qnan, raw_snan, raw_inf, max_exp, a64;                   \
+    uint64_t raw_qnan, raw_snan, raw_inf, max_exp;                        \
+    ppc_vsr_t va;                                                         \
     int bias;                                                             \
     int64_t exp;                                                          \
                                                                           \
-    get_dfp64(&a64, a);                                                   \
-    exp = (int64_t)a64;                                                   \
+    get_dfp64(&va, a);                                                    \
+    exp = (int64_t)va.VsrD(1);                                            \
     dfp_prepare_decimal##size(&dfp, 0, b, env);                           \
                                                                           \
     if ((size) == 64) {                                                   \
@@ -1250,14 +1255,14 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,          \
     }                                                                     \
                                                                           \
     if (unlikely((exp < 0) || (exp > max_exp))) {                         \
-        dfp.t64[0] = dfp.b64[0];                                          \
-        dfp.t64[1] = dfp.b64[1];                                          \
+        dfp.vt.VsrD(0) = dfp.vb.VsrD(0);                                  \
+        dfp.vt.VsrD(1) = dfp.vb.VsrD(1);                                  \
         if (exp == -1) {                                                  \
-            dfp_set_raw_exp_##size(dfp.t64, raw_inf);                     \
+            dfp_set_raw_exp_##size(&dfp.vt.u64[0], raw_inf);              \
         } else if (exp == -3) {                                           \
-            dfp_set_raw_exp_##size(dfp.t64, raw_snan);                    \
+            dfp_set_raw_exp_##size(&dfp.vt.u64[0], raw_snan);             \
         } else {                                                          \
-            dfp_set_raw_exp_##size(dfp.t64, raw_qnan);                    \
+            dfp_set_raw_exp_##size(&dfp.vt.u64[0], raw_qnan);             \
         }                                                                 \
     } else {                                                              \
         dfp.t = dfp.b;                                                    \
@@ -1268,9 +1273,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,          \
         dfp_finalize_decimal##size(&dfp);                                 \
     }                                                                     \
     if (size == 64) {                                                     \
-        set_dfp64(t, dfp.t64);                                            \
+        set_dfp64(t, &dfp.vt);                                            \
     } else if (size == 128) {                                             \
-        set_dfp128(t, dfp.t64);                                           \
+        set_dfp128(t, &dfp.vt);                                           \
     }                                                                     \
 }
 
@@ -1348,20 +1353,21 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,    \
         dfp_finalize_decimal##size(&dfp);                           \
     } else {                                                        \
         if ((size) == 64) {                                         \
-            dfp.t64[0] = dfp.a64[0] & 0xFFFC000000000000ULL;        \
-            dfp_clear_lmd_from_g5msb(dfp.t64);                      \
+            dfp.vt.VsrD(1) = dfp.va.VsrD(1) &                       \
+                             0xFFFC000000000000ULL;                 \
+            dfp_clear_lmd_from_g5msb(&dfp.vt.VsrD(1));              \
         } else {                                                    \
-            dfp.t64[HI_IDX] = dfp.a64[HI_IDX] &                     \
-                              0xFFFFC00000000000ULL;                \
-            dfp_clear_lmd_from_g5msb(dfp.t64 + HI_IDX);             \
-            dfp.t64[LO_IDX] = 0;                                    \
+            dfp.vt.VsrD(0) = dfp.va.VsrD(0) &                       \
+                             0xFFFFC00000000000ULL;                 \
+            dfp_clear_lmd_from_g5msb(&dfp.vt.VsrD(0));              \
+            dfp.vt.VsrD(1) = 0;                                     \
         }                                                           \
     }                                                               \
                                                                     \
     if ((size) == 64) {                                             \
-        set_dfp64(t, dfp.t64);                                      \
+        set_dfp64(t, &dfp.vt);                                      \
     } else {                                                        \
-        set_dfp128(t, dfp.t64);                                     \
+        set_dfp128(t, &dfp.vt);                                     \
     }                                                               \
 }
 
-- 
2.21.0



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

* [PULL 27/53] target/ppc: use existing VsrD() macro to eliminate HI_IDX and LO_IDX from dfp_helper.c
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (25 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 26/53] target/ppc: change struct PPC_DFP decimal storage from uint64[2] to ppc_vsr_t David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 28/53] target/ppc: remove unnecessary if() around calls to set_dfp{64, 128}() in DFP macros David Gibson
                   ` (26 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, Mark Cave-Ayland, qemu-devel,
	groug, qemu-ppc, clg, David Gibson

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Switch over all accesses to the decimal numbers held in struct PPC_DFP from
using HI_IDX and LO_IDX to using the VsrD() macro instead. Not only does this
allow the compiler to ensure that the various dfp_* functions are being passed
a ppc_vsr_t rather than an arbitrary uint64_t pointer, but also allows the
host endian-specific HI_IDX and LO_IDX to be completely removed from
dfp_helper.c.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190926185801.11176-7-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/dfp_helper.c | 70 ++++++++++++++++++-----------------------
 1 file changed, 31 insertions(+), 39 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index b72084d50a..c2bb458a78 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -28,13 +28,6 @@
 #include "libdecnumber/dpd/decimal64.h"
 #include "libdecnumber/dpd/decimal128.h"
 
-#if defined(HOST_WORDS_BIGENDIAN)
-#define HI_IDX 0
-#define LO_IDX 1
-#else
-#define HI_IDX 1
-#define LO_IDX 0
-#endif
 
 static void get_dfp64(ppc_vsr_t *dst, ppc_fprp_t *dfp)
 {
@@ -1039,31 +1032,31 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)              \
 DFP_HELPER_CTFIX(dctfix, 64)
 DFP_HELPER_CTFIX(dctfixq, 128)
 
-static inline void dfp_set_bcd_digit_64(uint64_t *t, uint8_t digit,
-                                            unsigned n)
+static inline void dfp_set_bcd_digit_64(ppc_vsr_t *t, uint8_t digit,
+                                        unsigned n)
 {
-    *t |= ((uint64_t)(digit & 0xF) << (n << 2));
+    t->VsrD(1) |= ((uint64_t)(digit & 0xF) << (n << 2));
 }
 
-static inline void dfp_set_bcd_digit_128(uint64_t *t, uint8_t digit,
-                                             unsigned n)
+static inline void dfp_set_bcd_digit_128(ppc_vsr_t *t, uint8_t digit,
+                                         unsigned n)
 {
-    t[(n & 0x10) ? HI_IDX : LO_IDX] |=
+    t->VsrD((n & 0x10) ? 0 : 1) |=
         ((uint64_t)(digit & 0xF) << ((n & 15) << 2));
 }
 
-static inline void dfp_set_sign_64(uint64_t *t, uint8_t sgn)
+static inline void dfp_set_sign_64(ppc_vsr_t *t, uint8_t sgn)
 {
-    *t <<= 4;
-    *t |= (sgn & 0xF);
+    t->VsrD(1) <<= 4;
+    t->VsrD(1) |= (sgn & 0xF);
 }
 
-static inline void dfp_set_sign_128(uint64_t *t, uint8_t sgn)
+static inline void dfp_set_sign_128(ppc_vsr_t *t, uint8_t sgn)
 {
-    t[HI_IDX] <<= 4;
-    t[HI_IDX] |= (t[LO_IDX] >> 60);
-    t[LO_IDX] <<= 4;
-    t[LO_IDX] |= (sgn & 0xF);
+    t->VsrD(0) <<= 4;
+    t->VsrD(0) |= (t->VsrD(1) >> 60);
+    t->VsrD(1) <<= 4;
+    t->VsrD(1) |= (sgn & 0xF);
 }
 
 #define DFP_HELPER_DEDPD(op, size)                                        \
@@ -1081,7 +1074,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,          \
     N = dfp.b.digits;                                                     \
                                                                           \
     for (i = 0; (i < N) && (i < (size)/4); i++) {                         \
-        dfp_set_bcd_digit_##size(&dfp.vt.u64[0], digits[N - i - 1], i);   \
+        dfp_set_bcd_digit_##size(&dfp.vt, digits[N - i - 1], i);          \
     }                                                                     \
                                                                           \
     if (sp & 2) {                                                         \
@@ -1092,7 +1085,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,          \
         } else {                                                          \
             sgn = ((sp & 1) ? 0xF : 0xC);                                 \
         }                                                                 \
-        dfp_set_sign_##size(&dfp.vt.u64[0], sgn);                         \
+        dfp_set_sign_##size(&dfp.vt, sgn);                                \
     }                                                                     \
                                                                           \
     if (size == 64) {                                                     \
@@ -1105,14 +1098,14 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,          \
 DFP_HELPER_DEDPD(ddedpd, 64)
 DFP_HELPER_DEDPD(ddedpdq, 128)
 
-static inline uint8_t dfp_get_bcd_digit_64(uint64_t *t, unsigned n)
+static inline uint8_t dfp_get_bcd_digit_64(ppc_vsr_t *t, unsigned n)
 {
-    return *t >> ((n << 2) & 63) & 15;
+    return t->VsrD(1) >> ((n << 2) & 63) & 15;
 }
 
-static inline uint8_t dfp_get_bcd_digit_128(uint64_t *t, unsigned n)
+static inline uint8_t dfp_get_bcd_digit_128(ppc_vsr_t *t, unsigned n)
 {
-    return t[(n & 0x10) ? HI_IDX : LO_IDX] >> ((n << 2) & 63) & 15;
+    return t->VsrD((n & 0x10) ? 0 : 1) >> ((n << 2) & 63) & 15;
 }
 
 #define DFP_HELPER_ENBCD(op, size)                                           \
@@ -1128,8 +1121,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,             \
     decNumberZero(&dfp.t);                                                   \
                                                                              \
     if (s) {                                                                 \
-        uint8_t sgnNibble = dfp_get_bcd_digit_##size(&dfp.vb.u64[0],         \
-                                                     offset++);              \
+        uint8_t sgnNibble = dfp_get_bcd_digit_##size(&dfp.vb, offset++);     \
         switch (sgnNibble) {                                                 \
         case 0xD:                                                            \
         case 0xB:                                                            \
@@ -1149,7 +1141,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,             \
                                                                              \
     while (offset < (size) / 4) {                                            \
         n++;                                                                 \
-        digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(&dfp.vb.u64[0],    \
+        digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(&dfp.vb,           \
                                                           offset++);         \
         if (digits[(size) / 4 - n] > 10) {                                   \
             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);            \
@@ -1212,16 +1204,16 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
 DFP_HELPER_XEX(dxex, 64)
 DFP_HELPER_XEX(dxexq, 128)
 
-static void dfp_set_raw_exp_64(uint64_t *t, uint64_t raw)
+static void dfp_set_raw_exp_64(ppc_vsr_t *t, uint64_t raw)
 {
-    *t &= 0x8003ffffffffffffULL;
-    *t |= (raw << (63 - 13));
+    t->VsrD(1) &= 0x8003ffffffffffffULL;
+    t->VsrD(1) |= (raw << (63 - 13));
 }
 
-static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw)
+static void dfp_set_raw_exp_128(ppc_vsr_t *t, uint64_t raw)
 {
-    t[HI_IDX] &= 0x80003fffffffffffULL;
-    t[HI_IDX] |= (raw << (63 - 17));
+    t->VsrD(0) &= 0x80003fffffffffffULL;
+    t->VsrD(0) |= (raw << (63 - 17));
 }
 
 #define DFP_HELPER_IEX(op, size)                                          \
@@ -1258,11 +1250,11 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,          \
         dfp.vt.VsrD(0) = dfp.vb.VsrD(0);                                  \
         dfp.vt.VsrD(1) = dfp.vb.VsrD(1);                                  \
         if (exp == -1) {                                                  \
-            dfp_set_raw_exp_##size(&dfp.vt.u64[0], raw_inf);              \
+            dfp_set_raw_exp_##size(&dfp.vt, raw_inf);                     \
         } else if (exp == -3) {                                           \
-            dfp_set_raw_exp_##size(&dfp.vt.u64[0], raw_snan);             \
+            dfp_set_raw_exp_##size(&dfp.vt, raw_snan);                    \
         } else {                                                          \
-            dfp_set_raw_exp_##size(&dfp.vt.u64[0], raw_qnan);             \
+            dfp_set_raw_exp_##size(&dfp.vt, raw_qnan);                    \
         }                                                                 \
     } else {                                                              \
         dfp.t = dfp.b;                                                    \
-- 
2.21.0



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

* [PULL 28/53] target/ppc: remove unnecessary if() around calls to set_dfp{64, 128}() in DFP macros
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (26 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 27/53] target/ppc: use existing VsrD() macro to eliminate HI_IDX and LO_IDX from dfp_helper.c David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 29/53] spapr-pci: Stop providing assigned-addresses David Gibson
                   ` (25 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, Mark Cave-Ayland, qemu-devel,
	groug, qemu-ppc, clg, David Gibson

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Now that the parameters to both set_dfp64() and set_dfp128() are exactly the
same, there is no need for an explicit if() statement to determine which
function should be called based upon size. Instead we can simply use the
preprocessor to generate the call to set_dfp##size() directly.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190926185801.11176-8-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/dfp_helper.c | 60 +++++++----------------------------------
 1 file changed, 10 insertions(+), 50 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index c2bb458a78..2c65badae4 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -427,11 +427,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,               \
     dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context);                                \
     dfp_finalize_decimal##size(&dfp);                                          \
     postprocs(&dfp);                                                           \
-    if (size == 64) {                                                          \
-        set_dfp64(t, &dfp.vt);                                                 \
-    } else if (size == 128) {                                                  \
-        set_dfp128(t, &dfp.vt);                                                \
-    }                                                                          \
+    set_dfp##size(t, &dfp.vt);                                                 \
 }
 
 static void ADD_PPs(struct PPC_DFP *dfp)
@@ -747,11 +743,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,        \
     dfp_finalize_decimal##size(&dfp);                                   \
     QUA_PPs(&dfp);                                                      \
                                                                         \
-    if (size == 64) {                                                   \
-        set_dfp64(t, &dfp.vt);                                          \
-    } else if (size == 128) {                                           \
-        set_dfp128(t, &dfp.vt);                                         \
-    }                                                                   \
+    set_dfp##size(t, &dfp.vt);                                          \
 }
 
 DFP_HELPER_QUAI(dquai, 64)
@@ -769,11 +761,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,        \
     dfp_finalize_decimal##size(&dfp);                                   \
     QUA_PPs(&dfp);                                                      \
                                                                         \
-    if (size == 64) {                                                   \
-        set_dfp64(t, &dfp.vt);                                          \
-    } else if (size == 128) {                                           \
-        set_dfp128(t, &dfp.vt);                                         \
-    }                                                                   \
+    set_dfp##size(t, &dfp.vt);                                          \
 }
 
 DFP_HELPER_QUA(dqua, 64)
@@ -851,11 +839,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,        \
     dfp_finalize_decimal##size(&dfp);                                   \
     QUA_PPs(&dfp);                                                      \
                                                                         \
-    if (size == 64) {                                                   \
-        set_dfp64(t, &dfp.vt);                                          \
-    } else if (size == 128) {                                           \
-        set_dfp128(t, &dfp.vt);                                         \
-    }                                                                   \
+    set_dfp##size(t, &dfp.vt);                                          \
 }
 
 DFP_HELPER_RRND(drrnd, 64)
@@ -874,11 +858,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,               \
     dfp_finalize_decimal##size(&dfp);                                          \
     postprocs(&dfp);                                                           \
                                                                                \
-    if (size == 64) {                                                          \
-        set_dfp64(t, &dfp.vt);                                                 \
-    } else if (size == 128) {                                                  \
-        set_dfp128(t, &dfp.vt);                                                \
-    }                                                                          \
+    set_dfp##size(t, &dfp.vt);                                                 \
 }
 
 static void RINTX_PPs(struct PPC_DFP *dfp)
@@ -978,11 +958,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)               \
     dfp_finalize_decimal##size(&dfp);                                          \
     CFFIX_PPs(&dfp);                                                           \
                                                                                \
-    if (size == 64) {                                                          \
-        set_dfp64(t, &dfp.vt);                                                 \
-    } else if (size == 128) {                                                  \
-        set_dfp128(t, &dfp.vt);                                                \
-    }                                                                          \
+    set_dfp##size(t, &dfp.vt);                                                 \
 }
 
 static void CFFIX_PPs(struct PPC_DFP *dfp)
@@ -1088,11 +1064,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,          \
         dfp_set_sign_##size(&dfp.vt, sgn);                                \
     }                                                                     \
                                                                           \
-    if (size == 64) {                                                     \
-        set_dfp64(t, &dfp.vt);                                            \
-    } else if (size == 128) {                                             \
-        set_dfp128(t, &dfp.vt);                                           \
-    }                                                                     \
+    set_dfp##size(t, &dfp.vt);                                            \
 }
 
 DFP_HELPER_DEDPD(ddedpd, 64)
@@ -1160,11 +1132,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,             \
     }                                                                        \
     dfp_finalize_decimal##size(&dfp);                                        \
     dfp_set_FPRF_from_FRT(&dfp);                                             \
-    if ((size) == 64) {                                                      \
-        set_dfp64(t, &dfp.vt);                                               \
-    } else if ((size) == 128) {                                              \
-        set_dfp128(t, &dfp.vt);                                              \
-    }                                                                        \
+    set_dfp##size(t, &dfp.vt);                                               \
 }
 
 DFP_HELPER_ENBCD(denbcd, 64)
@@ -1264,11 +1232,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,          \
         dfp.t.exponent = exp - bias;                                      \
         dfp_finalize_decimal##size(&dfp);                                 \
     }                                                                     \
-    if (size == 64) {                                                     \
-        set_dfp64(t, &dfp.vt);                                            \
-    } else if (size == 128) {                                             \
-        set_dfp128(t, &dfp.vt);                                           \
-    }                                                                     \
+    set_dfp##size(t, &dfp.vt);                                            \
 }
 
 DFP_HELPER_IEX(diex, 64)
@@ -1356,11 +1320,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,    \
         }                                                           \
     }                                                               \
                                                                     \
-    if ((size) == 64) {                                             \
-        set_dfp64(t, &dfp.vt);                                      \
-    } else {                                                        \
-        set_dfp128(t, &dfp.vt);                                     \
-    }                                                               \
+    set_dfp##size(t, &dfp.vt);                                      \
 }
 
 DFP_HELPER_SHIFT(dscli, 64, 1)
-- 
2.21.0



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

* [PULL 29/53] spapr-pci: Stop providing assigned-addresses
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (27 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 28/53] target/ppc: remove unnecessary if() around calls to set_dfp{64, 128}() in DFP macros David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 30/53] spapr: Render full FDT on ibm, client-architecture-support David Gibson
                   ` (24 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

QEMU does not allocate PCI resources (BARs) in any case - coldplug devices
are configured by the firmware and hotplug devices rely on the guest
system to do the assignment via the PCI rescan mechanism. Also in order
to create non empty "assigned-addresses", the device has to be enabled
(i.e. PCI_COMMAND needs the MMIO bit set) first as otherwise
io_regions[i].addr are -1, and devices are not enabled at this point.

This removes "assigned-addresses" and leaves it to those who actually
do resource allocation.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Message-Id: <20190927022651.71642-1-aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_pci.c | 42 +++++++-----------------------------------
 1 file changed, 7 insertions(+), 35 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7b71ad7c74..c1c9634755 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -835,7 +835,7 @@ static char *spapr_phb_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
 #define b_fff(x)        b_x((x), 8, 3)  /* function number */
 #define b_rrrrrrrr(x)   b_x((x), 0, 8)  /* register number */
 
-/* for 'reg'/'assigned-addresses' OF properties */
+/* for 'reg' OF properties */
 #define RESOURCE_CELLS_SIZE 2
 #define RESOURCE_CELLS_ADDRESS 3
 
@@ -849,17 +849,14 @@ typedef struct ResourceFields {
 
 typedef struct ResourceProps {
     ResourceFields reg[8];
-    ResourceFields assigned[7];
     uint32_t reg_len;
-    uint32_t assigned_len;
 } ResourceProps;
 
-/* fill in the 'reg'/'assigned-resources' OF properties for
+/* fill in the 'reg' OF properties for
  * a PCI device. 'reg' describes resource requirements for a
- * device's IO/MEM regions, 'assigned-addresses' describes the
- * actual resource assignments.
+ * device's IO/MEM regions.
  *
- * the properties are arrays of ('phys-addr', 'size') pairs describing
+ * the property is an array of ('phys-addr', 'size') pairs describing
  * the addressable regions of the PCI device, where 'phys-addr' is a
  * RESOURCE_CELLS_ADDRESS-tuple of 32-bit integers corresponding to
  * (phys.hi, phys.mid, phys.lo), and 'size' is a
@@ -888,18 +885,7 @@ typedef struct ResourceProps {
  * phys.mid and phys.lo correspond respectively to the hi/lo portions
  * of the actual address of the region.
  *
- * how the phys-addr/size values are used differ slightly between
- * 'reg' and 'assigned-addresses' properties. namely, 'reg' has
- * an additional description for the config space region of the
- * device, and in the case of QEMU has n=0 and phys.mid=phys.lo=0
- * to describe the region as relocatable, with an address-mapping
- * that corresponds directly to the PHB's address space for the
- * resource. 'assigned-addresses' always has n=1 set with an absolute
- * address assigned for the resource. in general, 'assigned-addresses'
- * won't be populated, since addresses for PCI devices are generally
- * unmapped initially and left to the guest to assign.
- *
- * note also that addresses defined in these properties are, at least
+ * note also that addresses defined in this property are, at least
  * for PAPR guests, relative to the PHBs IO/MEM windows, and
  * correspond directly to the addresses in the BARs.
  *
@@ -913,8 +899,8 @@ static void populate_resource_props(PCIDevice *d, ResourceProps *rp)
     uint32_t dev_id = (b_bbbbbbbb(bus_num) |
                        b_ddddd(PCI_SLOT(d->devfn)) |
                        b_fff(PCI_FUNC(d->devfn)));
-    ResourceFields *reg, *assigned;
-    int i, reg_idx = 0, assigned_idx = 0;
+    ResourceFields *reg;
+    int i, reg_idx = 0;
 
     /* config space region */
     reg = &rp->reg[reg_idx++];
@@ -943,21 +929,9 @@ static void populate_resource_props(PCIDevice *d, ResourceProps *rp)
         reg->phys_lo = 0;
         reg->size_hi = cpu_to_be32(d->io_regions[i].size >> 32);
         reg->size_lo = cpu_to_be32(d->io_regions[i].size);
-
-        if (d->io_regions[i].addr == PCI_BAR_UNMAPPED) {
-            continue;
-        }
-
-        assigned = &rp->assigned[assigned_idx++];
-        assigned->phys_hi = cpu_to_be32(be32_to_cpu(reg->phys_hi) | b_n(1));
-        assigned->phys_mid = cpu_to_be32(d->io_regions[i].addr >> 32);
-        assigned->phys_lo = cpu_to_be32(d->io_regions[i].addr);
-        assigned->size_hi = reg->size_hi;
-        assigned->size_lo = reg->size_lo;
     }
 
     rp->reg_len = reg_idx * sizeof(ResourceFields);
-    rp->assigned_len = assigned_idx * sizeof(ResourceFields);
 }
 
 typedef struct PCIClass PCIClass;
@@ -1471,8 +1445,6 @@ static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
 
     populate_resource_props(dev, &rp);
     _FDT(fdt_setprop(fdt, offset, "reg", (uint8_t *)rp.reg, rp.reg_len));
-    _FDT(fdt_setprop(fdt, offset, "assigned-addresses",
-                     (uint8_t *)rp.assigned, rp.assigned_len));
 
     if (sphb->pcie_ecs && pci_is_express(dev)) {
         _FDT(fdt_setprop_cell(fdt, offset, "ibm,pci-config-space-type", 0x1));
-- 
2.21.0



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

* [PULL 30/53] spapr: Render full FDT on ibm, client-architecture-support
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (28 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 29/53] spapr-pci: Stop providing assigned-addresses David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-12-03 16:11   ` [PULL 30/53] spapr: Render full FDT on ibm,client-architecture-support Laurent Vivier
  2019-10-04  9:37 ` [PULL 31/53] target/ppc: use Vsr macros in BCD helpers David Gibson
                   ` (23 subsequent siblings)
  53 siblings, 1 reply; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

The ibm,client-architecture-support call is a way for the guest to
negotiate capabilities with a hypervisor. It is implemented as:
- the guest calls SLOF via client interface;
- SLOF calls QEMU (H_CAS hypercall) with an options vector from the guest;
- QEMU returns a device tree diff (which uses FDT format with
an additional header before it);
- SLOF walks through the partial diff tree and updates its internal tree
with the values from the diff.

This changes QEMU to simply re-render the entire tree and send it as
an update. SLOF can handle this already mostly, [1] is needed before this
can be applied. This stores the resulting tree in the spapr machine to have
the latest valid FDT copy possible (this should not matter much as
H_UPDATE_DT happens right after that but nevertheless).

The benefit is reduced code size as there is no need for another set of
DT rendering helpers such as spapr_fixup_cpu_dt().

The downside is that the updates are bigger now (as they include all
nodes and properties) but the difference on a '-smp 256,threads=1' system
before/after is 2.35s vs. 2.5s.

[1] https://patchwork.ozlabs.org/patch/1152915/

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

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3742a8cf06..43920c140d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -295,64 +295,6 @@ static void spapr_populate_pa_features(SpaprMachineState *spapr,
     _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
 }
 
-static int spapr_fixup_cpu_dt(void *fdt, SpaprMachineState *spapr)
-{
-    MachineState *ms = MACHINE(spapr);
-    int ret = 0, offset, cpus_offset;
-    CPUState *cs;
-    char cpu_model[32];
-    uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
-
-    CPU_FOREACH(cs) {
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
-        DeviceClass *dc = DEVICE_GET_CLASS(cs);
-        int index = spapr_get_vcpu_id(cpu);
-        int compat_smt = MIN(ms->smp.threads, ppc_compat_max_vthreads(cpu));
-
-        if (!spapr_is_thread0_in_vcore(spapr, cpu)) {
-            continue;
-        }
-
-        snprintf(cpu_model, 32, "%s@%x", dc->fw_name, index);
-
-        cpus_offset = fdt_path_offset(fdt, "/cpus");
-        if (cpus_offset < 0) {
-            cpus_offset = fdt_add_subnode(fdt, 0, "cpus");
-            if (cpus_offset < 0) {
-                return cpus_offset;
-            }
-        }
-        offset = fdt_subnode_offset(fdt, cpus_offset, cpu_model);
-        if (offset < 0) {
-            offset = fdt_add_subnode(fdt, cpus_offset, cpu_model);
-            if (offset < 0) {
-                return offset;
-            }
-        }
-
-        ret = fdt_setprop(fdt, offset, "ibm,pft-size",
-                          pft_size_prop, sizeof(pft_size_prop));
-        if (ret < 0) {
-            return ret;
-        }
-
-        if (ms->numa_state->num_nodes > 1) {
-            ret = spapr_fixup_cpu_numa_dt(fdt, offset, cpu);
-            if (ret < 0) {
-                return ret;
-            }
-        }
-
-        ret = spapr_fixup_cpu_smt_dt(fdt, offset, cpu, compat_smt);
-        if (ret < 0) {
-            return ret;
-        }
-
-        spapr_populate_pa_features(spapr, cpu, fdt, offset);
-    }
-    return ret;
-}
-
 static hwaddr spapr_node0_size(MachineState *machine)
 {
     if (machine->numa_state->num_nodes) {
@@ -983,11 +925,13 @@ static bool spapr_hotplugged_dev_before_cas(void)
     return false;
 }
 
+static void *spapr_build_fdt(SpaprMachineState *spapr);
+
 int spapr_h_cas_compose_response(SpaprMachineState *spapr,
                                  target_ulong addr, target_ulong size,
                                  SpaprOptionVector *ov5_updates)
 {
-    void *fdt, *fdt_skel;
+    void *fdt;
     SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 };
 
     if (spapr_hotplugged_dev_before_cas()) {
@@ -1003,25 +947,7 @@ int spapr_h_cas_compose_response(SpaprMachineState *spapr,
 
     size -= sizeof(hdr);
 
-    /* Create skeleton */
-    fdt_skel = g_malloc0(size);
-    _FDT((fdt_create(fdt_skel, size)));
-    _FDT((fdt_finish_reservemap(fdt_skel)));
-    _FDT((fdt_begin_node(fdt_skel, "")));
-    _FDT((fdt_end_node(fdt_skel)));
-    _FDT((fdt_finish(fdt_skel)));
-    fdt = g_malloc0(size);
-    _FDT((fdt_open_into(fdt_skel, fdt, size)));
-    g_free(fdt_skel);
-
-    /* Fixup cpu nodes */
-    _FDT((spapr_fixup_cpu_dt(fdt, spapr)));
-
-    if (spapr_dt_cas_updates(spapr, fdt, ov5_updates)) {
-        return -1;
-    }
-
-    /* Pack resulting tree */
+    fdt = spapr_build_fdt(spapr);
     _FDT((fdt_pack(fdt)));
 
     if (fdt_totalsize(fdt) + sizeof(hdr) > size) {
@@ -1033,7 +959,11 @@ int spapr_h_cas_compose_response(SpaprMachineState *spapr,
     cpu_physical_memory_write(addr, &hdr, sizeof(hdr));
     cpu_physical_memory_write(addr + sizeof(hdr), fdt, fdt_totalsize(fdt));
     trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr));
-    g_free(fdt);
+
+    g_free(spapr->fdt_blob);
+    spapr->fdt_size = fdt_totalsize(fdt);
+    spapr->fdt_initial_size = spapr->fdt_size;
+    spapr->fdt_blob = fdt;
 
     return 0;
 }
-- 
2.21.0



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

* [PULL 31/53] target/ppc: use Vsr macros in BCD helpers
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (29 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 30/53] spapr: Render full FDT on ibm, client-architecture-support David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 32/53] spapr/xive: skip partially initialized vCPUs in presenter David Gibson
                   ` (22 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, Richard Henderson, Mark Cave-Ayland, qemu-devel,
	groug, qemu-ppc, clg, David Gibson

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

This allows us to remove more endian-specific defines from int_helper.c.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-Id: <20190926204453.31837-1-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/int_helper.c | 72 ++++++++++++++---------------------------
 1 file changed, 25 insertions(+), 47 deletions(-)

diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 46deb57a34..6d238b989d 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -2052,15 +2052,11 @@ void helper_vsubecuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
 #define NATIONAL_PLUS   0x2B
 #define NATIONAL_NEG    0x2D
 
-#if defined(HOST_WORDS_BIGENDIAN)
 #define BCD_DIG_BYTE(n) (15 - ((n) / 2))
-#else
-#define BCD_DIG_BYTE(n) ((n) / 2)
-#endif
 
 static int bcd_get_sgn(ppc_avr_t *bcd)
 {
-    switch (bcd->u8[BCD_DIG_BYTE(0)] & 0xF) {
+    switch (bcd->VsrB(BCD_DIG_BYTE(0)) & 0xF) {
     case BCD_PLUS_PREF_1:
     case BCD_PLUS_PREF_2:
     case BCD_PLUS_ALT_1:
@@ -2095,9 +2091,9 @@ static uint8_t bcd_get_digit(ppc_avr_t *bcd, int n, int *invalid)
 {
     uint8_t result;
     if (n & 1) {
-        result = bcd->u8[BCD_DIG_BYTE(n)] >> 4;
+        result = bcd->VsrB(BCD_DIG_BYTE(n)) >> 4;
     } else {
-       result = bcd->u8[BCD_DIG_BYTE(n)] & 0xF;
+       result = bcd->VsrB(BCD_DIG_BYTE(n)) & 0xF;
     }
 
     if (unlikely(result > 9)) {
@@ -2109,11 +2105,11 @@ static uint8_t bcd_get_digit(ppc_avr_t *bcd, int n, int *invalid)
 static void bcd_put_digit(ppc_avr_t *bcd, uint8_t digit, int n)
 {
     if (n & 1) {
-        bcd->u8[BCD_DIG_BYTE(n)] &= 0x0F;
-        bcd->u8[BCD_DIG_BYTE(n)] |= (digit << 4);
+        bcd->VsrB(BCD_DIG_BYTE(n)) &= 0x0F;
+        bcd->VsrB(BCD_DIG_BYTE(n)) |= (digit << 4);
     } else {
-        bcd->u8[BCD_DIG_BYTE(n)] &= 0xF0;
-        bcd->u8[BCD_DIG_BYTE(n)] |= digit;
+        bcd->VsrB(BCD_DIG_BYTE(n)) &= 0xF0;
+        bcd->VsrB(BCD_DIG_BYTE(n)) |= digit;
     }
 }
 
@@ -2228,21 +2224,21 @@ uint32_t helper_bcdadd(ppc_avr_t *r,  ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
 
     if (!invalid) {
         if (sgna == sgnb) {
-            result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgna, ps);
+            result.VsrB(BCD_DIG_BYTE(0)) = bcd_preferred_sgn(sgna, ps);
             bcd_add_mag(&result, a, b, &invalid, &overflow);
             cr = bcd_cmp_zero(&result);
         } else {
             int magnitude = bcd_cmp_mag(a, b);
             if (magnitude > 0) {
-                result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgna, ps);
+                result.VsrB(BCD_DIG_BYTE(0)) = bcd_preferred_sgn(sgna, ps);
                 bcd_sub_mag(&result, a, b, &invalid, &overflow);
                 cr = (sgna > 0) ? CRF_GT : CRF_LT;
             } else if (magnitude < 0) {
-                result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgnb, ps);
+                result.VsrB(BCD_DIG_BYTE(0)) = bcd_preferred_sgn(sgnb, ps);
                 bcd_sub_mag(&result, b, a, &invalid, &overflow);
                 cr = (sgnb > 0) ? CRF_GT : CRF_LT;
             } else {
-                result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(0, ps);
+                result.VsrB(BCD_DIG_BYTE(0)) = bcd_preferred_sgn(0, ps);
                 cr = CRF_EQ;
             }
         }
@@ -2353,15 +2349,15 @@ uint32_t helper_bcdcfz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
     int zone_lead = ps ? 0xF : 0x3;
     int digit = 0;
     ppc_avr_t ret = { .u64 = { 0, 0 } };
-    int sgnb = b->u8[BCD_DIG_BYTE(0)] >> 4;
+    int sgnb = b->VsrB(BCD_DIG_BYTE(0)) >> 4;
 
     if (unlikely((sgnb < 0xA) && ps)) {
         invalid = 1;
     }
 
     for (i = 0; i < 16; i++) {
-        zone_digit = i ? b->u8[BCD_DIG_BYTE(i * 2)] >> 4 : zone_lead;
-        digit = b->u8[BCD_DIG_BYTE(i * 2)] & 0xF;
+        zone_digit = i ? b->VsrB(BCD_DIG_BYTE(i * 2)) >> 4 : zone_lead;
+        digit = b->VsrB(BCD_DIG_BYTE(i * 2)) & 0xF;
         if (unlikely(zone_digit != zone_lead || digit > 0x9)) {
             invalid = 1;
             break;
@@ -2407,7 +2403,7 @@ uint32_t helper_bcdctz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
             break;
         }
 
-        ret.u8[BCD_DIG_BYTE(i * 2)] = zone_lead + digit;
+        ret.VsrB(BCD_DIG_BYTE(i * 2)) = zone_lead + digit;
     }
 
     if (ps) {
@@ -2519,7 +2515,7 @@ uint32_t helper_bcdcpsgn(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
     }
 
     *r = *a;
-    bcd_put_digit(r, b->u8[BCD_DIG_BYTE(0)] & 0xF, 0);
+    bcd_put_digit(r, b->VsrB(BCD_DIG_BYTE(0)) & 0xF, 0);
 
     for (i = 1; i < 32; i++) {
         bcd_get_digit(a, i, &invalid);
@@ -2549,11 +2545,7 @@ uint32_t helper_bcdsetsgn(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
 uint32_t helper_bcds(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
 {
     int cr;
-#if defined(HOST_WORDS_BIGENDIAN)
-    int i = a->s8[7];
-#else
-    int i = a->s8[8];
-#endif
+    int i = a->VsrSB(7);
     bool ox_flag = false;
     int sgnb = bcd_get_sgn(b);
     ppc_avr_t ret = *b;
@@ -2602,11 +2594,7 @@ uint32_t helper_bcdus(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
         }
     }
 
-#if defined(HOST_WORDS_BIGENDIAN)
-    i = a->s8[7];
-#else
-    i = a->s8[8];
-#endif
+    i = a->VsrSB(7);
     if (i >= 32) {
         ox_flag = true;
         ret.VsrD(1) = ret.VsrD(0) = 0;
@@ -2637,13 +2625,11 @@ uint32_t helper_bcdsr(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
     ppc_avr_t ret = *b;
     ret.VsrD(1) &= ~0xf;
 
-#if defined(HOST_WORDS_BIGENDIAN)
-    int i = a->s8[7];
-    ppc_avr_t bcd_one = { .u64 = { 0, 0x10 } };
-#else
-    int i = a->s8[8];
-    ppc_avr_t bcd_one = { .u64 = { 0x10, 0 } };
-#endif
+    int i = a->VsrSB(7);
+    ppc_avr_t bcd_one;
+
+    bcd_one.VsrD(0) = 0;
+    bcd_one.VsrD(1) = 0x10;
 
     if (bcd_is_valid(b) == false) {
         return CRF_SO;
@@ -2679,11 +2665,7 @@ uint32_t helper_bcdtrunc(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
 {
     uint64_t mask;
     uint32_t ox_flag = 0;
-#if defined(HOST_WORDS_BIGENDIAN)
-    int i = a->s16[3] + 1;
-#else
-    int i = a->s16[4] + 1;
-#endif
+    int i = a->VsrSH(3) + 1;
     ppc_avr_t ret = *b;
 
     if (bcd_is_valid(b) == false) {
@@ -2728,11 +2710,7 @@ uint32_t helper_bcdutrunc(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
         }
     }
 
-#if defined(HOST_WORDS_BIGENDIAN)
-    i = a->s16[3];
-#else
-    i = a->s16[4];
-#endif
+    i = a->VsrSH(3);
     if (i > 16 && i < 33) {
         mask = (uint64_t)-1 >> (128 - i * 4);
         if (ret.VsrD(0) & ~mask) {
-- 
2.21.0



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

* [PULL 32/53] spapr/xive: skip partially initialized vCPUs in presenter
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (30 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 31/53] target/ppc: use Vsr macros in BCD helpers David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 33/53] xics: Minor fixes for XICSFabric interface David Gibson
                   ` (21 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

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

When vCPUs are hotplugged, they are added to the QEMU CPU list before
being fully realized. This can crash the XIVE presenter because the
'tctx' pointer is not necessarily initialized when looking for a
matching target.

These vCPUs are not valid targets for the presenter. Skip them.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191001085722.32755-1-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/xive.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index b7417210d8..29df06df11 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1396,6 +1396,14 @@ static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
         XiveTCTX *tctx = xive_router_get_tctx(xrtr, cs);
         int ring;
 
+        /*
+         * Skip partially initialized vCPUs. This can happen when
+         * vCPUs are hotplugged.
+         */
+        if (!tctx) {
+            continue;
+        }
+
         /*
          * HW checks that the CPU is enabled in the Physical Thread
          * Enable Register (PTER).
-- 
2.21.0



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

* [PULL 33/53] xics: Minor fixes for XICSFabric interface
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (31 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 32/53] spapr/xive: skip partially initialized vCPUs in presenter David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 34/53] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
                   ` (20 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

Interface instances should never be directly dereferenced.  So, the common
practice is to make them incomplete types to make sure no-one does that.
XICSFrabric, however, had a dummy type which is less safe.

We were also using OBJECT_CHECK() where we should have been using
INTERFACE_CHECK().

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/xics.h | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 64a2c8862a..faa33ae943 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -147,13 +147,9 @@ struct ICSIRQState {
     uint8_t flags;
 };
 
-struct XICSFabric {
-    Object parent;
-};
-
 #define TYPE_XICS_FABRIC "xics-fabric"
 #define XICS_FABRIC(obj)                                     \
-    OBJECT_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
+    INTERFACE_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
 #define XICS_FABRIC_CLASS(klass)                                     \
     OBJECT_CLASS_CHECK(XICSFabricClass, (klass), TYPE_XICS_FABRIC)
 #define XICS_FABRIC_GET_CLASS(obj)                                   \
-- 
2.21.0



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

* [PULL 34/53] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (32 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 33/53] xics: Minor fixes for XICSFabric interface David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 35/53] xics: Rename misleading ics_simple_*() functions David Gibson
                   ` (19 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

Currently ics_reject(), ics_resend() and ics_eoi() indirect through
class methods.  But there's only one implementation of each method,
the one in TYPE_ICS_SIMPLE.  TYPE_ICS_BASE has no implementation, but
it's never instantiated, and has no other subtypes.

So clean up by eliminating the method and just having ics_reject(),
ics_resend() and ics_eoi() contain the logic directly.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/trace-events  |  4 ++--
 hw/intc/xics.c        | 54 +++++++++++--------------------------------
 include/hw/ppc/xics.h |  4 ----
 3 files changed, 15 insertions(+), 47 deletions(-)

diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 719f46b516..fdc716c2cc 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -70,8 +70,8 @@ xics_ics_simple_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq 0x%x]
 xics_masked_pending(void) "set_irq_msi: masked pending"
 xics_ics_simple_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq 0x%x]"
 xics_ics_simple_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x"
-xics_ics_simple_reject(int nr, int srcno) "reject irq 0x%x [src %d]"
-xics_ics_simple_eoi(int nr) "ics_eoi: irq 0x%x"
+xics_ics_reject(int nr, int srcno) "reject irq 0x%x [src %d]"
+xics_ics_eoi(int nr) "ics_eoi: irq 0x%x"
 
 # s390_flic_kvm.c
 flic_create_device(int err) "flic: create device failed %d"
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index b2fca2975c..93139b0189 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -98,32 +98,8 @@ void ics_pic_print_info(ICSState *ics, Monitor *mon)
 #define XISR(icp)   (((icp)->xirr) & XISR_MASK)
 #define CPPR(icp)   (((icp)->xirr) >> 24)
 
-static void ics_reject(ICSState *ics, uint32_t nr)
-{
-    ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
-
-    if (k->reject) {
-        k->reject(ics, nr);
-    }
-}
-
-void ics_resend(ICSState *ics)
-{
-    ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
-
-    if (k->resend) {
-        k->resend(ics);
-    }
-}
-
-static void ics_eoi(ICSState *ics, int nr)
-{
-    ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
-
-    if (k->eoi) {
-        k->eoi(ics, nr);
-    }
-}
+static void ics_reject(ICSState *ics, uint32_t nr);
+static void ics_eoi(ICSState *ics, uint32_t nr);
 
 static void icp_check_ipi(ICPState *icp)
 {
@@ -427,7 +403,7 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp)
 /*
  * ICS: Source layer
  */
-static void ics_simple_resend_msi(ICSState *ics, int srcno)
+static void ics_resend_msi(ICSState *ics, int srcno)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
@@ -440,7 +416,7 @@ static void ics_simple_resend_msi(ICSState *ics, int srcno)
     }
 }
 
-static void ics_simple_resend_lsi(ICSState *ics, int srcno)
+static void ics_resend_lsi(ICSState *ics, int srcno)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
@@ -478,7 +454,7 @@ static void ics_simple_set_irq_lsi(ICSState *ics, int srcno, int val)
     } else {
         irq->status &= ~XICS_STATUS_ASSERTED;
     }
-    ics_simple_resend_lsi(ics, srcno);
+    ics_resend_lsi(ics, srcno);
 }
 
 void ics_simple_set_irq(void *opaque, int srcno, int val)
@@ -512,7 +488,7 @@ static void ics_simple_write_xive_msi(ICSState *ics, int srcno)
 
 static void ics_simple_write_xive_lsi(ICSState *ics, int srcno)
 {
-    ics_simple_resend_lsi(ics, srcno);
+    ics_resend_lsi(ics, srcno);
 }
 
 void ics_simple_write_xive(ICSState *ics, int srcno, int server,
@@ -534,11 +510,11 @@ void ics_simple_write_xive(ICSState *ics, int srcno, int server,
     }
 }
 
-static void ics_simple_reject(ICSState *ics, uint32_t nr)
+static void ics_reject(ICSState *ics, uint32_t nr)
 {
     ICSIRQState *irq = ics->irqs + nr - ics->offset;
 
-    trace_xics_ics_simple_reject(nr, nr - ics->offset);
+    trace_xics_ics_reject(nr, nr - ics->offset);
     if (irq->flags & XICS_FLAGS_IRQ_MSI) {
         irq->status |= XICS_STATUS_REJECTED;
     } else if (irq->flags & XICS_FLAGS_IRQ_LSI) {
@@ -546,26 +522,26 @@ static void ics_simple_reject(ICSState *ics, uint32_t nr)
     }
 }
 
-static void ics_simple_resend(ICSState *ics)
+void ics_resend(ICSState *ics)
 {
     int i;
 
     for (i = 0; i < ics->nr_irqs; i++) {
         /* FIXME: filter by server#? */
         if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
-            ics_simple_resend_lsi(ics, i);
+            ics_resend_lsi(ics, i);
         } else {
-            ics_simple_resend_msi(ics, i);
+            ics_resend_msi(ics, i);
         }
     }
 }
 
-static void ics_simple_eoi(ICSState *ics, uint32_t nr)
+static void ics_eoi(ICSState *ics, uint32_t nr)
 {
     int srcno = nr - ics->offset;
     ICSIRQState *irq = ics->irqs + srcno;
 
-    trace_xics_ics_simple_eoi(nr);
+    trace_xics_ics_eoi(nr);
 
     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
         irq->status &= ~XICS_STATUS_SENT;
@@ -617,10 +593,6 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
                                     &isc->parent_realize);
     device_class_set_parent_reset(dc, ics_simple_reset,
                                   &isc->parent_reset);
-
-    isc->reject = ics_simple_reject;
-    isc->resend = ics_simple_resend;
-    isc->eoi = ics_simple_eoi;
 }
 
 static const TypeInfo ics_simple_info = {
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index faa33ae943..ecca17695d 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -106,10 +106,6 @@ struct ICSStateClass {
 
     DeviceRealize parent_realize;
     DeviceReset parent_reset;
-
-    void (*reject)(ICSState *s, uint32_t irq);
-    void (*resend)(ICSState *s);
-    void (*eoi)(ICSState *s, uint32_t irq);
 };
 
 struct ICSState {
-- 
2.21.0



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

* [PULL 35/53] xics: Rename misleading ics_simple_*() functions
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (33 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 34/53] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 36/53] xics: Eliminate reset hook David Gibson
                   ` (18 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

There are a number of ics_simple_*() functions that aren't actually
specific to TYPE_XICS_SIMPLE at all, and are equally valid on
TYPE_XICS_BASE.  Rename them to ics_*() accordingly.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/trace-events  |  6 +++---
 hw/intc/xics.c        | 29 ++++++++++++++---------------
 hw/intc/xics_spapr.c  | 12 ++++++------
 hw/ppc/pnv_psi.c      |  4 ++--
 hw/ppc/spapr_irq.c    |  2 +-
 include/hw/ppc/xics.h |  6 +++---
 6 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index fdc716c2cc..527c3f76ca 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -66,10 +66,10 @@ xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) "icp_accept: XIRR 0x%"PRIx
 xics_icp_eoi(int server, uint32_t xirr, uint32_t new_xirr) "icp_eoi: server %d given XIRR 0x%"PRIx32" new XIRR 0x%"PRIx32
 xics_icp_irq(int server, int nr, uint8_t priority) "cpu %d trying to deliver irq 0x%"PRIx32" priority 0x%x"
 xics_icp_raise(uint32_t xirr, uint8_t pending_priority) "raising IRQ new XIRR=0x%x new pending priority=0x%x"
-xics_ics_simple_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq 0x%x]"
+xics_ics_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq 0x%x]"
 xics_masked_pending(void) "set_irq_msi: masked pending"
-xics_ics_simple_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq 0x%x]"
-xics_ics_simple_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x"
+xics_ics_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq 0x%x]"
+xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x"
 xics_ics_reject(int nr, int srcno) "reject irq 0x%x [src %d]"
 xics_ics_eoi(int nr) "ics_eoi: irq 0x%x"
 
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 93139b0189..310dc72b46 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -428,11 +428,11 @@ static void ics_resend_lsi(ICSState *ics, int srcno)
     }
 }
 
-static void ics_simple_set_irq_msi(ICSState *ics, int srcno, int val)
+static void ics_set_irq_msi(ICSState *ics, int srcno, int val)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
-    trace_xics_ics_simple_set_irq_msi(srcno, srcno + ics->offset);
+    trace_xics_ics_set_irq_msi(srcno, srcno + ics->offset);
 
     if (val) {
         if (irq->priority == 0xff) {
@@ -444,11 +444,11 @@ static void ics_simple_set_irq_msi(ICSState *ics, int srcno, int val)
     }
 }
 
-static void ics_simple_set_irq_lsi(ICSState *ics, int srcno, int val)
+static void ics_set_irq_lsi(ICSState *ics, int srcno, int val)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
-    trace_xics_ics_simple_set_irq_lsi(srcno, srcno + ics->offset);
+    trace_xics_ics_set_irq_lsi(srcno, srcno + ics->offset);
     if (val) {
         irq->status |= XICS_STATUS_ASSERTED;
     } else {
@@ -457,7 +457,7 @@ static void ics_simple_set_irq_lsi(ICSState *ics, int srcno, int val)
     ics_resend_lsi(ics, srcno);
 }
 
-void ics_simple_set_irq(void *opaque, int srcno, int val)
+void ics_set_irq(void *opaque, int srcno, int val)
 {
     ICSState *ics = (ICSState *)opaque;
 
@@ -467,13 +467,13 @@ void ics_simple_set_irq(void *opaque, int srcno, int val)
     }
 
     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
-        ics_simple_set_irq_lsi(ics, srcno, val);
+        ics_set_irq_lsi(ics, srcno, val);
     } else {
-        ics_simple_set_irq_msi(ics, srcno, val);
+        ics_set_irq_msi(ics, srcno, val);
     }
 }
 
-static void ics_simple_write_xive_msi(ICSState *ics, int srcno)
+static void ics_write_xive_msi(ICSState *ics, int srcno)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
@@ -486,13 +486,13 @@ static void ics_simple_write_xive_msi(ICSState *ics, int srcno)
     icp_irq(ics, irq->server, srcno + ics->offset, irq->priority);
 }
 
-static void ics_simple_write_xive_lsi(ICSState *ics, int srcno)
+static void ics_write_xive_lsi(ICSState *ics, int srcno)
 {
     ics_resend_lsi(ics, srcno);
 }
 
-void ics_simple_write_xive(ICSState *ics, int srcno, int server,
-                           uint8_t priority, uint8_t saved_priority)
+void ics_write_xive(ICSState *ics, int srcno, int server,
+                    uint8_t priority, uint8_t saved_priority)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
@@ -500,13 +500,12 @@ void ics_simple_write_xive(ICSState *ics, int srcno, int server,
     irq->priority = priority;
     irq->saved_priority = saved_priority;
 
-    trace_xics_ics_simple_write_xive(ics->offset + srcno, srcno, server,
-                                     priority);
+    trace_xics_ics_write_xive(ics->offset + srcno, srcno, server, priority);
 
     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
-        ics_simple_write_xive_lsi(ics, srcno);
+        ics_write_xive_lsi(ics, srcno);
     } else {
-        ics_simple_write_xive_msi(ics, srcno);
+        ics_write_xive_msi(ics, srcno);
     }
 }
 
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 6577be0d92..3e9444813a 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -179,7 +179,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
     }
 
     srcno = nr - ics->offset;
-    ics_simple_write_xive(ics, srcno, server, priority, priority);
+    ics_write_xive(ics, srcno, server, priority, priority);
 
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
@@ -243,8 +243,8 @@ static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
     }
 
     srcno = nr - ics->offset;
-    ics_simple_write_xive(ics, srcno, ics->irqs[srcno].server, 0xff,
-                          ics->irqs[srcno].priority);
+    ics_write_xive(ics, srcno, ics->irqs[srcno].server, 0xff,
+                   ics->irqs[srcno].priority);
 
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
@@ -276,9 +276,9 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
     }
 
     srcno = nr - ics->offset;
-    ics_simple_write_xive(ics, srcno, ics->irqs[srcno].server,
-                          ics->irqs[srcno].saved_priority,
-                          ics->irqs[srcno].saved_priority);
+    ics_write_xive(ics, srcno, ics->irqs[srcno].server,
+                   ics->irqs[srcno].saved_priority,
+                   ics->irqs[srcno].saved_priority);
 
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 88ba8e7b9b..8ea81e9d8e 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -311,7 +311,7 @@ static void pnv_psi_set_xivr(PnvPsi *psi, uint32_t reg, uint64_t val)
      * do for now but a more accurate implementation would instead
      * use a fixed server/prio and a remapper of the generated irq.
      */
-    ics_simple_write_xive(ics, src, server, prio, prio);
+    ics_write_xive(ics, src, server, prio, prio);
 }
 
 static uint64_t pnv_psi_reg_read(PnvPsi *psi, uint32_t offset, bool mmio)
@@ -514,7 +514,7 @@ static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
         ics_set_irq_type(ics, i, true);
     }
 
-    psi->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);
+    psi->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);
 
     /* XSCOM region for PSI registers */
     pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_xscom_ops,
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index d8f46b6797..ac189c5796 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -210,7 +210,7 @@ static void spapr_irq_set_irq_xics(void *opaque, int srcno, int val)
 {
     SpaprMachineState *spapr = opaque;
 
-    ics_simple_set_irq(spapr->ics, srcno, val);
+    ics_set_irq(spapr->ics, srcno, val);
 }
 
 static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index ecca17695d..8874bad328 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -167,9 +167,9 @@ uint32_t icp_accept(ICPState *ss);
 uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr);
 void icp_eoi(ICPState *icp, uint32_t xirr);
 
-void ics_simple_write_xive(ICSState *ics, int nr, int server,
-                           uint8_t priority, uint8_t saved_priority);
-void ics_simple_set_irq(void *opaque, int srcno, int val);
+void ics_write_xive(ICSState *ics, int nr, int server,
+                    uint8_t priority, uint8_t saved_priority);
+void ics_set_irq(void *opaque, int srcno, int val);
 
 static inline bool ics_irq_free(ICSState *ics, uint32_t srcno)
 {
-- 
2.21.0



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

* [PULL 36/53] xics: Eliminate reset hook
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (34 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 35/53] xics: Rename misleading ics_simple_*() functions David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 37/53] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
                   ` (17 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

Currently TYPE_XICS_BASE and TYPE_XICS_SIMPLE have their own reset methods,
using the standard technique for having the subtype call the supertype's
methods before doing its own thing.

But TYPE_XICS_SIMPLE is the only subtype of TYPE_XICS_BASE ever
instantiated, so there's no point having the split here.  Merge them
together into just an ics_reset() function.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/xics.c        | 57 ++++++++++++++++++-------------------------
 include/hw/ppc/xics.h |  1 -
 2 files changed, 24 insertions(+), 34 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 310dc72b46..82e6f09259 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -547,11 +547,28 @@ static void ics_eoi(ICSState *ics, uint32_t nr)
     }
 }
 
-static void ics_simple_reset(DeviceState *dev)
+static void ics_reset_irq(ICSIRQState *irq)
 {
-    ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev);
+    irq->priority = 0xff;
+    irq->saved_priority = 0xff;
+}
 
-    icsc->parent_reset(dev);
+static void ics_reset(DeviceState *dev)
+{
+    ICSState *ics = ICS_BASE(dev);
+    int i;
+    uint8_t flags[ics->nr_irqs];
+
+    for (i = 0; i < ics->nr_irqs; i++) {
+        flags[i] = ics->irqs[i].flags;
+    }
+
+    memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
+
+    for (i = 0; i < ics->nr_irqs; i++) {
+        ics_reset_irq(ics->irqs + i);
+        ics->irqs[i].flags = flags[i];
+    }
 
     if (kvm_irqchip_in_kernel()) {
         Error *local_err = NULL;
@@ -563,9 +580,9 @@ static void ics_simple_reset(DeviceState *dev)
     }
 }
 
-static void ics_simple_reset_handler(void *dev)
+static void ics_reset_handler(void *dev)
 {
-    ics_simple_reset(dev);
+    ics_reset(dev);
 }
 
 static void ics_simple_realize(DeviceState *dev, Error **errp)
@@ -580,7 +597,7 @@ static void ics_simple_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    qemu_register_reset(ics_simple_reset_handler, ics);
+    qemu_register_reset(ics_reset_handler, ics);
 }
 
 static void ics_simple_class_init(ObjectClass *klass, void *data)
@@ -590,8 +607,6 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
 
     device_class_set_parent_realize(dc, ics_simple_realize,
                                     &isc->parent_realize);
-    device_class_set_parent_reset(dc, ics_simple_reset,
-                                  &isc->parent_reset);
 }
 
 static const TypeInfo ics_simple_info = {
@@ -602,30 +617,6 @@ static const TypeInfo ics_simple_info = {
     .class_size = sizeof(ICSStateClass),
 };
 
-static void ics_reset_irq(ICSIRQState *irq)
-{
-    irq->priority = 0xff;
-    irq->saved_priority = 0xff;
-}
-
-static void ics_base_reset(DeviceState *dev)
-{
-    ICSState *ics = ICS_BASE(dev);
-    int i;
-    uint8_t flags[ics->nr_irqs];
-
-    for (i = 0; i < ics->nr_irqs; i++) {
-        flags[i] = ics->irqs[i].flags;
-    }
-
-    memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
-
-    for (i = 0; i < ics->nr_irqs; i++) {
-        ics_reset_irq(ics->irqs + i);
-        ics->irqs[i].flags = flags[i];
-    }
-}
-
 static void ics_base_realize(DeviceState *dev, Error **errp)
 {
     ICSState *ics = ICS_BASE(dev);
@@ -726,7 +717,7 @@ static void ics_base_class_init(ObjectClass *klass, void *data)
 
     dc->realize = ics_base_realize;
     dc->props = ics_base_properties;
-    dc->reset = ics_base_reset;
+    dc->reset = ics_reset;
     dc->vmsd = &vmstate_ics_base;
 }
 
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 8874bad328..7efd49c02c 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -105,7 +105,6 @@ struct ICSStateClass {
     DeviceClass parent_class;
 
     DeviceRealize parent_realize;
-    DeviceReset parent_reset;
 };
 
 struct ICSState {
-- 
2.21.0



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

* [PULL 37/53] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (35 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 36/53] xics: Eliminate reset hook David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 38/53] xics: Create sPAPR specific ICS subtype David Gibson
                   ` (16 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

TYPE_ICS_SIMPLE is the only subtype of TYPE_ICS_BASE that's ever
instantiated.  The existence of different classes is mostly a hang
over from when we (misguidedly) had separate subtypes for the KVM and
non-KVM version of the device.

There could be some call for an abstract base type for ICS variants
that use a different representation of their state (PowerNV PHB3 might
want this).  The current split isn't really in the right place for
that though.  If we need this in future, we can re-implement it more
in line with what we actually need.

So, collapse the two classes together into just TYPE_ICS.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/xics.c        | 86 ++++++++++++++-----------------------------
 hw/ppc/pnv_psi.c      |  2 +-
 hw/ppc/spapr_irq.c    |  4 +-
 include/hw/ppc/xics.h | 16 +++-----
 4 files changed, 36 insertions(+), 72 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 82e6f09259..dfe7dbd254 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -555,7 +555,7 @@ static void ics_reset_irq(ICSIRQState *irq)
 
 static void ics_reset(DeviceState *dev)
 {
-    ICSState *ics = ICS_BASE(dev);
+    ICSState *ics = ICS(dev);
     int i;
     uint8_t flags[ics->nr_irqs];
 
@@ -573,7 +573,7 @@ static void ics_reset(DeviceState *dev)
     if (kvm_irqchip_in_kernel()) {
         Error *local_err = NULL;
 
-        ics_set_kvm_state(ICS_BASE(dev), &local_err);
+        ics_set_kvm_state(ICS(dev), &local_err);
         if (local_err) {
             error_report_err(local_err);
         }
@@ -585,47 +585,15 @@ static void ics_reset_handler(void *dev)
     ics_reset(dev);
 }
 
-static void ics_simple_realize(DeviceState *dev, Error **errp)
+static void ics_realize(DeviceState *dev, Error **errp)
 {
-    ICSState *ics = ICS_SIMPLE(dev);
-    ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics);
+    ICSState *ics = ICS(dev);
     Error *local_err = NULL;
-
-    icsc->parent_realize(dev, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    qemu_register_reset(ics_reset_handler, ics);
-}
-
-static void ics_simple_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    ICSStateClass *isc = ICS_BASE_CLASS(klass);
-
-    device_class_set_parent_realize(dc, ics_simple_realize,
-                                    &isc->parent_realize);
-}
-
-static const TypeInfo ics_simple_info = {
-    .name = TYPE_ICS_SIMPLE,
-    .parent = TYPE_ICS_BASE,
-    .instance_size = sizeof(ICSState),
-    .class_init = ics_simple_class_init,
-    .class_size = sizeof(ICSStateClass),
-};
-
-static void ics_base_realize(DeviceState *dev, Error **errp)
-{
-    ICSState *ics = ICS_BASE(dev);
     Object *obj;
-    Error *err = NULL;
 
-    obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &err);
+    obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &local_err);
     if (!obj) {
-        error_propagate_prepend(errp, err,
+        error_propagate_prepend(errp, local_err,
                                 "required link '" ICS_PROP_XICS
                                 "' not found: ");
         return;
@@ -637,16 +605,18 @@ static void ics_base_realize(DeviceState *dev, Error **errp)
         return;
     }
     ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
+
+    qemu_register_reset(ics_reset_handler, ics);
 }
 
-static void ics_base_instance_init(Object *obj)
+static void ics_instance_init(Object *obj)
 {
-    ICSState *ics = ICS_BASE(obj);
+    ICSState *ics = ICS(obj);
 
     ics->offset = XICS_IRQ_BASE;
 }
 
-static int ics_base_pre_save(void *opaque)
+static int ics_pre_save(void *opaque)
 {
     ICSState *ics = opaque;
 
@@ -657,7 +627,7 @@ static int ics_base_pre_save(void *opaque)
     return 0;
 }
 
-static int ics_base_post_load(void *opaque, int version_id)
+static int ics_post_load(void *opaque, int version_id)
 {
     ICSState *ics = opaque;
 
@@ -675,7 +645,7 @@ static int ics_base_post_load(void *opaque, int version_id)
     return 0;
 }
 
-static const VMStateDescription vmstate_ics_base_irq = {
+static const VMStateDescription vmstate_ics_irq = {
     .name = "ics/irq",
     .version_id = 2,
     .minimum_version_id = 1,
@@ -689,45 +659,44 @@ static const VMStateDescription vmstate_ics_base_irq = {
     },
 };
 
-static const VMStateDescription vmstate_ics_base = {
+static const VMStateDescription vmstate_ics = {
     .name = "ics",
     .version_id = 1,
     .minimum_version_id = 1,
-    .pre_save = ics_base_pre_save,
-    .post_load = ics_base_post_load,
+    .pre_save = ics_pre_save,
+    .post_load = ics_post_load,
     .fields = (VMStateField[]) {
         /* Sanity check */
         VMSTATE_UINT32_EQUAL(nr_irqs, ICSState, NULL),
 
         VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
-                                             vmstate_ics_base_irq,
+                                             vmstate_ics_irq,
                                              ICSIRQState),
         VMSTATE_END_OF_LIST()
     },
 };
 
-static Property ics_base_properties[] = {
+static Property ics_properties[] = {
     DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static void ics_base_class_init(ObjectClass *klass, void *data)
+static void ics_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    dc->realize = ics_base_realize;
-    dc->props = ics_base_properties;
+    dc->realize = ics_realize;
+    dc->props = ics_properties;
     dc->reset = ics_reset;
-    dc->vmsd = &vmstate_ics_base;
+    dc->vmsd = &vmstate_ics;
 }
 
-static const TypeInfo ics_base_info = {
-    .name = TYPE_ICS_BASE,
+static const TypeInfo ics_info = {
+    .name = TYPE_ICS,
     .parent = TYPE_DEVICE,
-    .abstract = true,
     .instance_size = sizeof(ICSState),
-    .instance_init = ics_base_instance_init,
-    .class_init = ics_base_class_init,
+    .instance_init = ics_instance_init,
+    .class_init = ics_class_init,
     .class_size = sizeof(ICSStateClass),
 };
 
@@ -767,8 +736,7 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
 
 static void xics_register_types(void)
 {
-    type_register_static(&ics_simple_info);
-    type_register_static(&ics_base_info);
+    type_register_static(&ics_info);
     type_register_static(&icp_info);
     type_register_static(&xics_fabric_info);
 }
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 8ea81e9d8e..a997f16bb4 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -469,7 +469,7 @@ static void pnv_psi_power8_instance_init(Object *obj)
     Pnv8Psi *psi8 = PNV8_PSI(obj);
 
     object_initialize_child(obj, "ics-psi",  &psi8->ics, sizeof(psi8->ics),
-                            TYPE_ICS_SIMPLE, &error_abort, NULL);
+                            TYPE_ICS, &error_abort, NULL);
 }
 
 static const uint8_t irq_to_xivr[] = {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index ac189c5796..6c45d2a3c0 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -98,7 +98,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
     Object *obj;
     Error *local_err = NULL;
 
-    obj = object_new(TYPE_ICS_SIMPLE);
+    obj = object_new(TYPE_ICS);
     object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
     object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
                                    &error_fatal);
@@ -109,7 +109,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
         return;
     }
 
-    spapr->ics = ICS_BASE(obj);
+    spapr->ics = ICS(obj);
 
     xics_spapr_init(spapr);
 }
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 7efd49c02c..1e6a9300eb 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -89,17 +89,13 @@ struct PnvICPState {
     uint32_t links[3];
 };
 
-#define TYPE_ICS_BASE "ics-base"
-#define ICS_BASE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_BASE)
+#define TYPE_ICS "ics"
+#define ICS(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS)
 
-/* Retain ics for sPAPR for migration from existing sPAPR guests */
-#define TYPE_ICS_SIMPLE "ics"
-#define ICS_SIMPLE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE)
-
-#define ICS_BASE_CLASS(klass) \
-     OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS_BASE)
-#define ICS_BASE_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS_BASE)
+#define ICS_CLASS(klass) \
+     OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS)
+#define ICS_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS)
 
 struct ICSStateClass {
     DeviceClass parent_class;
-- 
2.21.0



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

* [PULL 38/53] xics: Create sPAPR specific ICS subtype
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (36 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 37/53] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 39/53] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
                   ` (15 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
does is move the setup of the PAPR specific hcalls and RTAS calls to
the realize() function for this, rather than requiring the PAPR code to
explicitly call xics_spapr_init().  In future it will have some more
function.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/xics_spapr.c        | 34 +++++++++++++++++++++++++++++++++-
 hw/ppc/spapr_irq.c          |  6 ++----
 include/hw/ppc/xics_spapr.h |  4 +++-
 3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 3e9444813a..e6dd004587 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -283,8 +283,18 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-void xics_spapr_init(SpaprMachineState *spapr)
+static void ics_spapr_realize(DeviceState *dev, Error **errp)
 {
+    ICSState *ics = ICS_SPAPR(dev);
+    ICSStateClass *icsc = ICS_GET_CLASS(ics);
+    Error *local_err = NULL;
+
+    icsc->parent_realize(dev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
     spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
     spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
     spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
@@ -319,3 +329,25 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
     _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
     _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
 }
+
+static void ics_spapr_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    ICSStateClass *isc = ICS_CLASS(klass);
+
+    device_class_set_parent_realize(dc, ics_spapr_realize,
+                                    &isc->parent_realize);
+}
+
+static const TypeInfo ics_spapr_info = {
+    .name = TYPE_ICS_SPAPR,
+    .parent = TYPE_ICS,
+    .class_init = ics_spapr_class_init,
+};
+
+static void xics_spapr_register_types(void)
+{
+    type_register_static(&ics_spapr_info);
+}
+
+type_init(xics_spapr_register_types)
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 6c45d2a3c0..8c26fa2d1e 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -98,7 +98,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
     Object *obj;
     Error *local_err = NULL;
 
-    obj = object_new(TYPE_ICS);
+    obj = object_new(TYPE_ICS_SPAPR);
     object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
     object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
                                    &error_fatal);
@@ -109,9 +109,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
         return;
     }
 
-    spapr->ics = ICS(obj);
-
-    xics_spapr_init(spapr);
+    spapr->ics = ICS_SPAPR(obj);
 }
 
 static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 5dabc9a138..691a6d00f7 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -31,11 +31,13 @@
 
 #define XICS_NODENAME "interrupt-controller"
 
+#define TYPE_ICS_SPAPR "ics-spapr"
+#define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
+
 void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
                    uint32_t phandle);
 int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
 void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
 bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
-void xics_spapr_init(SpaprMachineState *spapr);
 
 #endif /* XICS_SPAPR_H */
-- 
2.21.0



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

* [PULL 39/53] spapr: Fold spapr_phb_lsi_qirq() into its single caller
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (37 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 38/53] xics: Create sPAPR specific ICS subtype David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 40/53] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
                   ` (14 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Philippe Mathieu-Daudé,
	David Gibson

No point having a two-line helper that's used exactly once, and not likely
to be used anywhere else in future.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 hw/ppc/spapr_pci.c          | 3 ++-
 include/hw/pci-host/spapr.h | 7 -------
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index c1c9634755..01ff41d4c4 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -721,9 +721,10 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
      * corresponding qemu_irq.
      */
     SpaprPhbState *phb = opaque;
+    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
     trace_spapr_pci_lsi_set(phb->dtbusname, irq_num, phb->lsi_table[irq_num].irq);
-    qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
+    qemu_set_irq(spapr_qirq(spapr, phb->lsi_table[irq_num].irq), level);
 }
 
 static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index abd87605b2..23506f05d9 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -128,13 +128,6 @@ struct SpaprPhbState {
 #define SPAPR_PCI_NV2ATSD_WIN_SIZE   (NVGPU_MAX_NUM * NVGPU_MAX_LINKS * \
                                       64 * KiB)
 
-static inline qemu_irq spapr_phb_lsi_qirq(struct SpaprPhbState *phb, int pin)
-{
-    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
-
-    return spapr_qirq(spapr, phb->lsi_table[pin].irq);
-}
-
 int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
                  uint32_t nr_msis, int *node_offset);
 
-- 
2.21.0



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

* [PULL 40/53] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (38 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 39/53] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 41/53] spapr: Clarify and fix handling of nr_irqs David Gibson
                   ` (13 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Philippe Mathieu-Daudé,
	David Gibson

Every caller of spapr_vio_qirq() immediately calls qemu_irq_pulse() with
the result, so we might as well just fold that into the helper.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 hw/char/spapr_vty.c        | 3 +--
 hw/net/spapr_llan.c        | 3 +--
 hw/ppc/spapr_vio.c         | 3 +--
 include/hw/ppc/spapr_vio.h | 5 +++--
 4 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 087c93e4fa..8f4d9fe472 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -5,7 +5,6 @@
 #include "cpu.h"
 #include "migration/vmstate.h"
 #include "chardev/char-fe.h"
-#include "hw/irq.h"
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
 #include "hw/qdev-properties.h"
@@ -37,7 +36,7 @@ static void vty_receive(void *opaque, const uint8_t *buf, int size)
 
     if ((dev->in == dev->out) && size) {
         /* toggle line to simulate edge interrupt */
-        qemu_irq_pulse(spapr_vio_qirq(&dev->sdev));
+        spapr_vio_irq_pulse(&dev->sdev);
     }
     for (i = 0; i < size; i++) {
         if (dev->in - dev->out >= VTERM_BUFSIZE) {
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 701e6e1514..3d96884d66 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -27,7 +27,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "hw/irq.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "net/net.h"
@@ -267,7 +266,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
     }
 
     if (sdev->signal_state & 1) {
-        qemu_irq_pulse(spapr_vio_qirq(sdev));
+        spapr_vio_irq_pulse(sdev);
     }
 
     return size;
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 0803649658..554de9930d 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -23,7 +23,6 @@
 #include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
-#include "hw/irq.h"
 #include "qemu/log.h"
 #include "hw/loader.h"
 #include "elf.h"
@@ -294,7 +293,7 @@ int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq)
     dev->crq.qnext = (dev->crq.qnext + 16) % dev->crq.qsize;
 
     if (dev->signal_state & 1) {
-        qemu_irq_pulse(spapr_vio_qirq(dev));
+        spapr_vio_irq_pulse(dev);
     }
 
     return 0;
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index 875be28cdd..72762ed16b 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -24,6 +24,7 @@
 
 #include "hw/ppc/spapr.h"
 #include "sysemu/dma.h"
+#include "hw/irq.h"
 
 #define TYPE_VIO_SPAPR_DEVICE "vio-spapr-device"
 #define VIO_SPAPR_DEVICE(obj) \
@@ -84,11 +85,11 @@ extern SpaprVioDevice *spapr_vio_find_by_reg(SpaprVioBus *bus, uint32_t reg);
 void spapr_dt_vdevice(SpaprVioBus *bus, void *fdt);
 extern gchar *spapr_vio_stdout_path(SpaprVioBus *bus);
 
-static inline qemu_irq spapr_vio_qirq(SpaprVioDevice *dev)
+static inline void spapr_vio_irq_pulse(SpaprVioDevice *dev)
 {
     SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
-    return spapr_qirq(spapr, dev->irq);
+    qemu_irq_pulse(spapr_qirq(spapr, dev->irq));
 }
 
 static inline bool spapr_vio_dma_valid(SpaprVioDevice *dev, uint64_t taddr,
-- 
2.21.0



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

* [PULL 41/53] spapr: Clarify and fix handling of nr_irqs
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (39 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 40/53] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 42/53] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
                   ` (12 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

Both the XICS and XIVE interrupt backends have a "nr-irqs" property, but
it means slightly different things.  For XICS (or, strictly, the ICS) it
indicates the number of "real" external IRQs.  Those start at XICS_IRQ_BASE
(0x1000) and don't include the special IPI vector.  For XIVE, however, it
includes the whole IRQ space, including XIVE's many IPI vectors.

The spapr code currently doesn't handle this sensibly, with the
nr_irqs value in SpaprIrq having different meanings depending on the
backend.  We fix this by renaming nr_irqs to nr_xirqs and making it
always indicate just the number of external irqs, adjusting the value
we pass to XIVE accordingly.  We also move to using common constants
in most of the irq configurations, to make it clearer that the IRQ
space looks the same to the guest (and emulated devices), even if the
backend is different.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/spapr_irq.c         | 53 ++++++++++++++------------------------
 include/hw/ppc/spapr_irq.h | 19 +++++++++-----
 2 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8c26fa2d1e..3207b6bd01 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -92,7 +92,7 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
                                 Error **errp)
 {
     Object *obj;
@@ -102,7 +102,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
     object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
     object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
                                    &error_fatal);
-    object_property_set_int(obj, nr_irqs, "nr-irqs",  &error_fatal);
+    object_property_set_int(obj, nr_xirqs, "nr-irqs",  &error_fatal);
     object_property_set_bool(obj, true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -234,13 +234,9 @@ static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
     }
 }
 
-#define SPAPR_IRQ_XICS_NR_IRQS     0x1000
-#define SPAPR_IRQ_XICS_NR_MSIS     \
-    (XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI)
-
 SpaprIrq spapr_irq_xics = {
-    .nr_irqs     = SPAPR_IRQ_XICS_NR_IRQS,
-    .nr_msis     = SPAPR_IRQ_XICS_NR_MSIS,
+    .nr_xirqs    = SPAPR_NR_XIRQS,
+    .nr_msis     = SPAPR_NR_MSIS,
     .ov5         = SPAPR_OV5_XIVE_LEGACY,
 
     .init        = spapr_irq_init_xics,
@@ -260,7 +256,7 @@ SpaprIrq spapr_irq_xics = {
 /*
  * XIVE IRQ backend.
  */
-static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_xirqs,
                                 Error **errp)
 {
     uint32_t nr_servers = spapr_max_server_number(spapr);
@@ -268,7 +264,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
     int i;
 
     dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-    qdev_prop_set_uint32(dev, "nr-irqs", nr_irqs);
+    qdev_prop_set_uint32(dev, "nr-irqs", nr_xirqs + SPAPR_XIRQ_BASE);
     /*
      * 8 XIVE END structures per CPU. One for each available priority
      */
@@ -308,7 +304,7 @@ static qemu_irq spapr_qirq_xive(SpaprMachineState *spapr, int irq)
 {
     SpaprXive *xive = spapr->xive;
 
-    if (irq >= xive->nr_irqs) {
+    if ((irq < SPAPR_XIRQ_BASE) || (irq >= xive->nr_irqs)) {
         return NULL;
     }
 
@@ -404,17 +400,9 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
     }
 }
 
-/*
- * XIVE uses the full IRQ number space. Set it to 8K to be compatible
- * with XICS.
- */
-
-#define SPAPR_IRQ_XIVE_NR_IRQS     0x2000
-#define SPAPR_IRQ_XIVE_NR_MSIS     (SPAPR_IRQ_XIVE_NR_IRQS - SPAPR_IRQ_MSI)
-
 SpaprIrq spapr_irq_xive = {
-    .nr_irqs     = SPAPR_IRQ_XIVE_NR_IRQS,
-    .nr_msis     = SPAPR_IRQ_XIVE_NR_MSIS,
+    .nr_xirqs    = SPAPR_NR_XIRQS,
+    .nr_msis     = SPAPR_NR_MSIS,
     .ov5         = SPAPR_OV5_XIVE_EXPLOIT,
 
     .init        = spapr_irq_init_xive,
@@ -450,18 +438,18 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
         &spapr_irq_xive : &spapr_irq_xics;
 }
 
-static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_xirqs,
                                 Error **errp)
 {
     Error *local_err = NULL;
 
-    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_irqs, &local_err);
+    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_xirqs, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
 
-    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_irqs, &local_err);
+    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_xirqs, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
@@ -586,12 +574,9 @@ static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
 /*
  * Define values in sync with the XIVE and XICS backend
  */
-#define SPAPR_IRQ_DUAL_NR_IRQS     0x2000
-#define SPAPR_IRQ_DUAL_NR_MSIS     (SPAPR_IRQ_DUAL_NR_IRQS - SPAPR_IRQ_MSI)
-
 SpaprIrq spapr_irq_dual = {
-    .nr_irqs     = SPAPR_IRQ_DUAL_NR_IRQS,
-    .nr_msis     = SPAPR_IRQ_DUAL_NR_MSIS,
+    .nr_xirqs    = SPAPR_NR_XIRQS,
+    .nr_msis     = SPAPR_NR_MSIS,
     .ov5         = SPAPR_OV5_XIVE_BOTH,
 
     .init        = spapr_irq_init_dual,
@@ -693,10 +678,10 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
     }
 
-    spapr->irq->init(spapr, spapr->irq->nr_irqs, errp);
+    spapr->irq->init(spapr, spapr->irq->nr_xirqs, errp);
 
     spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
-                                      spapr->irq->nr_irqs);
+                                      spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
 }
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
@@ -804,11 +789,11 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
     return first + ics->offset;
 }
 
-#define SPAPR_IRQ_XICS_LEGACY_NR_IRQS     0x400
+#define SPAPR_IRQ_XICS_LEGACY_NR_XIRQS     0x400
 
 SpaprIrq spapr_irq_xics_legacy = {
-    .nr_irqs     = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
-    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
+    .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
+    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
     .ov5         = SPAPR_OV5_XIVE_LEGACY,
 
     .init        = spapr_irq_init_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 5db305165c..a8f9a2ab11 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -16,13 +16,18 @@
  * IRQ range offsets per device type
  */
 #define SPAPR_IRQ_IPI        0x0
-#define SPAPR_IRQ_EPOW       0x1000  /* XICS_IRQ_BASE offset */
-#define SPAPR_IRQ_HOTPLUG    0x1001
-#define SPAPR_IRQ_VIO        0x1100  /* 256 VIO devices */
-#define SPAPR_IRQ_PCI_LSI    0x1200  /* 32+ PHBs devices */
 
-#define SPAPR_IRQ_MSI        0x1300  /* Offset of the dynamic range covered
-                                      * by the bitmap allocator */
+#define SPAPR_XIRQ_BASE      XICS_IRQ_BASE /* 0x1000 */
+#define SPAPR_IRQ_EPOW       (SPAPR_XIRQ_BASE + 0x0000)
+#define SPAPR_IRQ_HOTPLUG    (SPAPR_XIRQ_BASE + 0x0001)
+#define SPAPR_IRQ_VIO        (SPAPR_XIRQ_BASE + 0x0100)  /* 256 VIO devices */
+#define SPAPR_IRQ_PCI_LSI    (SPAPR_XIRQ_BASE + 0x0200)  /* 32+ PHBs devices */
+
+/* Offset of the dynamic range covered by the bitmap allocator */
+#define SPAPR_IRQ_MSI        (SPAPR_XIRQ_BASE + 0x0300)
+
+#define SPAPR_NR_XIRQS       0x1000
+#define SPAPR_NR_MSIS        (SPAPR_XIRQ_BASE + SPAPR_NR_XIRQS - SPAPR_IRQ_MSI)
 
 typedef struct SpaprMachineState SpaprMachineState;
 
@@ -32,7 +37,7 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
 void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
 
 typedef struct SpaprIrq {
-    uint32_t    nr_irqs;
+    uint32_t    nr_xirqs;
     uint32_t    nr_msis;
     uint8_t     ov5;
 
-- 
2.21.0



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

* [PULL 42/53] spapr: Eliminate nr_irqs parameter to SpaprIrq::init
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (40 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 41/53] spapr: Clarify and fix handling of nr_irqs David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 43/53] spapr: Fix indexing of XICS irqs David Gibson
                   ` (11 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

The only reason this parameter was needed was to work around the
inconsistent meaning of nr_irqs between xics and xive.  Now that we've
fixed that, we can consistently use the number directly in the SpaprIrq
configuration.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr_irq.c         | 21 ++++++++++-----------
 include/hw/ppc/spapr_irq.h |  2 +-
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 3207b6bd01..cded3a0154 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -92,8 +92,7 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
-                                Error **errp)
+static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
 {
     Object *obj;
     Error *local_err = NULL;
@@ -102,7 +101,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
     object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
     object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
                                    &error_fatal);
-    object_property_set_int(obj, nr_xirqs, "nr-irqs",  &error_fatal);
+    object_property_set_int(obj, spapr->irq->nr_xirqs,
+                            "nr-irqs",  &error_fatal);
     object_property_set_bool(obj, true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -256,15 +256,15 @@ SpaprIrq spapr_irq_xics = {
 /*
  * XIVE IRQ backend.
  */
-static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_xirqs,
-                                Error **errp)
+static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
 {
     uint32_t nr_servers = spapr_max_server_number(spapr);
     DeviceState *dev;
     int i;
 
     dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-    qdev_prop_set_uint32(dev, "nr-irqs", nr_xirqs + SPAPR_XIRQ_BASE);
+    qdev_prop_set_uint32(dev, "nr-irqs",
+                         spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
     /*
      * 8 XIVE END structures per CPU. One for each available priority
      */
@@ -438,18 +438,17 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
         &spapr_irq_xive : &spapr_irq_xics;
 }
 
-static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_xirqs,
-                                Error **errp)
+static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
 {
     Error *local_err = NULL;
 
-    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_xirqs, &local_err);
+    spapr_irq_xics.init(spapr, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
 
-    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_xirqs, &local_err);
+    spapr_irq_xive.init(spapr, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
@@ -678,7 +677,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
     }
 
-    spapr->irq->init(spapr, spapr->irq->nr_xirqs, errp);
+    spapr->irq->init(spapr, errp);
 
     spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
                                       spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index a8f9a2ab11..7e26288fcd 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -41,7 +41,7 @@ typedef struct SpaprIrq {
     uint32_t    nr_msis;
     uint8_t     ov5;
 
-    void (*init)(SpaprMachineState *spapr, int nr_irqs, Error **errp);
+    void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
     void (*free)(SpaprMachineState *spapr, int irq, int num);
     qemu_irq (*qirq)(SpaprMachineState *spapr, int irq);
-- 
2.21.0



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

* [PULL 43/53] spapr: Fix indexing of XICS irqs
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (41 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 42/53] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 44/53] spapr: Simplify spapr_qirq() handling David Gibson
                   ` (10 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

spapr global irq numbers are different from the source numbers on the ICS
when using XICS - they're offset by XICS_IRQ_BASE (0x1000).  But
spapr_irq_set_irq_xics() was passing through the global irq number to
the ICS code unmodified.

We only got away with this because of a counteracting bug - we were
incorrectly adjusting the qemu_irq we returned for a requested global irq
number.

That approach mostly worked but is very confusing, incorrectly relies on
the way the qemu_irq array is allocated, and undermines the intention of
having the global array of qemu_irqs for spapr have a consistent meaning
regardless of irq backend.

So, fix both set_irq and qemu_irq indexing.  We rename some parameters at
the same time to make it clear that they are referring to spapr global
irq numbers.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr_irq.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index cded3a0154..8f79aa829f 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -153,10 +153,9 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
 static qemu_irq spapr_qirq_xics(SpaprMachineState *spapr, int irq)
 {
     ICSState *ics = spapr->ics;
-    uint32_t srcno = irq - ics->offset;
 
     if (ics_valid_irq(ics, irq)) {
-        return spapr->qirqs[srcno];
+        return spapr->qirqs[irq];
     }
 
     return NULL;
@@ -204,9 +203,10 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
     return 0;
 }
 
-static void spapr_irq_set_irq_xics(void *opaque, int srcno, int val)
+static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
 {
     SpaprMachineState *spapr = opaque;
+    uint32_t srcno = irq - spapr->ics->offset;
 
     ics_set_irq(spapr->ics, srcno, val);
 }
@@ -377,14 +377,14 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
     spapr_xive_mmio_set_enabled(spapr->xive, true);
 }
 
-static void spapr_irq_set_irq_xive(void *opaque, int srcno, int val)
+static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
 {
     SpaprMachineState *spapr = opaque;
 
     if (kvm_irqchip_in_kernel()) {
-        kvmppc_xive_source_set_irq(&spapr->xive->source, srcno, val);
+        kvmppc_xive_source_set_irq(&spapr->xive->source, irq, val);
     } else {
-        xive_source_set_irq(&spapr->xive->source, srcno, val);
+        xive_source_set_irq(&spapr->xive->source, irq, val);
     }
 }
 
@@ -558,11 +558,11 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
     spapr_irq_current(spapr)->reset(spapr, errp);
 }
 
-static void spapr_irq_set_irq_dual(void *opaque, int srcno, int val)
+static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
 {
     SpaprMachineState *spapr = opaque;
 
-    spapr_irq_current(spapr)->set_irq(spapr, srcno, val);
+    spapr_irq_current(spapr)->set_irq(spapr, irq, val);
 }
 
 static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
-- 
2.21.0



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

* [PULL 44/53] spapr: Simplify spapr_qirq() handling
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (42 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 43/53] spapr: Fix indexing of XICS irqs David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 45/53] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
                   ` (9 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Philippe Mathieu-Daudé,
	David Gibson

Currently spapr_qirq(), whic is used to find the qemu_irq for an spapr
global irq number, redirects through the SpaprIrq::qirq method.  But
the array of qemu_irqs is allocated in the PAPR layer, not the
backends, and so the method implementations all return the same thing,
just differing in the preliminary checks they make.

So, we can remove the method, and just implement spapr_qirq() directly,
including all the relevant checks in one place.  We change all those
checks into assert()s as well, since a failure here indicates an error in
the calling code.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 hw/ppc/spapr_irq.c         | 54 ++++++++++++++------------------------
 include/hw/ppc/spapr_irq.h |  1 -
 2 files changed, 19 insertions(+), 36 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8f79aa829f..8f179076c6 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -150,17 +150,6 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
     }
 }
 
-static qemu_irq spapr_qirq_xics(SpaprMachineState *spapr, int irq)
-{
-    ICSState *ics = spapr->ics;
-
-    if (ics_valid_irq(ics, irq)) {
-        return spapr->qirqs[irq];
-    }
-
-    return NULL;
-}
-
 static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
 {
     CPUState *cs;
@@ -242,7 +231,6 @@ SpaprIrq spapr_irq_xics = {
     .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
     .free        = spapr_irq_free_xics,
-    .qirq        = spapr_qirq_xics,
     .print_info  = spapr_irq_print_info_xics,
     .dt_populate = spapr_dt_xics,
     .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
@@ -300,20 +288,6 @@ static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq, int num)
     }
 }
 
-static qemu_irq spapr_qirq_xive(SpaprMachineState *spapr, int irq)
-{
-    SpaprXive *xive = spapr->xive;
-
-    if ((irq < SPAPR_XIRQ_BASE) || (irq >= xive->nr_irqs)) {
-        return NULL;
-    }
-
-    /* The sPAPR machine/device should have claimed the IRQ before */
-    assert(xive_eas_is_valid(&xive->eat[irq]));
-
-    return spapr->qirqs[irq];
-}
-
 static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
                                       Monitor *mon)
 {
@@ -408,7 +382,6 @@ SpaprIrq spapr_irq_xive = {
     .init        = spapr_irq_init_xive,
     .claim       = spapr_irq_claim_xive,
     .free        = spapr_irq_free_xive,
-    .qirq        = spapr_qirq_xive,
     .print_info  = spapr_irq_print_info_xive,
     .dt_populate = spapr_dt_xive,
     .cpu_intc_create = spapr_irq_cpu_intc_create_xive,
@@ -482,11 +455,6 @@ static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq, int num)
     spapr_irq_xive.free(spapr, irq, num);
 }
 
-static qemu_irq spapr_qirq_dual(SpaprMachineState *spapr, int irq)
-{
-    return spapr_irq_current(spapr)->qirq(spapr, irq);
-}
-
 static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
 {
     spapr_irq_current(spapr)->print_info(spapr, mon);
@@ -581,7 +549,6 @@ SpaprIrq spapr_irq_dual = {
     .init        = spapr_irq_init_dual,
     .claim       = spapr_irq_claim_dual,
     .free        = spapr_irq_free_dual,
-    .qirq        = spapr_qirq_dual,
     .print_info  = spapr_irq_print_info_dual,
     .dt_populate = spapr_irq_dt_populate_dual,
     .cpu_intc_create = spapr_irq_cpu_intc_create_dual,
@@ -695,7 +662,25 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 
 qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
 {
-    return spapr->irq->qirq(spapr, irq);
+    /*
+     * This interface is basically for VIO and PHB devices to find the
+     * right qemu_irq to manipulate, so we only allow access to the
+     * external irqs for now.  Currently anything which needs to
+     * access the IPIs most naturally gets there via the guest side
+     * interfaces, we can change this if we need to in future.
+     */
+    assert(irq >= SPAPR_XIRQ_BASE);
+    assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+
+    if (spapr->ics) {
+        assert(ics_valid_irq(spapr->ics, irq));
+    }
+    if (spapr->xive) {
+        assert(irq < spapr->xive->nr_irqs);
+        assert(xive_eas_is_valid(&spapr->xive->eat[irq]));
+    }
+
+    return spapr->qirqs[irq];
 }
 
 int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
@@ -798,7 +783,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
     .free        = spapr_irq_free_xics,
-    .qirq        = spapr_qirq_xics,
     .print_info  = spapr_irq_print_info_xics,
     .dt_populate = spapr_dt_xics,
     .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 7e26288fcd..a4e790ef60 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -44,7 +44,6 @@ typedef struct SpaprIrq {
     void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
     void (*free)(SpaprMachineState *spapr, int irq, int num);
-    qemu_irq (*qirq)(SpaprMachineState *spapr, int irq);
     void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
     void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
                         void *fdt, uint32_t phandle);
-- 
2.21.0



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

* [PULL 45/53] spapr: Eliminate SpaprIrq:get_nodename method
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (43 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 44/53] spapr: Simplify spapr_qirq() handling David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 46/53] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
                   ` (8 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Philippe Mathieu-Daudé,
	David Gibson

This method is used to determine the name of the irq backend's node in the
device tree, so that we can find its phandle (after SLOF may have modified
it from the phandle we initially gave it).

But, in the two cases the only difference between the node name is the
presence of a unit address.  Searching for a node name without considering
unit address is standard practice for the device tree, and
fdt_subnode_offset() will do exactly that, making this method unecessary.

While we're there, remove the XICS_NODENAME define.  The name
"interrupt-controller" is required by PAPR (and IEEE1275), and a bunch of
places assume it already.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/xics_spapr.c        |  2 +-
 hw/ppc/spapr_irq.c          | 25 +++----------------------
 include/hw/ppc/spapr_irq.h  |  1 -
 include/hw/ppc/xics_spapr.h |  2 --
 4 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index e6dd004587..6e5eb24b3c 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -316,7 +316,7 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
     };
     int node;
 
-    _FDT(node = fdt_add_subnode(fdt, 0, XICS_NODENAME));
+    _FDT(node = fdt_add_subnode(fdt, 0, "interrupt-controller"));
 
     _FDT(fdt_setprop_string(fdt, node, "device_type",
                             "PowerPC-External-Interrupt-Presentation"));
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8f179076c6..ec2229d2d1 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -211,11 +211,6 @@ static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
     }
 }
 
-static const char *spapr_irq_get_nodename_xics(SpaprMachineState *spapr)
-{
-    return XICS_NODENAME;
-}
-
 static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
 {
     if (kvm_enabled()) {
@@ -237,7 +232,6 @@ SpaprIrq spapr_irq_xics = {
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
     .set_irq     = spapr_irq_set_irq_xics,
-    .get_nodename = spapr_irq_get_nodename_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
 };
 
@@ -362,11 +356,6 @@ static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
     }
 }
 
-static const char *spapr_irq_get_nodename_xive(SpaprMachineState *spapr)
-{
-    return spapr->xive->nodename;
-}
-
 static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
 {
     if (kvm_enabled()) {
@@ -388,7 +377,6 @@ SpaprIrq spapr_irq_xive = {
     .post_load   = spapr_irq_post_load_xive,
     .reset       = spapr_irq_reset_xive,
     .set_irq     = spapr_irq_set_irq_xive,
-    .get_nodename = spapr_irq_get_nodename_xive,
     .init_kvm    = spapr_irq_init_kvm_xive,
 };
 
@@ -533,11 +521,6 @@ static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
     spapr_irq_current(spapr)->set_irq(spapr, irq, val);
 }
 
-static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
-{
-    return spapr_irq_current(spapr)->get_nodename(spapr);
-}
-
 /*
  * Define values in sync with the XIVE and XICS backend
  */
@@ -555,7 +538,6 @@ SpaprIrq spapr_irq_dual = {
     .post_load   = spapr_irq_post_load_dual,
     .reset       = spapr_irq_reset_dual,
     .set_irq     = spapr_irq_set_irq_dual,
-    .get_nodename = spapr_irq_get_nodename_dual,
     .init_kvm    = NULL, /* should not be used */
 };
 
@@ -699,13 +681,13 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
 
 int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp)
 {
-    const char *nodename = spapr->irq->get_nodename(spapr);
+    const char *nodename = "interrupt-controller";
     int offset, phandle;
 
     offset = fdt_subnode_offset(fdt, 0, nodename);
     if (offset < 0) {
-        error_setg(errp, "Can't find node \"%s\": %s", nodename,
-                   fdt_strerror(offset));
+        error_setg(errp, "Can't find node \"%s\": %s",
+                   nodename, fdt_strerror(offset));
         return -1;
     }
 
@@ -789,6 +771,5 @@ SpaprIrq spapr_irq_xics_legacy = {
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
     .set_irq     = spapr_irq_set_irq_xics,
-    .get_nodename = spapr_irq_get_nodename_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
 };
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index a4e790ef60..9b60378e28 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -52,7 +52,6 @@ typedef struct SpaprIrq {
     int (*post_load)(SpaprMachineState *spapr, int version_id);
     void (*reset)(SpaprMachineState *spapr, Error **errp);
     void (*set_irq)(void *opaque, int srcno, int val);
-    const char *(*get_nodename)(SpaprMachineState *spapr);
     void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
 } SpaprIrq;
 
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 691a6d00f7..0b35e85c26 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -29,8 +29,6 @@
 
 #include "hw/ppc/spapr.h"
 
-#define XICS_NODENAME "interrupt-controller"
-
 #define TYPE_ICS_SPAPR "ics-spapr"
 #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
 
-- 
2.21.0



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

* [PULL 46/53] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (44 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 45/53] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 47/53] spapr: Handle freeing of multiple irqs in frontend only David Gibson
                   ` (7 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Philippe Mathieu-Daudé,
	David Gibson

These traces contain some useless information (the always-0 source#) and
have no equivalents for XIVE mode.  For now just remove them, and we can
put back something more sensible if and when we need it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 hw/ppc/spapr_irq.c  | 4 ----
 hw/ppc/trace-events | 4 ----
 2 files changed, 8 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index ec2229d2d1..9919910a86 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -140,11 +140,7 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
     int i;
 
     if (ics_valid_irq(ics, irq)) {
-        trace_spapr_irq_free(0, irq, num);
         for (i = srcno; i < srcno + num; ++i) {
-            if (ics_irq_free(ics, i)) {
-                trace_spapr_irq_free_warn(0, i);
-            }
             memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
         }
     }
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
index 96dad767a1..9ea620f23c 100644
--- a/hw/ppc/trace-events
+++ b/hw/ppc/trace-events
@@ -13,10 +13,6 @@ spapr_pci_msi_retry(unsigned config_addr, unsigned req_num, unsigned max_irqs) "
 spapr_cas_failed(unsigned long n) "DT diff buffer is too small: %ld bytes"
 spapr_cas_continue(unsigned long n) "Copy changes to the guest: %ld bytes"
 
-# spapr_irq.c
-spapr_irq_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
-spapr_irq_free_warn(int src, int irq) "Source#%d, irq %d is already free"
-
 # spapr_hcall.c
 spapr_cas_pvr(uint32_t cur_pvr, bool explicit_match, uint32_t new_pvr) "current=0x%x, explicit_match=%u, new=0x%x"
 spapr_h_resize_hpt_prepare(uint64_t flags, uint64_t shift) "flags=0x%"PRIx64", shift=%"PRIu64
-- 
2.21.0



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

* [PULL 47/53] spapr: Handle freeing of multiple irqs in frontend only
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (45 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 46/53] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 48/53] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
                   ` (6 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

spapr_irq_free() can be used to free multiple irqs at once. That's useful
for its callers, but there's no need to make the individual backend hooks
handle this.  We can loop across the irqs in spapr_irq_free() itself and
have the hooks just do one at time.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/spapr_irq.c         | 27 ++++++++++++---------------
 include/hw/ppc/spapr_irq.h |  2 +-
 2 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 9919910a86..d2ac35bbe1 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -133,16 +133,13 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
     return 0;
 }
 
-static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
+static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
 {
     ICSState *ics = spapr->ics;
     uint32_t srcno = irq - ics->offset;
-    int i;
 
     if (ics_valid_irq(ics, irq)) {
-        for (i = srcno; i < srcno + num; ++i) {
-            memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
-        }
+        memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
     }
 }
 
@@ -269,13 +266,9 @@ static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
     return 0;
 }
 
-static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq, int num)
+static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
 {
-    int i;
-
-    for (i = irq; i < irq + num; ++i) {
-        spapr_xive_irq_free(spapr->xive, i);
-    }
+    spapr_xive_irq_free(spapr->xive, irq);
 }
 
 static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
@@ -433,10 +426,10 @@ static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
     return ret;
 }
 
-static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq, int num)
+static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
 {
-    spapr_irq_xics.free(spapr, irq, num);
-    spapr_irq_xive.free(spapr, irq, num);
+    spapr_irq_xics.free(spapr, irq);
+    spapr_irq_xive.free(spapr, irq);
 }
 
 static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
@@ -635,7 +628,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 
 void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 {
-    spapr->irq->free(spapr, irq, num);
+    int i;
+
+    for (i = irq; i < (irq + num); i++) {
+        spapr->irq->free(spapr, i);
+    }
 }
 
 qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 9b60378e28..ed88b4599a 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -43,7 +43,7 @@ typedef struct SpaprIrq {
 
     void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
-    void (*free)(SpaprMachineState *spapr, int irq, int num);
+    void (*free)(SpaprMachineState *spapr, int irq);
     void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
     void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
                         void *fdt, uint32_t phandle);
-- 
2.21.0



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

* [PULL 48/53] spapr, xics, xive: Better use of assert()s on irq claim/free paths
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (46 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 47/53] spapr: Handle freeing of multiple irqs in frontend only David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 49/53] xive: Improve irq claim/free path David Gibson
                   ` (5 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

The irq claim and free paths for both XICS and XIVE check for some
validity conditions.  Some of these represent genuine runtime failures,
however others - particularly checking that the basic irq number is in a
sane range - could only fail in the case of bugs in the callin code.
Therefore use assert()s instead of runtime failures for those.

In addition the non backend-specific part of the claim/free paths should
only be used for PAPR external irqs, that is in the range SPAPR_XIRQ_BASE
to the maximum irq number.  Put assert()s for that into the top level
dispatchers as well.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/spapr_xive.c |  8 ++------
 hw/ppc/spapr_irq.c   | 18 ++++++++++--------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index c1c97192a7..47b5ec0b56 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -532,9 +532,7 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
 {
     XiveSource *xsrc = &xive->source;
 
-    if (lisn >= xive->nr_irqs) {
-        return false;
-    }
+    assert(lisn < xive->nr_irqs);
 
     /*
      * Set default values when allocating an IRQ number
@@ -559,9 +557,7 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
 
 bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
 {
-    if (lisn >= xive->nr_irqs) {
-        return false;
-    }
+    assert(lisn < xive->nr_irqs);
 
     xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
     return true;
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index d2ac35bbe1..025c802e7b 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -118,11 +118,7 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
     ICSState *ics = spapr->ics;
 
     assert(ics);
-
-    if (!ics_valid_irq(ics, irq)) {
-        error_setg(errp, "IRQ %d is invalid", irq);
-        return -1;
-    }
+    assert(ics_valid_irq(ics, irq));
 
     if (!ics_irq_free(ics, irq - ics->offset)) {
         error_setg(errp, "IRQ %d is not free", irq);
@@ -138,9 +134,9 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
     ICSState *ics = spapr->ics;
     uint32_t srcno = irq - ics->offset;
 
-    if (ics_valid_irq(ics, irq)) {
-        memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
-    }
+    assert(ics_valid_irq(ics, irq));
+
+    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
 }
 
 static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
@@ -623,6 +619,9 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 {
+    assert(irq >= SPAPR_XIRQ_BASE);
+    assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+
     return spapr->irq->claim(spapr, irq, lsi, errp);
 }
 
@@ -630,6 +629,9 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 {
     int i;
 
+    assert(irq >= SPAPR_XIRQ_BASE);
+    assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+
     for (i = irq; i < (irq + num); i++) {
         spapr->irq->free(spapr, i);
     }
-- 
2.21.0



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

* [PULL 49/53] xive: Improve irq claim/free path
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (47 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 48/53] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 50/53] spapr: Use less cryptic representation of which irq backends are supported David Gibson
                   ` (4 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

spapr_xive_irq_claim() returns a bool to indicate if it succeeded.
But most of the callers and one callee use int return values and/or an
Error * with more information instead.  In any case, ints are a more
common idiom for success/failure states than bools (one never knows
what sense they'll be in).

So instead change to an int return value to indicate presence of error
+ an Error * to describe the details through that call chain.

It also didn't actually check if the irq was already claimed, which is
one of the primary purposes of the claim path, so do that.

spapr_xive_irq_free() also returned a bool... which no callers checked
and was always true, so just drop it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/spapr_xive.c        | 20 +++++++++-----------
 hw/intc/spapr_xive_kvm.c    |  8 ++++----
 hw/ppc/spapr_irq.c          | 11 +++++------
 include/hw/ppc/spapr_xive.h |  4 ++--
 include/hw/ppc/xive.h       |  2 +-
 5 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 47b5ec0b56..04879abf2e 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -528,12 +528,17 @@ static void spapr_xive_register_types(void)
 
 type_init(spapr_xive_register_types)
 
-bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
+int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
 {
     XiveSource *xsrc = &xive->source;
 
     assert(lisn < xive->nr_irqs);
 
+    if (xive_eas_is_valid(&xive->eat[lisn])) {
+        error_setg(errp, "IRQ %d is not free", lisn);
+        return -EBUSY;
+    }
+
     /*
      * Set default values when allocating an IRQ number
      */
@@ -543,24 +548,17 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
     }
 
     if (kvm_irqchip_in_kernel()) {
-        Error *local_err = NULL;
-
-        kvmppc_xive_source_reset_one(xsrc, lisn, &local_err);
-        if (local_err) {
-            error_report_err(local_err);
-            return false;
-        }
+        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
     }
 
-    return true;
+    return 0;
 }
 
-bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
+void spapr_xive_irq_free(SpaprXive *xive, int lisn)
 {
     assert(lisn < xive->nr_irqs);
 
     xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
-    return true;
 }
 
 /*
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 2006f96aec..51b334b676 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -232,14 +232,14 @@ void kvmppc_xive_sync_source(SpaprXive *xive, uint32_t lisn, Error **errp)
  * only need to inform the KVM XIVE device about their type: LSI or
  * MSI.
  */
-void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
+int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
 {
     SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
     uint64_t state = 0;
 
     /* The KVM XIVE device is not in use */
     if (xive->fd == -1) {
-        return;
+        return -ENODEV;
     }
 
     if (xive_source_irq_is_lsi(xsrc, srcno)) {
@@ -249,8 +249,8 @@ void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
         }
     }
 
-    kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, &state,
-                      true, errp);
+    return kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, &state,
+                             true, errp);
 }
 
 static void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp)
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 025c802e7b..516bf00a35 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -246,7 +246,10 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
 
     /* Enable the CPU IPIs */
     for (i = 0; i < nr_servers; ++i) {
-        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false);
+        if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
+                                 false, errp) < 0) {
+            return;
+        }
     }
 
     spapr_xive_hcall_init(spapr);
@@ -255,11 +258,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
 static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
                                 Error **errp)
 {
-    if (!spapr_xive_irq_claim(spapr->xive, irq, lsi)) {
-        error_setg(errp, "IRQ %d is invalid", irq);
-        return -1;
-    }
-    return 0;
+    return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp);
 }
 
 static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index bfd40f01d8..0df20a6590 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -54,8 +54,8 @@ typedef struct SpaprXive {
  */
 #define SPAPR_XIVE_BLOCK_ID 0x0
 
-bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi);
-bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn);
+int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp);
+void spapr_xive_irq_free(SpaprXive *xive, int lisn);
 void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
 int spapr_xive_post_load(SpaprXive *xive, int version_id);
 
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 6d38755f84..fd3319bd32 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -425,7 +425,7 @@ static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
  * KVM XIVE device helpers
  */
 
-void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp);
+int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp);
 void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val);
 void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp);
 void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp);
-- 
2.21.0



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

* [PULL 50/53] spapr: Use less cryptic representation of which irq backends are supported
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (48 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 49/53] xive: Improve irq claim/free path David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 51/53] spapr: Add return value to spapr_irq_check() David Gibson
                   ` (3 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

SpaprIrq::ov5 stores the value for a particular byte in PAPR option vector
5 which indicates whether XICS, XIVE or both interrupt controllers are
available.  As usual for PAPR, the encoding is kind of overly complicated
and confusing (though to be fair there are some backwards compat things it
has to handle).

But to make our internal code clearer, have SpaprIrq encode more directly
which backends are available as two booleans, and derive the OV5 value from
that at the point we need it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr.c             | 15 ++++++++++++---
 hw/ppc/spapr_hcall.c       |  6 +++---
 hw/ppc/spapr_irq.c         | 12 ++++++++----
 include/hw/ppc/spapr_irq.h |  3 ++-
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 43920c140d..514a17ae74 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1066,19 +1066,28 @@ static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
     PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
 
     char val[2 * 4] = {
-        23, spapr->irq->ov5, /* Xive mode. */
+        23, 0x00, /* XICS / XIVE mode */
         24, 0x00, /* Hash/Radix, filled in below. */
         25, 0x00, /* Hash options: Segment Tables == no, GTSE == no. */
         26, 0x40, /* Radix options: GTSE == yes. */
     };
 
+    if (spapr->irq->xics && spapr->irq->xive) {
+        val[1] = SPAPR_OV5_XIVE_BOTH;
+    } else if (spapr->irq->xive) {
+        val[1] = SPAPR_OV5_XIVE_EXPLOIT;
+    } else {
+        assert(spapr->irq->xics);
+        val[1] = SPAPR_OV5_XIVE_LEGACY;
+    }
+
     if (!ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
                           first_ppc_cpu->compat_pvr)) {
         /*
          * If we're in a pre POWER9 compat mode then the guest should
          * do hash and use the legacy interrupt mode
          */
-        val[1] = 0x00; /* XICS */
+        val[1] = SPAPR_OV5_XIVE_LEGACY; /* XICS */
         val[3] = 0x00; /* Hash */
     } else if (kvm_enabled()) {
         if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) {
@@ -2767,7 +2776,7 @@ static void spapr_machine_init(MachineState *machine)
     spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
 
     /* advertise XIVE on POWER9 machines */
-    if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) {
+    if (spapr->irq->xive) {
         spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
     }
 
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 3d3a67149a..140f05c1c6 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1784,13 +1784,13 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
      * terminate the boot.
      */
     if (guest_xive) {
-        if (spapr->irq->ov5 == SPAPR_OV5_XIVE_LEGACY) {
+        if (!spapr->irq->xive) {
             error_report(
 "Guest requested unavailable interrupt mode (XIVE), try the ic-mode=xive or ic-mode=dual machine property");
             exit(EXIT_FAILURE);
         }
     } else {
-        if (spapr->irq->ov5 == SPAPR_OV5_XIVE_EXPLOIT) {
+        if (!spapr->irq->xics) {
             error_report(
 "Guest requested unavailable interrupt mode (XICS), either don't set the ic-mode machine property or try ic-mode=xics or ic-mode=dual");
             exit(EXIT_FAILURE);
@@ -1804,7 +1804,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
      */
     if (!spapr->cas_reboot) {
         spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
-            && spapr->irq->ov5 & SPAPR_OV5_XIVE_BOTH;
+            && spapr->irq->xics && spapr->irq->xive;
     }
 
     spapr_ovec_cleanup(ov5_updates);
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 516bf00a35..3ac67ba0c7 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -210,7 +210,8 @@ static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
 SpaprIrq spapr_irq_xics = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
-    .ov5         = SPAPR_OV5_XIVE_LEGACY,
+    .xics        = true,
+    .xive        = false,
 
     .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
@@ -350,7 +351,8 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
 SpaprIrq spapr_irq_xive = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
-    .ov5         = SPAPR_OV5_XIVE_EXPLOIT,
+    .xics        = false,
+    .xive        = true,
 
     .init        = spapr_irq_init_xive,
     .claim       = spapr_irq_claim_xive,
@@ -511,7 +513,8 @@ static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
 SpaprIrq spapr_irq_dual = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
-    .ov5         = SPAPR_OV5_XIVE_BOTH,
+    .xics        = true,
+    .xive        = true,
 
     .init        = spapr_irq_init_dual,
     .claim       = spapr_irq_claim_dual,
@@ -754,7 +757,8 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
 SpaprIrq spapr_irq_xics_legacy = {
     .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
     .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
-    .ov5         = SPAPR_OV5_XIVE_LEGACY,
+    .xics        = true,
+    .xive        = false,
 
     .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index ed88b4599a..d3f3b85eb9 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -39,7 +39,8 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
 typedef struct SpaprIrq {
     uint32_t    nr_xirqs;
     uint32_t    nr_msis;
-    uint8_t     ov5;
+    bool        xics;
+    bool        xive;
 
     void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
-- 
2.21.0



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

* [PULL 51/53] spapr: Add return value to spapr_irq_check()
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (49 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 50/53] spapr: Use less cryptic representation of which irq backends are supported David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 52/53] spapr: Eliminate SpaprIrq::init hook David Gibson
                   ` (2 subsequent siblings)
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

Explicitly return success or failure, rather than just relying on the
Error ** parameter.  This makes handling it less verbose in the caller.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr_irq.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 3ac67ba0c7..0413fbd0a3 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -529,7 +529,7 @@ SpaprIrq spapr_irq_dual = {
 };
 
 
-static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
+static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
 
@@ -545,7 +545,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
          */
         if (spapr->irq == &spapr_irq_dual) {
             spapr->irq = &spapr_irq_xics;
-            return;
+            return 0;
         }
 
         /*
@@ -565,7 +565,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
          */
         if (spapr->irq == &spapr_irq_xive) {
             error_setg(errp, "XIVE-only machines require a POWER9 CPU");
-            return;
+            return -1;
         }
     }
 
@@ -579,8 +579,10 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
         machine_kernel_irqchip_required(machine) &&
         xics_kvm_has_broken_disconnect(spapr)) {
         error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
-        return;
+        return -1;
     }
+
+    return 0;
 }
 
 /*
@@ -589,7 +591,6 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
-    Error *local_err = NULL;
 
     if (machine_kernel_irqchip_split(machine)) {
         error_setg(errp, "kernel_irqchip split mode not supported on pseries");
@@ -602,9 +603,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         return;
     }
 
-    spapr_irq_check(spapr, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
+    if (spapr_irq_check(spapr, errp) < 0) {
         return;
     }
 
-- 
2.21.0



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

* [PULL 52/53] spapr: Eliminate SpaprIrq::init hook
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (50 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 51/53] spapr: Add return value to spapr_irq_check() David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-04  9:37 ` [PULL 53/53] ppc/pnv: Remove the XICSFabric Interface from the POWER9 machine David Gibson
  2019-10-07 14:40 ` [PULL 00/53] ppc-for-4.2 queue 20191004 Peter Maydell
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

This method is used to set up the interrupt backends for the current
configuration.  However, this means some confusing redirection between
the "dual" mode init and the init hooks for xics only and xive only modes.

Since we now have simple flags indicating whether XICS and/or XIVE are
supported, it's easier to just open code each initialization directly in
spapr_irq_init().  This will also make some future cleanups simpler.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr_irq.c         | 130 +++++++++++++++++--------------------
 include/hw/ppc/spapr_irq.h |   1 -
 2 files changed, 61 insertions(+), 70 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 0413fbd0a3..457eabe24c 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -92,26 +92,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
-{
-    Object *obj;
-    Error *local_err = NULL;
-
-    obj = object_new(TYPE_ICS_SPAPR);
-    object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
-    object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
-                                   &error_fatal);
-    object_property_set_int(obj, spapr->irq->nr_xirqs,
-                            "nr-irqs",  &error_fatal);
-    object_property_set_bool(obj, true, "realized", &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    spapr->ics = ICS_SPAPR(obj);
-}
-
 static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
                                 Error **errp)
 {
@@ -213,7 +193,6 @@ SpaprIrq spapr_irq_xics = {
     .xics        = true,
     .xive        = false,
 
-    .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
     .free        = spapr_irq_free_xics,
     .print_info  = spapr_irq_print_info_xics,
@@ -228,33 +207,6 @@ SpaprIrq spapr_irq_xics = {
 /*
  * XIVE IRQ backend.
  */
-static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
-{
-    uint32_t nr_servers = spapr_max_server_number(spapr);
-    DeviceState *dev;
-    int i;
-
-    dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-    qdev_prop_set_uint32(dev, "nr-irqs",
-                         spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
-    /*
-     * 8 XIVE END structures per CPU. One for each available priority
-     */
-    qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
-    qdev_init_nofail(dev);
-
-    spapr->xive = SPAPR_XIVE(dev);
-
-    /* Enable the CPU IPIs */
-    for (i = 0; i < nr_servers; ++i) {
-        if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
-                                 false, errp) < 0) {
-            return;
-        }
-    }
-
-    spapr_xive_hcall_init(spapr);
-}
 
 static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
                                 Error **errp)
@@ -354,7 +306,6 @@ SpaprIrq spapr_irq_xive = {
     .xics        = false,
     .xive        = true,
 
-    .init        = spapr_irq_init_xive,
     .claim       = spapr_irq_claim_xive,
     .free        = spapr_irq_free_xive,
     .print_info  = spapr_irq_print_info_xive,
@@ -385,23 +336,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
         &spapr_irq_xive : &spapr_irq_xics;
 }
 
-static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
-{
-    Error *local_err = NULL;
-
-    spapr_irq_xics.init(spapr, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    spapr_irq_xive.init(spapr, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-}
-
 static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
                                 Error **errp)
 {
@@ -516,7 +450,6 @@ SpaprIrq spapr_irq_dual = {
     .xics        = true,
     .xive        = true,
 
-    .init        = spapr_irq_init_dual,
     .claim       = spapr_irq_claim_dual,
     .free        = spapr_irq_free_dual,
     .print_info  = spapr_irq_print_info_dual,
@@ -612,7 +545,67 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
     }
 
-    spapr->irq->init(spapr, errp);
+    if (spapr->irq->xics) {
+        Error *local_err = NULL;
+        Object *obj;
+
+        obj = object_new(TYPE_ICS_SPAPR);
+        object_property_add_child(OBJECT(spapr), "ics", obj, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+
+        object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
+                                       &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+
+        object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
+                                &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+
+        object_property_set_bool(obj, true, "realized", &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+
+        spapr->ics = ICS_SPAPR(obj);
+    }
+
+    if (spapr->irq->xive) {
+        uint32_t nr_servers = spapr_max_server_number(spapr);
+        DeviceState *dev;
+        int i;
+
+        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
+        qdev_prop_set_uint32(dev, "nr-irqs",
+                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
+        /*
+         * 8 XIVE END structures per CPU. One for each available
+         * priority
+         */
+        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
+        qdev_init_nofail(dev);
+
+        spapr->xive = SPAPR_XIVE(dev);
+
+        /* Enable the CPU IPIs */
+        for (i = 0; i < nr_servers; ++i) {
+            if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
+                                     false, errp) < 0) {
+                return;
+            }
+        }
+
+        spapr_xive_hcall_init(spapr);
+    }
 
     spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
                                       spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
@@ -759,7 +752,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .xics        = true,
     .xive        = false,
 
-    .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
     .free        = spapr_irq_free_xics,
     .print_info  = spapr_irq_print_info_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index d3f3b85eb9..69a37f608e 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -42,7 +42,6 @@ typedef struct SpaprIrq {
     bool        xics;
     bool        xive;
 
-    void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
     void (*free)(SpaprMachineState *spapr, int irq);
     void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
-- 
2.21.0



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

* [PULL 53/53] ppc/pnv: Remove the XICSFabric Interface from the POWER9 machine
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (51 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 52/53] spapr: Eliminate SpaprIrq::init hook David Gibson
@ 2019-10-04  9:37 ` David Gibson
  2019-10-07 14:40 ` [PULL 00/53] ppc-for-4.2 queue 20191004 Peter Maydell
  53 siblings, 0 replies; 56+ messages in thread
From: David Gibson @ 2019-10-04  9:37 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

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

The POWER8 PowerNV machine needs to implement a XICSFabric interface
as this is the POWER8 interrupt controller model. But the POWER9
machine uselessly inherits of XICSFabric from the common PowerNV
machine definition.

Open code machine definitions to have a better control on the
different interfaces each machine should define.

Fixes: f30c843ced50 ("ppc/pnv: Introduce PowerNV machines with fixed CPU models")
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191003143617.21682-1-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c | 31 ++++++++++++++-----------------
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 77a86c6a23..7cf64b6d25 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1485,23 +1485,21 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
         .parent        = TYPE_PNV9_CHIP,          \
     }
 
-#define DEFINE_PNV_MACHINE_TYPE(cpu, class_initfn)      \
-    {                                                   \
-        .name          = MACHINE_TYPE_NAME(cpu),        \
-        .parent        = TYPE_PNV_MACHINE,              \
-        .instance_size = sizeof(PnvMachineState),       \
-        .instance_init = pnv_machine_instance_init,     \
-        .class_init    = class_initfn,                  \
-        .interfaces = (InterfaceInfo[]) {               \
-            { TYPE_XICS_FABRIC },                       \
-            { TYPE_INTERRUPT_STATS_PROVIDER },          \
-            { },                                        \
-        },                                              \
-    }
-
 static const TypeInfo types[] = {
-    DEFINE_PNV_MACHINE_TYPE("powernv8", pnv_machine_power8_class_init),
-    DEFINE_PNV_MACHINE_TYPE("powernv9", pnv_machine_power9_class_init),
+    {
+        .name          = MACHINE_TYPE_NAME("powernv9"),
+        .parent        = TYPE_PNV_MACHINE,
+        .class_init    = pnv_machine_power9_class_init,
+    },
+    {
+        .name          = MACHINE_TYPE_NAME("powernv8"),
+        .parent        = TYPE_PNV_MACHINE,
+        .class_init    = pnv_machine_power8_class_init,
+        .interfaces = (InterfaceInfo[]) {
+            { TYPE_XICS_FABRIC },
+            { },
+        },
+    },
     {
         .name          = TYPE_PNV_MACHINE,
         .parent        = TYPE_MACHINE,
@@ -1510,7 +1508,6 @@ static const TypeInfo types[] = {
         .instance_init = pnv_machine_instance_init,
         .class_init    = pnv_machine_class_init,
         .interfaces = (InterfaceInfo[]) {
-            { TYPE_XICS_FABRIC },
             { TYPE_INTERRUPT_STATS_PROVIDER },
             { },
         },
-- 
2.21.0



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

* Re: [PULL 00/53] ppc-for-4.2 queue 20191004
  2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
                   ` (52 preceding siblings ...)
  2019-10-04  9:37 ` [PULL 53/53] ppc/pnv: Remove the XICSFabric Interface from the POWER9 machine David Gibson
@ 2019-10-07 14:40 ` Peter Maydell
  53 siblings, 0 replies; 56+ messages in thread
From: Peter Maydell @ 2019-10-07 14:40 UTC (permalink / raw)
  To: David Gibson
  Cc: Laurent Vivier, Alexey Kardashevskiy, QEMU Developers, Greg Kurz,
	qemu-ppc, Cédric Le Goater

On Fri, 4 Oct 2019 at 10:37, David Gibson <david@gibson.dropbear.id.au> wrote:
>
> The following changes since commit 4f59102571fce49af180cfc6d4cdd2b5df7bdb14:
>
>   Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-oct-01-2019' into staging (2019-10-01 16:21:42 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/dgibson/qemu.git tags/ppc-for-4.2-20191004
>
> for you to fetch changes up to 1aba8716c8335e88b8c358002a6e1ac89f7dd258:
>
>   ppc/pnv: Remove the XICSFabric Interface from the POWER9 machine (2019-10-04 19:08:23 +1000)
>
> ----------------------------------------------------------------
> ppc patch queue 2019-10-04
>
> Here's the next batch of ppc and spapr patches.  Includes:
>   * Fist part of a large cleanup to irq infrastructure
>   * Recreate the full FDT at CAS time, instead of making a difficult
>     to follow set of updates.  This will help us move towards
>     eliminating CAS reboots altogether
>   * No longer provide RTAS blob to SLOF - SLOF can include it just as
>     well itself, since guests will generally need to relocate it with
>     a call to instantiate-rtas
>   * A number of DFP fixes and cleanups from Mark Cave-Ayland
>   * Assorted bugfixes
>   * Several new small devices for powernv
>


Applied, thanks.

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

-- PMM


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

* Re: [PULL 30/53] spapr: Render full FDT on ibm,client-architecture-support
  2019-10-04  9:37 ` [PULL 30/53] spapr: Render full FDT on ibm, client-architecture-support David Gibson
@ 2019-12-03 16:11   ` Laurent Vivier
  0 siblings, 0 replies; 56+ messages in thread
From: Laurent Vivier @ 2019-12-03 16:11 UTC (permalink / raw)
  To: David Gibson, peter.maydell; +Cc: aik, qemu-devel, qemu-ppc, groug, clg

On 04/10/2019 11:37, David Gibson wrote:
> From: Alexey Kardashevskiy <aik@ozlabs.ru>
> 
> The ibm,client-architecture-support call is a way for the guest to
> negotiate capabilities with a hypervisor. It is implemented as:
> - the guest calls SLOF via client interface;
> - SLOF calls QEMU (H_CAS hypercall) with an options vector from the guest;
> - QEMU returns a device tree diff (which uses FDT format with
> an additional header before it);
> - SLOF walks through the partial diff tree and updates its internal tree
> with the values from the diff.
> 
> This changes QEMU to simply re-render the entire tree and send it as
> an update. SLOF can handle this already mostly, [1] is needed before this
> can be applied. This stores the resulting tree in the spapr machine to have
> the latest valid FDT copy possible (this should not matter much as
> H_UPDATE_DT happens right after that but nevertheless).
> 
> The benefit is reduced code size as there is no need for another set of
> DT rendering helpers such as spapr_fixup_cpu_dt().
> 
> The downside is that the updates are bigger now (as they include all
> nodes and properties) but the difference on a '-smp 256,threads=1' system
> before/after is 2.35s vs. 2.5s.
> 
> [1] https://patchwork.ozlabs.org/patch/1152915/
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/ppc/spapr.c | 88 ++++++--------------------------------------------
>  1 file changed, 9 insertions(+), 79 deletions(-)

[Resend the comment I sent to another patch by mistake]

This patch breaks pseries boot when we use a pci-bridge (since v4.2.0-rc0):

...
    -device pci-bridge,id=pci_bridge1,bus=pci.0,addr=0x3,chassis_nr=1 \
    -device virtio-scsi-pci,bus=pci_bridge1 \
...

OF stdout device is: /vdevice/vty@71000000
Preparing to boot Linux version 5.4.0-rc3+ (lvivier@localhost) (gcc
version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)) #2 SMP Wed Nov 13
09:08:20 EST 2019
Detected machine type: 0000000000000101
command line: BOOT_IMAGE=/vmlinuz-5.4.0-rc3+ root=/dev/mapper/rhel-root
ro crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap
Max number of cores passed to firmware: 2048 (NR_CPUS = 2048)
Calling ibm,client-architecture-support...

( 300 ) Data Storage Exception [ 1dc5f230 ]


    R0 .. R7           R8 .. R15         R16 .. R23         R24 .. R31
8000000000001000   000000001e477010   0000000000000000   000000001dc17500
000000001e67afe0   0000000020000004   0000000000000000   000000001dc1bf88
000000001dc21800   000000001dc5f248   000000001e477010   0000000000000003
000000001dc61000   000000001e78dc2d   000000001dc1c158   000000000000f001
0000000000000000   a000000000000001   0000000000008000   000000001e67b060
000000001dc5f230   0000000000000000   000000000000f003   ffffffffffffffff
000000001e745860   0000000000000000   0000000000000006   000000001dbf48f8
000000001dc5f248   0000000000000000   000000001e67b050   000000001dc1c350

    CR / XER           LR / CTR          SRR0 / SRR1        DAR / DSISR
        80000808   000000001dbf34d4   000000001dbf4194   0000000020000004
0000000020000000   000000001dbf48f8   8000000000001000           40000000


4a >

Thanks,
Laurent



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

end of thread, other threads:[~2019-12-03 17:11 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-04  9:36 [PULL 00/53] ppc-for-4.2 queue 20191004 David Gibson
2019-10-04  9:36 ` [PULL 01/53] pseries: do not allow memory-less/cpu-less NUMA node David Gibson
2019-10-04  9:36 ` [PULL 02/53] ppc/pnv: fix "bmc" node name in DT David Gibson
2019-10-04  9:36 ` [PULL 03/53] spapr-tpm-proxy: Drop misleading check David Gibson
2019-10-04  9:36 ` [PULL 04/53] hw/ppc/pnv: fix checkpatch.pl coding style warnings David Gibson
2019-10-04  9:36 ` [PULL 05/53] spapr: Report kvm_irqchip_in_kernel() in 'info pic' David Gibson
2019-10-04  9:37 ` [PULL 06/53] hw/ppc/pnv_xscom: retrieve homer/occ base address from PBA BARs David Gibson
2019-10-04  9:37 ` [PULL 07/53] hw/ppc/pnv_occ: add sram device model for occ common area David Gibson
2019-10-04  9:37 ` [PULL 08/53] hw/ppc/pnv_homer: add PowerNV homer device model David Gibson
2019-10-04  9:37 ` [PULL 09/53] spapr/irq: Introduce an ics_irq_free() helper David Gibson
2019-10-04  9:37 ` [PULL 10/53] spapr/irq: Only claim VALID interrupts at the KVM level David Gibson
2019-10-04  9:37 ` [PULL 11/53] ppc: Add support for 'mffscrn','mffscrni' instructions David Gibson
2019-10-04  9:37 ` [PULL 12/53] ppc: Add support for 'mffsce' instruction David Gibson
2019-10-04  9:37 ` [PULL 13/53] ppc: Use FPSCR defines instead of constants David Gibson
2019-10-04  9:37 ` [PULL 14/53] ppc/kvm: Skip writing DPDES back when in run time state David Gibson
2019-10-04  9:37 ` [PULL 15/53] spapr: Simplify handling of pre ISA 3.0 guest workaround handling David Gibson
2019-10-04  9:37 ` [PULL 16/53] spapr: Move handling of special NVLink numa node from reset to init David Gibson
2019-10-04  9:37 ` [PULL 17/53] spapr: Fixes a leak in CAS David Gibson
2019-10-04  9:37 ` [PULL 18/53] spapr: Skip leading zeroes from memory@ DT node names David Gibson
2019-10-04  9:37 ` [PULL 19/53] spapr: Do not put empty properties for -kernel/-initrd/-append David Gibson
2019-10-04  9:37 ` [PULL 20/53] spapr: Stop providing RTAS blob David Gibson
2019-10-04  9:37 ` [PULL 21/53] pseries: Update SLOF firmware image David Gibson
2019-10-04  9:37 ` [PULL 22/53] target/ppc: introduce get_dfp{64, 128}() helper functions David Gibson
2019-10-04  9:37 ` [PULL 23/53] target/ppc: introduce set_dfp{64, " David Gibson
2019-10-04  9:37 ` [PULL 24/53] target/ppc: update {get, set}_dfp{64, 128}() helper functions to read/write DFP numbers correctly David Gibson
2019-10-04  9:37 ` [PULL 25/53] target/ppc: introduce dfp_finalize_decimal{64, 128}() helper functions David Gibson
2019-10-04  9:37 ` [PULL 26/53] target/ppc: change struct PPC_DFP decimal storage from uint64[2] to ppc_vsr_t David Gibson
2019-10-04  9:37 ` [PULL 27/53] target/ppc: use existing VsrD() macro to eliminate HI_IDX and LO_IDX from dfp_helper.c David Gibson
2019-10-04  9:37 ` [PULL 28/53] target/ppc: remove unnecessary if() around calls to set_dfp{64, 128}() in DFP macros David Gibson
2019-10-04  9:37 ` [PULL 29/53] spapr-pci: Stop providing assigned-addresses David Gibson
2019-10-04  9:37 ` [PULL 30/53] spapr: Render full FDT on ibm, client-architecture-support David Gibson
2019-12-03 16:11   ` [PULL 30/53] spapr: Render full FDT on ibm,client-architecture-support Laurent Vivier
2019-10-04  9:37 ` [PULL 31/53] target/ppc: use Vsr macros in BCD helpers David Gibson
2019-10-04  9:37 ` [PULL 32/53] spapr/xive: skip partially initialized vCPUs in presenter David Gibson
2019-10-04  9:37 ` [PULL 33/53] xics: Minor fixes for XICSFabric interface David Gibson
2019-10-04  9:37 ` [PULL 34/53] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
2019-10-04  9:37 ` [PULL 35/53] xics: Rename misleading ics_simple_*() functions David Gibson
2019-10-04  9:37 ` [PULL 36/53] xics: Eliminate reset hook David Gibson
2019-10-04  9:37 ` [PULL 37/53] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
2019-10-04  9:37 ` [PULL 38/53] xics: Create sPAPR specific ICS subtype David Gibson
2019-10-04  9:37 ` [PULL 39/53] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
2019-10-04  9:37 ` [PULL 40/53] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
2019-10-04  9:37 ` [PULL 41/53] spapr: Clarify and fix handling of nr_irqs David Gibson
2019-10-04  9:37 ` [PULL 42/53] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
2019-10-04  9:37 ` [PULL 43/53] spapr: Fix indexing of XICS irqs David Gibson
2019-10-04  9:37 ` [PULL 44/53] spapr: Simplify spapr_qirq() handling David Gibson
2019-10-04  9:37 ` [PULL 45/53] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
2019-10-04  9:37 ` [PULL 46/53] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
2019-10-04  9:37 ` [PULL 47/53] spapr: Handle freeing of multiple irqs in frontend only David Gibson
2019-10-04  9:37 ` [PULL 48/53] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
2019-10-04  9:37 ` [PULL 49/53] xive: Improve irq claim/free path David Gibson
2019-10-04  9:37 ` [PULL 50/53] spapr: Use less cryptic representation of which irq backends are supported David Gibson
2019-10-04  9:37 ` [PULL 51/53] spapr: Add return value to spapr_irq_check() David Gibson
2019-10-04  9:37 ` [PULL 52/53] spapr: Eliminate SpaprIrq::init hook David Gibson
2019-10-04  9:37 ` [PULL 53/53] ppc/pnv: Remove the XICSFabric Interface from the POWER9 machine David Gibson
2019-10-07 14:40 ` [PULL 00/53] ppc-for-4.2 queue 20191004 Peter Maydell

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