All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4
@ 2015-07-07 15:49 Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 01/30] linux-user, ppc: mftbl can be used by user application Alexander Graf
                   ` (30 more replies)
  0 siblings, 31 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel

Hi Peter,

This is my current patch queue for ppc.  Please pull.

Alex


The following changes since commit 1452673888f6d7f0454276d049846c9bec659233:

  Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20150706.0' into staging (2015-07-07 09:22:40 +0100)

are available in the git repository at:


  git://github.com/agraf/qemu.git tags/signed-ppc-for-upstream

for you to fetch changes up to 6319b1dad04e66f450fb3ac6c31d2bf3940068b8:

  sPAPR: Clear stale MSIx table during EEH reset (2015-07-07 17:44:54 +0200)

----------------------------------------------------------------
Patch queue for ppc - 2015-07-07

A few last minute PPC changes for 2.4:

  - spapr: Update SLOF
  - spapr: Fix a few bugs
  - spapr: Preparation for hotplug
  - spapr: Minor code cleanups
  - linux-user: Add mftb handling
  - kvm: Enable hugepage support with memory-backend-file
  - mac99: Remove nonexistent interrupt pin (Mac OS 9 fix)

----------------------------------------------------------------
Alexey Kardashevskiy (1):
      pseries: Update SLOF firmware image to qemu-slof-20150429

Bharata B Rao (7):
      spapr: Consider max_cpus during xics initialization
      spapr: Support ibm, lrdr-capacity device tree property
      cpus: Add a macro to walk CPUs in reverse
      spapr: Reorganize CPU dt generation code
      spapr: Consolidate cpu init code into a routine
      ppc: Update cpu_model in MachineState
      xics_kvm: Don't enable KVM_CAP_IRQ_XICS if already enabled

Cormac O'Brien (1):
      macio: remove nonexistent interrupt on pin 1

David Gibson (6):
      spapr: Merge sPAPREnvironment into sPAPRMachineState
      spapr: Remove obsolete ram_limit field from sPAPRMachineState
      spapr: Remove obsolete entry_point field from sPAPRMachineState
      spapr: Add sPAPRMachineClass
      spapr_vty: lookup should only return valid VTY objects
      spapr-vty: Use TYPE_ definition instead of hardcoding

Gavin Shan (3):
      sPAPR: Don't enable EEH on emulated PCI devices
      sPAPR: Reenable EEH functionality on reboot
      sPAPR: Clear stale MSIx table during EEH reset

Greg Kurz (3):
      spapr: ensure we have at least one XICS server
      spapr_iommu: drop erroneous check in h_put_tce_indirect()
      spapr_iommu: translate sPAPRTCEAccess to IOMMUAccessFlags

Laurent Vivier (1):
      linux-user, ppc: mftbl can be used by user application

Markus Armbruster (1):
      Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)"

Michael Roth (1):
      target-ppc: fix hugepage support when using memory-backend-file

Nikunj A Dadhania (6):
      spapr_pci: encode missing 64-bit memory address space
      spapr_pci: encode class code including Prog IF register
      spapr_pci: set device node unit address as hex
      spapr_pci: enumerate and add PCI device tree
      spapr_pci: populate ibm,loc-code
      spapr_pci: drop redundant args in spapr_[populate, create]_pci_child_dt

 docs/specs/ppc-spapr-hotplug.txt |  18 ++
 hw/char/spapr_vty.c              |  12 +-
 hw/intc/xics.c                   |  20 +-
 hw/intc/xics_kvm.c               |  12 +-
 hw/misc/macio/macio.c            |   2 -
 hw/net/spapr_llan.c              |  12 +-
 hw/nvram/spapr_nvram.c           |   4 +-
 hw/ppc/mac_newworld.c            |  10 +-
 hw/ppc/mac_oldworld.c            |   7 +-
 hw/ppc/ppc440_bamboo.c           |   7 +-
 hw/ppc/prep.c                    |   7 +-
 hw/ppc/spapr.c                   | 450 +++++++++++++++++++++------------------
 hw/ppc/spapr_events.c            |  13 +-
 hw/ppc/spapr_hcall.c             |  39 ++--
 hw/ppc/spapr_iommu.c             |  30 ++-
 hw/ppc/spapr_pci.c               | 325 ++++++++++++++++++++++------
 hw/ppc/spapr_pci_vfio.c          |  65 +++++-
 hw/ppc/spapr_rtas.c              |  54 +++--
 hw/ppc/spapr_rtc.c               |   4 +-
 hw/ppc/spapr_vio.c               |  15 +-
 hw/ppc/virtex_ml507.c            |   7 +-
 include/hw/pci-host/spapr.h      |  10 +-
 include/hw/ppc/spapr.h           |  53 ++++-
 include/hw/ppc/spapr_vio.h       |   4 +-
 include/hw/ppc/xics.h            |   1 +
 include/qom/cpu.h                |   2 +
 linux-user/main.c                |   3 +-
 pc-bios/README                   |   2 +-
 pc-bios/slof.bin                 | Bin 912192 -> 912720 bytes
 roms/SLOF                        |   2 +-
 target-ppc/kvm.c                 |  57 ++++-
 31 files changed, 836 insertions(+), 411 deletions(-)

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

* [Qemu-devel] [PULL 01/30] linux-user, ppc: mftbl can be used by user application
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 02/30] macio: remove nonexistent interrupt on pin 1 Alexander Graf
                   ` (29 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, Laurent Vivier

From: Laurent Vivier <laurent@vivier.eu>

In qemu-linux-user, when calling gethostbyname2(),
it was hanging in .__res_nmkquery.

(gdb) bt
0 in .__res_nmkquery () from /lib64/libresolv.so.2
1 in .__libc_res_nquery () from /lib64/libresolv.so.2
2 in .__libc_res_nsearch () from /lib64/libresolv.so.2
3 in ._nss_dns_gethostbyname3_r () from /lib64/libnss_dns.so.2
4 in ._nss_dns_gethostbyname2_r () from /lib64/libnss_dns.so.2
5 in .gethostbyname2_r () from /lib64/libc.so.6
6 in .gethostbyname2 () from /lib64/libc.so.6

.__res_nmkquery() is:

...
do { RANDOM_BITS (randombits); } while ((randombits & 0xffff) == 0);
...

<.__res_nmkquery+112>:	mftbl   r11
<.__res_nmkquery+116>:	clrlwi  r10,r11,16
<.__res_nmkquery+120>:	cmpwi   cr7,r10,0
<.__res_nmkquery+124>:	beq     cr7,<.__res_nmkquery+112>

but as mftbl (Move From Time Base Lower) is not implemented,
r11 is always 0, so we have an infinite loop.

This patch fills the Time Base register with cpu_get_real_ticks().

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 linux-user/main.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index c855bcc..6c5c2ef 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1424,8 +1424,7 @@ void cpu_loop (CPUSPARCState *env)
 #ifdef TARGET_PPC
 static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env)
 {
-    /* TO FIX */
-    return 0;
+    return cpu_get_real_ticks();
 }
 
 uint64_t cpu_ppc_load_tbl(CPUPPCState *env)
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 02/30] macio: remove nonexistent interrupt on pin 1
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 01/30] linux-user, ppc: mftbl can be used by user application Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 03/30] target-ppc: fix hugepage support when using memory-backend-file Alexander Graf
                   ` (28 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, Cormac O'Brien, qemu-devel

From: Cormac O'Brien <i.am.cormac.obrien@gmail.com>

The current macio implementation declares an interrupt that doesn't appear to
exist in the hardware or any other emulator implementation. OpenBIOS detects
this interrupt and generates an 'interrupts' property in the macio device tree
entry. Mac OS 9 halts boot when it detects this interrupt, so it has been
removed to permit further progress in the boot process.

Signed-off-by: Cormac O'Brien <i.am.cormac.obrien@gmail.com>
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/misc/macio/macio.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index e9037b0..e3c0242 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -132,8 +132,6 @@ static void macio_common_realize(PCIDevice *d, Error **errp)
     SysBusDevice *sysbus_dev;
     Error *err = NULL;
 
-    d->config[0x3d] = 0x01; // interrupt on pin 1
-
     object_property_set_bool(OBJECT(&s->cuda), true, "realized", &err);
     if (err) {
         error_propagate(errp, err);
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 03/30] target-ppc: fix hugepage support when using memory-backend-file
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 01/30] linux-user, ppc: mftbl can be used by user application Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 02/30] macio: remove nonexistent interrupt on pin 1 Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 04/30] spapr: ensure we have at least one XICS server Alexander Graf
                   ` (27 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, Michael Roth

From: Michael Roth <mdroth@linux.vnet.ibm.com>

Current PPC code relies on -mem-path being used in order for
hugepage support to be detected. With the introduction of
MemoryBackendFile we can now handle this via:
  -object memory-file-backend,mem-path=...,id=hugemem0 \
  -numa node,id=mem0,memdev=hugemem0

Management tools like libvirt treat the 2 approaches as
interchangeable in some cases, which can lead to user-visible
regressions even for previously supported guest configurations.

Fix these by also iterating through any configured memory
backends that may be backed by hugepages.

Since the old code assumed hugepages always backed the entirety
of guest memory, play it safe an pick the minimum across the
max pages sizes for all backends, even ones that aren't backed
by hugepages.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/kvm.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 51 insertions(+), 6 deletions(-)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index ddf469f..110436d 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -40,6 +40,7 @@
 #include "trace.h"
 #include "exec/gdbstub.h"
 #include "exec/memattrs.h"
+#include "sysemu/hostmem.h"
 
 //#define DEBUG_KVM
 
@@ -303,16 +304,11 @@ static void kvm_get_smmu_info(PowerPCCPU *cpu, struct kvm_ppc_smmu_info *info)
     kvm_get_fallback_smmu_info(cpu, info);
 }
 
-static long getrampagesize(void)
+static long gethugepagesize(const char *mem_path)
 {
     struct statfs fs;
     int ret;
 
-    if (!mem_path) {
-        /* guest RAM is backed by normal anonymous pages */
-        return getpagesize();
-    }
-
     do {
         ret = statfs(mem_path, &fs);
     } while (ret != 0 && errno == EINTR);
@@ -334,6 +330,55 @@ static long getrampagesize(void)
     return fs.f_bsize;
 }
 
+static int find_max_supported_pagesize(Object *obj, void *opaque)
+{
+    char *mem_path;
+    long *hpsize_min = opaque;
+
+    if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
+        mem_path = object_property_get_str(obj, "mem-path", NULL);
+        if (mem_path) {
+            long hpsize = gethugepagesize(mem_path);
+            if (hpsize < *hpsize_min) {
+                *hpsize_min = hpsize;
+            }
+        } else {
+            *hpsize_min = getpagesize();
+        }
+    }
+
+    return 0;
+}
+
+static long getrampagesize(void)
+{
+    long hpsize = LONG_MAX;
+    Object *memdev_root;
+
+    if (mem_path) {
+        return gethugepagesize(mem_path);
+    }
+
+    /* it's possible we have memory-backend objects with
+     * hugepage-backed RAM. these may get mapped into system
+     * address space via -numa parameters or memory hotplug
+     * hooks. we want to take these into account, but we
+     * also want to make sure these supported hugepage
+     * sizes are applicable across the entire range of memory
+     * we may boot from, so we take the min across all
+     * backends, and assume normal pages in cases where a
+     * backend isn't backed by hugepages.
+     */
+    memdev_root = object_resolve_path("/objects", NULL);
+    if (!memdev_root) {
+        return getpagesize();
+    }
+
+    object_child_foreach(memdev_root, find_max_supported_pagesize, &hpsize);
+
+    return (hpsize == LONG_MAX) ? getpagesize() : hpsize;
+}
+
 static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift)
 {
     if (!(flags & KVM_PPC_PAGE_SIZES_REAL)) {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 04/30] spapr: ensure we have at least one XICS server
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (2 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 03/30] target-ppc: fix hugepage support when using memory-backend-file Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 05/30] pseries: Update SLOF firmware image to qemu-slof-20150429 Alexander Graf
                   ` (26 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Greg Kurz

From: Greg Kurz <gkurz@linux.vnet.ibm.com>

XICS needs to know the upper value for cpu_index as it is used to compute
the number of servers:

    smp_cpus * kvmppc_smt_threads() / smp_threads

When passing -smp cpus=1,threads=9 on a POWER8 host, we end up with:

    1 * 8 / 9 = 0

... which leads to an assertion in both emulated:

Number of servers needs to be greater 0
Aborted (core dumped)

... and in-kernel XICS:

xics_kvm_realize: Assertion `icp->nr_servers' failed.
Aborted (core dumped)

With this patch, we are sure that nr_servers > 0. Passing the same bogus
-smp option then leads to:

qemu-system-ppc64: Cannot support more than 8 threads on PPC with KVM

... which is a lot more explicit than the XICS errors.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f174e5a..10ca866 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1467,7 +1467,8 @@ static void ppc_spapr_init(MachineState *machine)
 
     /* Set up Interrupt Controller before we create the VCPUs */
     spapr->icp = xics_system_init(machine,
-                                  smp_cpus * kvmppc_smt_threads() / smp_threads,
+                                  DIV_ROUND_UP(smp_cpus * kvmppc_smt_threads(),
+                                               smp_threads),
                                   XICS_IRQS);
 
     /* init CPUs */
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 05/30] pseries: Update SLOF firmware image to qemu-slof-20150429
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (3 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 04/30] spapr: ensure we have at least one XICS server Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 06/30] spapr: Merge sPAPREnvironment into sPAPRMachineState Alexander Graf
                   ` (25 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: Alexey Kardashevskiy, peter.maydell, qemu-devel

From: Alexey Kardashevskiy <aik@ozlabs.ru>

The changelog is:
  > version: update to 20150429
  > pci: Use QEMU created PCI device nodes
  > usb: support 64-bit pci bars
  > pci: Support 64-bit address translation
  > pci: program correct bridge limit registers during probe
  > scsi: handle report-luns failure
  > Fix "key?" Forth word when using USB keyboards
  > Remove bulk.fs package
  > Include make.rules in the library Makefiles

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 pc-bios/README   |   2 +-
 pc-bios/slof.bin | Bin 912192 -> 912720 bytes
 roms/SLOF        |   2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pc-bios/README b/pc-bios/README
index 63e7254..05cf042 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-20150313.
+  built from git tag qemu-slof-20150429.
 
 - 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 ab72cba80c528aea2545974e9c717cee583c254c..0398ac67bc8d07410fe2ccc9d62c376ef3cf87c3 100644
GIT binary patch
delta 88316
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
T!XFI1a^w*!hWz_a+Yb1DL}#t0

delta 88582
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
Me)x!w=Y0PE0V;bn!2kdN

diff --git a/roms/SLOF b/roms/SLOF
index c89b0df..7d766a3 160000
--- a/roms/SLOF
+++ b/roms/SLOF
@@ -1 +1 @@
-Subproject commit c89b0df661c0a6bfa9ff0ed4a371f631f5ee38b0
+Subproject commit 7d766a3ac9b2474f6c7da0084d43590cbbf047bf
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 06/30] spapr: Merge sPAPREnvironment into sPAPRMachineState
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (4 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 05/30] pseries: Update SLOF firmware image to qemu-slof-20150429 Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 07/30] spapr: Remove obsolete ram_limit field from sPAPRMachineState Alexander Graf
                   ` (24 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, David Gibson

From: David Gibson <david@gibson.dropbear.id.au>

The code for -machine pseries maintains a global sPAPREnvironment structure
which keeps track of general state information about the guest platform.
This predates the existence of the MachineState structure, but performs
basically the same function.

Now that we have the generic MachineState, fold sPAPREnvironment into
sPAPRMachineState, the pseries specific subclass of MachineState.

This is mostly a matter of search and replace, although a few places which
relied on the global spapr variable are changed to find the structure via
qdev_get_machine().

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/char/spapr_vty.c         |  6 ++--
 hw/intc/xics.c              | 20 ++++++-------
 hw/intc/xics_kvm.c          |  2 +-
 hw/net/spapr_llan.c         | 12 ++++----
 hw/nvram/spapr_nvram.c      |  4 +--
 hw/ppc/spapr.c              | 73 +++++++++++++++++++--------------------------
 hw/ppc/spapr_events.c       | 13 +++++---
 hw/ppc/spapr_hcall.c        | 36 +++++++++++-----------
 hw/ppc/spapr_iommu.c        |  8 ++---
 hw/ppc/spapr_pci.c          | 37 ++++++++++++-----------
 hw/ppc/spapr_rtas.c         | 38 +++++++++++------------
 hw/ppc/spapr_rtc.c          |  4 +--
 hw/ppc/spapr_vio.c          | 15 +++++-----
 include/hw/pci-host/spapr.h | 10 ++++---
 include/hw/ppc/spapr.h      | 33 ++++++++++++++------
 include/hw/ppc/spapr_vio.h  |  4 ++-
 16 files changed, 167 insertions(+), 148 deletions(-)

diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 4e464bd..1d53035 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -74,7 +74,7 @@ static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp)
 }
 
 /* Forward declaration */
-static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                     target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
@@ -101,7 +101,7 @@ static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_get_term_char(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_get_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                     target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
@@ -214,7 +214,7 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
     return selected;
 }
 
-VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
+VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg)
 {
     VIOsPAPRDevice *sdev;
 
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 0fd2a84..924b1ae 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -806,7 +806,7 @@ void xics_free(XICSState *icp, int irq, int num)
  * Guest interfaces
  */
 
-static target_ulong h_cppr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
@@ -816,7 +816,7 @@ static target_ulong h_cppr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_ipi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                           target_ulong opcode, target_ulong *args)
 {
     target_ulong server = get_cpu_index_by_dt_id(args[0]);
@@ -830,7 +830,7 @@ static target_ulong h_ipi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_xirr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
@@ -840,7 +840,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                              target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
@@ -852,7 +852,7 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_eoi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                           target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
@@ -862,7 +862,7 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                             target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
@@ -874,7 +874,7 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                           uint32_t token,
                           uint32_t nargs, target_ulong args,
                           uint32_t nret, target_ulong rets)
@@ -902,7 +902,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void rtas_get_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                           uint32_t token,
                           uint32_t nargs, target_ulong args,
                           uint32_t nret, target_ulong rets)
@@ -927,7 +927,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
 }
 
-static void rtas_int_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                          uint32_t token,
                          uint32_t nargs, target_ulong args,
                          uint32_t nret, target_ulong rets)
@@ -953,7 +953,7 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void rtas_int_on(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                         uint32_t token,
                         uint32_t nargs, target_ulong args,
                         uint32_t nret, target_ulong rets)
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index c15453f..ea886da 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -368,7 +368,7 @@ static void xics_kvm_set_nr_servers(XICSState *icp, uint32_t nr_servers,
     }
 }
 
-static void rtas_dummy(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                        uint32_t token,
                        uint32_t nargs, target_ulong args,
                        uint32_t nret, target_ulong rets)
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 2dd5ec1..1ca5e9c 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -284,7 +284,7 @@ static int check_bd(VIOsPAPRVLANDevice *dev, vlan_bd_t bd,
 }
 
 static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
-                                           sPAPREnvironment *spapr,
+                                           sPAPRMachineState *spapr,
                                            target_ulong opcode,
                                            target_ulong *args)
 {
@@ -349,7 +349,8 @@ static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
 }
 
 
-static target_ulong h_free_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_free_logical_lan(PowerPCCPU *cpu,
+                                       sPAPRMachineState *spapr,
                                        target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
@@ -371,7 +372,7 @@ static target_ulong h_free_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 }
 
 static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
-                                             sPAPREnvironment *spapr,
+                                             sPAPRMachineState *spapr,
                                              target_ulong opcode,
                                              target_ulong *args)
 {
@@ -421,7 +422,8 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
     return H_SUCCESS;
 }
 
-static target_ulong h_send_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
+                                       sPAPRMachineState *spapr,
                                        target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
@@ -490,7 +492,7 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                      target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c
index 11332d1..fcaa77d 100644
--- a/hw/nvram/spapr_nvram.c
+++ b/hw/nvram/spapr_nvram.c
@@ -45,7 +45,7 @@ typedef struct sPAPRNVRAM {
 #define DEFAULT_NVRAM_SIZE 65536
 #define MAX_NVRAM_SIZE 1048576
 
-static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                              uint32_t token, uint32_t nargs,
                              target_ulong args,
                              uint32_t nret, target_ulong rets)
@@ -86,7 +86,7 @@ static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     rtas_st(rets, 1, len);
 }
 
-static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_nvram_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                              uint32_t token, uint32_t nargs,
                              target_ulong args,
                              uint32_t nret, target_ulong rets)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 10ca866..f820534 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -90,25 +90,6 @@
 
 #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
 
-typedef struct sPAPRMachineState sPAPRMachineState;
-
-#define TYPE_SPAPR_MACHINE      "spapr-machine"
-#define SPAPR_MACHINE(obj) \
-    OBJECT_CHECK(sPAPRMachineState, (obj), TYPE_SPAPR_MACHINE)
-
-/**
- * sPAPRMachineState:
- */
-struct sPAPRMachineState {
-    /*< private >*/
-    MachineState parent_obj;
-
-    /*< public >*/
-    char *kvm_type;
-};
-
-sPAPREnvironment *spapr;
-
 static XICSState *try_create_xics(const char *type, int nr_servers,
                                   int nr_irqs, Error **errp)
 {
@@ -184,7 +165,7 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
     return ret;
 }
 
-static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
+static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
 {
     int ret = 0, offset, cpus_offset;
     CPUState *cs;
@@ -604,7 +585,8 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
     return fdt;
 }
 
-int spapr_h_cas_compose_response(target_ulong addr, target_ulong size)
+int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
+                                 target_ulong addr, target_ulong size)
 {
     void *fdt, *fdt_skel;
     sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 };
@@ -665,7 +647,7 @@ static void spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start,
                       sizeof(associativity))));
 }
 
-static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
+static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt)
 {
     hwaddr mem_start, node_size;
     int i, nb_nodes = nb_numa_nodes;
@@ -714,7 +696,7 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
     return 0;
 }
 
-static void spapr_finalize_fdt(sPAPREnvironment *spapr,
+static void spapr_finalize_fdt(sPAPRMachineState *spapr,
                                hwaddr fdt_addr,
                                hwaddr rtas_addr,
                                hwaddr rtas_size)
@@ -830,7 +812,7 @@ static void emulate_spapr_hypercall(PowerPCCPU *cpu)
 #define CLEAN_HPTE(_hpte)  ((*(uint64_t *)(_hpte)) &= tswap64(~HPTE64_V_HPTE_DIRTY))
 #define DIRTY_HPTE(_hpte)  ((*(uint64_t *)(_hpte)) |= tswap64(HPTE64_V_HPTE_DIRTY))
 
-static void spapr_reset_htab(sPAPREnvironment *spapr)
+static void spapr_reset_htab(sPAPRMachineState *spapr)
 {
     long shift;
     int index;
@@ -892,7 +874,7 @@ static int find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque)
  * A guest reset will cause spapr->htab_fd to become stale if being used.
  * Reopen the file descriptor to make sure the whole HTAB is properly read.
  */
-static int spapr_check_htab_fd(sPAPREnvironment *spapr)
+static int spapr_check_htab_fd(sPAPRMachineState *spapr)
 {
     int rc = 0;
 
@@ -912,6 +894,7 @@ static int spapr_check_htab_fd(sPAPREnvironment *spapr)
 
 static void ppc_spapr_reset(void)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     PowerPCCPU *first_ppc_cpu;
     uint32_t rtas_limit;
 
@@ -951,6 +934,7 @@ static void ppc_spapr_reset(void)
 
 static void spapr_cpu_reset(void *opaque)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     PowerPCCPU *cpu = opaque;
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
@@ -979,12 +963,12 @@ static void spapr_cpu_reset(void *opaque)
      * We have 8 hpte per group, and each hpte is 16 bytes.
      * ie have 128 bytes per hpte entry.
      */
-    env->htab_mask = (1ULL << ((spapr)->htab_shift - 7)) - 1;
+    env->htab_mask = (1ULL << (spapr->htab_shift - 7)) - 1;
     env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab |
         (spapr->htab_shift - 18);
 }
 
-static void spapr_create_nvram(sPAPREnvironment *spapr)
+static void spapr_create_nvram(sPAPRMachineState *spapr)
 {
     DeviceState *dev = qdev_create(&spapr->vio_bus->bus, "spapr-nvram");
     DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
@@ -998,7 +982,7 @@ static void spapr_create_nvram(sPAPREnvironment *spapr)
     spapr->nvram = (struct sPAPRNVRAM *)dev;
 }
 
-static void spapr_rtc_create(sPAPREnvironment *spapr)
+static void spapr_rtc_create(sPAPRMachineState *spapr)
 {
     DeviceState *dev = qdev_create(NULL, TYPE_SPAPR_RTC);
 
@@ -1028,7 +1012,7 @@ static int spapr_vga_init(PCIBus *pci_bus)
 
 static int spapr_post_load(void *opaque, int version_id)
 {
-    sPAPREnvironment *spapr = (sPAPREnvironment *)opaque;
+    sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
     int err = 0;
 
     /* In earlier versions, there was no separate qdev for the PAPR
@@ -1057,16 +1041,16 @@ static const VMStateDescription vmstate_spapr = {
         VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4),
 
         /* RTC offset */
-        VMSTATE_UINT64_TEST(rtc_offset, sPAPREnvironment, version_before_3),
+        VMSTATE_UINT64_TEST(rtc_offset, sPAPRMachineState, version_before_3),
 
-        VMSTATE_PPC_TIMEBASE_V(tb, sPAPREnvironment, 2),
+        VMSTATE_PPC_TIMEBASE_V(tb, sPAPRMachineState, 2),
         VMSTATE_END_OF_LIST()
     },
 };
 
 static int htab_save_setup(QEMUFile *f, void *opaque)
 {
-    sPAPREnvironment *spapr = opaque;
+    sPAPRMachineState *spapr = opaque;
 
     /* "Iteration" header */
     qemu_put_be32(f, spapr->htab_shift);
@@ -1090,7 +1074,7 @@ static int htab_save_setup(QEMUFile *f, void *opaque)
     return 0;
 }
 
-static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr,
+static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr,
                                  int64_t max_ns)
 {
     int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64;
@@ -1140,7 +1124,7 @@ static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr,
     spapr->htab_save_index = index;
 }
 
-static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr,
+static int htab_save_later_pass(QEMUFile *f, sPAPRMachineState *spapr,
                                 int64_t max_ns)
 {
     bool final = max_ns < 0;
@@ -1222,7 +1206,7 @@ static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr,
 
 static int htab_save_iterate(QEMUFile *f, void *opaque)
 {
-    sPAPREnvironment *spapr = opaque;
+    sPAPRMachineState *spapr = opaque;
     int rc = 0;
 
     /* Iteration header */
@@ -1257,7 +1241,7 @@ static int htab_save_iterate(QEMUFile *f, void *opaque)
 
 static int htab_save_complete(QEMUFile *f, void *opaque)
 {
-    sPAPREnvironment *spapr = opaque;
+    sPAPRMachineState *spapr = opaque;
 
     /* Iteration header */
     qemu_put_be32(f, 0);
@@ -1292,7 +1276,7 @@ static int htab_save_complete(QEMUFile *f, void *opaque)
 
 static int htab_load(QEMUFile *f, void *opaque, int version_id)
 {
-    sPAPREnvironment *spapr = opaque;
+    sPAPRMachineState *spapr = opaque;
     uint32_t section_hdr;
     int fd = -1;
 
@@ -1389,6 +1373,7 @@ static void spapr_boot_set(void *opaque, const char *boot_device,
 /* pSeries LPAR / sPAPR hardware init */
 static void ppc_spapr_init(MachineState *machine)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
     ram_addr_t ram_size = machine->ram_size;
     const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
@@ -1412,7 +1397,6 @@ static void ppc_spapr_init(MachineState *machine)
 
     msi_supported = true;
 
-    spapr = g_malloc0(sizeof(*spapr));
     QLIST_INIT(&spapr->phbs);
 
     cpu_ppc_hypercall = emulate_spapr_hypercall;
@@ -1661,6 +1645,9 @@ static void ppc_spapr_init(MachineState *machine)
 
     spapr->entry_point = 0x100;
 
+    /* FIXME: Should register things through the MachineState's qdev
+     * interface, this is a legacy from the sPAPREnvironment structure
+     * which predated MachineState but had a similar function */
     vmstate_register(NULL, 0, &vmstate_spapr, spapr);
     register_savevm_live(NULL, "spapr/htab", -1, 1,
                          &savevm_htab_handlers, spapr);
@@ -1756,17 +1743,17 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
 
 static char *spapr_get_kvm_type(Object *obj, Error **errp)
 {
-    sPAPRMachineState *sm = SPAPR_MACHINE(obj);
+    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
 
-    return g_strdup(sm->kvm_type);
+    return g_strdup(spapr->kvm_type);
 }
 
 static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp)
 {
-    sPAPRMachineState *sm = SPAPR_MACHINE(obj);
+    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
 
-    g_free(sm->kvm_type);
-    sm->kvm_type = g_strdup(value);
+    g_free(spapr->kvm_type);
+    spapr->kvm_type = g_strdup(value);
 }
 
 static void spapr_machine_initfn(Object *obj)
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index fda9e35..f626eb7 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -238,6 +238,7 @@ void spapr_events_fdt_skel(void *fdt, uint32_t check_exception_irq)
 
 static void rtas_event_log_queue(int log_type, void *data, bool exception)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     sPAPREventLogEntry *entry = g_new(sPAPREventLogEntry, 1);
 
     g_assert(data);
@@ -250,6 +251,7 @@ static void rtas_event_log_queue(int log_type, void *data, bool exception)
 static sPAPREventLogEntry *rtas_event_log_dequeue(uint32_t event_mask,
                                                   bool exception)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     sPAPREventLogEntry *entry = NULL;
 
     /* we only queue EPOW events atm. */
@@ -278,6 +280,7 @@ static sPAPREventLogEntry *rtas_event_log_dequeue(uint32_t event_mask,
 
 static bool rtas_event_log_contains(uint32_t event_mask, bool exception)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     sPAPREventLogEntry *entry = NULL;
 
     /* we only queue EPOW events atm. */
@@ -314,6 +317,7 @@ static void spapr_init_v6hdr(struct rtas_event_log_v6 *v6hdr)
 static void spapr_init_maina(struct rtas_event_log_v6_maina *maina,
                              int section_count)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     struct tm tm;
     int year;
 
@@ -336,7 +340,7 @@ static void spapr_init_maina(struct rtas_event_log_v6_maina *maina,
 
 static void spapr_powerdown_req(Notifier *n, void *opaque)
 {
-    sPAPREnvironment *spapr = container_of(n, sPAPREnvironment, epow_notifier);
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     struct rtas_error_log *hdr;
     struct rtas_event_log_v6 *v6hdr;
     struct rtas_event_log_v6_maina *maina;
@@ -384,6 +388,7 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
 
 static void spapr_hotplug_req_event(sPAPRDRConnector *drc, uint8_t hp_action)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     struct hp_log_full *new_hp;
     struct rtas_error_log *hdr;
     struct rtas_event_log_v6 *v6hdr;
@@ -453,7 +458,7 @@ void spapr_hotplug_req_remove_event(sPAPRDRConnector *drc)
     spapr_hotplug_req_event(drc, RTAS_LOG_V6_HP_ACTION_REMOVE);
 }
 
-static void check_exception(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                             uint32_t token, uint32_t nargs,
                             target_ulong args,
                             uint32_t nret, target_ulong rets)
@@ -508,7 +513,7 @@ out_no_events:
     rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
 }
 
-static void event_scan(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void event_scan(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                        uint32_t token, uint32_t nargs,
                        target_ulong args,
                        uint32_t nret, target_ulong rets)
@@ -548,7 +553,7 @@ out_no_events:
     rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
 }
 
-void spapr_events_init(sPAPREnvironment *spapr)
+void spapr_events_init(sPAPRMachineState *spapr)
 {
     QTAILQ_INIT(&spapr->pending_events);
     spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false);
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 4f76f1c..1a20884 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -84,7 +84,7 @@ static inline bool valid_pte_index(CPUPPCState *env, target_ulong pte_index)
     return true;
 }
 
-static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                             target_ulong opcode, target_ulong *args)
 {
     CPUPPCState *env = &cpu->env;
@@ -205,7 +205,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
     return REMOVE_SUCCESS;
 }
 
-static target_ulong h_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                              target_ulong opcode, target_ulong *args)
 {
     CPUPPCState *env = &cpu->env;
@@ -252,7 +252,7 @@ static target_ulong h_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 
 #define H_BULK_REMOVE_MAX_BATCH        4
 
-static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                   target_ulong opcode, target_ulong *args)
 {
     CPUPPCState *env = &cpu->env;
@@ -299,7 +299,7 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                               target_ulong opcode, target_ulong *args)
 {
     CPUPPCState *env = &cpu->env;
@@ -337,7 +337,7 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_read(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_read(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
     CPUPPCState *env = &cpu->env;
@@ -367,7 +367,7 @@ static target_ulong h_read(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                target_ulong opcode, target_ulong *args)
 {
     /* FIXME: actually implement this */
@@ -506,7 +506,7 @@ static target_ulong deregister_dtl(CPUPPCState *env, target_ulong addr)
     return H_SUCCESS;
 }
 
-static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                    target_ulong opcode, target_ulong *args)
 {
     target_ulong flags = args[0];
@@ -551,7 +551,7 @@ static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return ret;
 }
 
-static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_cede(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
     CPUPPCState *env = &cpu->env;
@@ -567,7 +567,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_rtas(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_rtas(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
     target_ulong rtas_r3 = args[0];
@@ -579,7 +579,7 @@ static target_ulong h_rtas(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                            nret, rtas_r3 + 12 + 4*nargs);
 }
 
-static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                    target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
@@ -603,7 +603,7 @@ static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_PARAMETER;
 }
 
-static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                     target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
@@ -629,7 +629,7 @@ static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_PARAMETER;
 }
 
-static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                     target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
@@ -698,14 +698,14 @@ static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static target_ulong h_logical_icbi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_logical_icbi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                    target_ulong opcode, target_ulong *args)
 {
     /* Nothing to do on emulation, KVM will trap this in the kernel */
     return H_SUCCESS;
 }
 
-static target_ulong h_logical_dcbf(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_logical_dcbf(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                    target_ulong opcode, target_ulong *args)
 {
     /* Nothing to do on emulation, KVM will trap this in the kernel */
@@ -788,7 +788,7 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu,
     return H_SUCCESS;
 }
 
-static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                target_ulong opcode, target_ulong *args)
 {
     target_ulong resource = args[1];
@@ -828,7 +828,7 @@ static void do_set_compat(void *arg)
     ((cpuver) == CPU_POWERPC_LOGICAL_2_07) ? 2070 : 0)
 
 static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
-                                                  sPAPREnvironment *spapr,
+                                                  sPAPRMachineState *spapr,
                                                   target_ulong opcode,
                                                   target_ulong *args)
 {
@@ -921,7 +921,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
         return H_SUCCESS;
     }
 
-    if (spapr_h_cas_compose_response(args[1], args[2])) {
+    if (spapr_h_cas_compose_response(spapr, args[1], args[2])) {
         qemu_system_reset_request();
     }
 
@@ -952,6 +952,8 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
 target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
                              target_ulong *args)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+
     if ((opcode <= MAX_HCALL_OPCODE)
         && ((opcode & 0x3) == 0)) {
         spapr_hcall_fn fn = papr_hypercall_table[opcode / 4];
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 8cd9dba..d58d9ba 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -240,7 +240,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
 }
 
 static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
-                                       sPAPREnvironment *spapr,
+                                       sPAPRMachineState *spapr,
                                        target_ulong opcode, target_ulong *args)
 {
     int i;
@@ -287,7 +287,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
     return ret;
 }
 
-static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                               target_ulong opcode, target_ulong *args)
 {
     int i;
@@ -326,7 +326,7 @@ static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return ret;
 }
 
-static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                               target_ulong opcode, target_ulong *args)
 {
     target_ulong liobn = args[0];
@@ -367,7 +367,7 @@ static target_ulong get_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
     return H_SUCCESS;
 }
 
-static target_ulong h_get_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_get_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                               target_ulong opcode, target_ulong *args)
 {
     target_ulong liobn = args[0];
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index d4a6150..eab4cfb 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -58,7 +58,7 @@
         }                                                          \
     } while (0)
 
-sPAPRPHBState *spapr_pci_find_phb(sPAPREnvironment *spapr, uint64_t buid)
+sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid)
 {
     sPAPRPHBState *sphb;
 
@@ -72,7 +72,7 @@ sPAPRPHBState *spapr_pci_find_phb(sPAPREnvironment *spapr, uint64_t buid)
     return NULL;
 }
 
-PCIDevice *spapr_pci_find_dev(sPAPREnvironment *spapr, uint64_t buid,
+PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid,
                               uint32_t config_addr)
 {
     sPAPRPHBState *sphb = spapr_pci_find_phb(spapr, buid);
@@ -93,7 +93,7 @@ static uint32_t rtas_pci_cfgaddr(uint32_t arg)
     return ((arg >> 20) & 0xf00) | (arg & 0xff);
 }
 
-static void finish_read_pci_config(sPAPREnvironment *spapr, uint64_t buid,
+static void finish_read_pci_config(sPAPRMachineState *spapr, uint64_t buid,
                                    uint32_t addr, uint32_t size,
                                    target_ulong rets)
 {
@@ -123,7 +123,7 @@ static void finish_read_pci_config(sPAPREnvironment *spapr, uint64_t buid,
     rtas_st(rets, 1, val);
 }
 
-static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                      uint32_t token, uint32_t nargs,
                                      target_ulong args,
                                      uint32_t nret, target_ulong rets)
@@ -143,7 +143,7 @@ static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     finish_read_pci_config(spapr, buid, addr, size, rets);
 }
 
-static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                  uint32_t token, uint32_t nargs,
                                  target_ulong args,
                                  uint32_t nret, target_ulong rets)
@@ -161,7 +161,7 @@ static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     finish_read_pci_config(spapr, 0, addr, size, rets);
 }
 
-static void finish_write_pci_config(sPAPREnvironment *spapr, uint64_t buid,
+static void finish_write_pci_config(sPAPRMachineState *spapr, uint64_t buid,
                                     uint32_t addr, uint32_t size,
                                     uint32_t val, target_ulong rets)
 {
@@ -189,7 +189,7 @@ static void finish_write_pci_config(sPAPREnvironment *spapr, uint64_t buid,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                       uint32_t token, uint32_t nargs,
                                       target_ulong args,
                                       uint32_t nret, target_ulong rets)
@@ -210,7 +210,7 @@ static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     finish_write_pci_config(spapr, buid, addr, size, val, rets);
 }
 
-static void rtas_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                   uint32_t token, uint32_t nargs,
                                   target_ulong args,
                                   uint32_t nret, target_ulong rets)
@@ -259,7 +259,7 @@ static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr, bool msix,
     }
 }
 
-static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                 uint32_t token, uint32_t nargs,
                                 target_ulong args, uint32_t nret,
                                 target_ulong rets)
@@ -377,7 +377,7 @@ out:
 }
 
 static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
-                                                   sPAPREnvironment *spapr,
+                                                   sPAPRMachineState *spapr,
                                                    uint32_t token,
                                                    uint32_t nargs,
                                                    target_ulong args,
@@ -418,7 +418,7 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
 }
 
 static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
-                                    sPAPREnvironment *spapr,
+                                    sPAPRMachineState *spapr,
                                     uint32_t token, uint32_t nargs,
                                     target_ulong args, uint32_t nret,
                                     target_ulong rets)
@@ -456,7 +456,7 @@ param_error_exit:
 }
 
 static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
-                                           sPAPREnvironment *spapr,
+                                           sPAPRMachineState *spapr,
                                            uint32_t token, uint32_t nargs,
                                            target_ulong args, uint32_t nret,
                                            target_ulong rets)
@@ -512,7 +512,7 @@ param_error_exit:
 }
 
 static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu,
-                                            sPAPREnvironment *spapr,
+                                            sPAPRMachineState *spapr,
                                             uint32_t token, uint32_t nargs,
                                             target_ulong args, uint32_t nret,
                                             target_ulong rets)
@@ -556,7 +556,7 @@ param_error_exit:
 }
 
 static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu,
-                                    sPAPREnvironment *spapr,
+                                    sPAPRMachineState *spapr,
                                     uint32_t token, uint32_t nargs,
                                     target_ulong args, uint32_t nret,
                                     target_ulong rets)
@@ -592,7 +592,7 @@ param_error_exit:
 }
 
 static void rtas_ibm_configure_pe(PowerPCCPU *cpu,
-                                  sPAPREnvironment *spapr,
+                                  sPAPRMachineState *spapr,
                                   uint32_t token, uint32_t nargs,
                                   target_ulong args, uint32_t nret,
                                   target_ulong rets)
@@ -627,7 +627,7 @@ param_error_exit:
 
 /* To support it later */
 static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu,
-                                       sPAPREnvironment *spapr,
+                                       sPAPRMachineState *spapr,
                                        uint32_t token, uint32_t nargs,
                                        target_ulong args, uint32_t nret,
                                        target_ulong rets)
@@ -718,6 +718,7 @@ static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
 static void spapr_msi_write(void *opaque, hwaddr addr,
                             uint64_t data, unsigned size)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     uint32_t irq = data;
 
     trace_spapr_pci_msi_write(addr, data, irq);
@@ -1110,6 +1111,7 @@ static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler,
 
 static void spapr_phb_realize(DeviceState *dev, Error **errp)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     SysBusDevice *s = SYS_BUS_DEVICE(dev);
     sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
     PCIHostState *phb = PCI_HOST_BRIDGE(s);
@@ -1464,7 +1466,7 @@ static const TypeInfo spapr_phb_info = {
     }
 };
 
-PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index)
+PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index)
 {
     DeviceState *dev;
 
@@ -1631,6 +1633,7 @@ static int spapr_switch_one_vga(DeviceState *dev, void *opaque)
 
 void spapr_pci_switch_vga(bool big_endian)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     sPAPRPHBState *sphb;
 
     /*
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index fa28d43..3b95dfc 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -47,7 +47,7 @@
     do { } while (0)
 #endif
 
-static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPREnvironment *spapr,
+static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPRMachineState *spapr,
                                                     uint32_t drc_index)
 {
     sPAPRConfigureConnectorState *ccs = NULL;
@@ -61,14 +61,14 @@ static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPREnvironment *spapr,
     return ccs;
 }
 
-static void spapr_ccs_add(sPAPREnvironment *spapr,
+static void spapr_ccs_add(sPAPRMachineState *spapr,
                           sPAPRConfigureConnectorState *ccs)
 {
     g_assert(!spapr_ccs_find(spapr, ccs->drc_index));
     QTAILQ_INSERT_HEAD(&spapr->ccs_list, ccs, next);
 }
 
-static void spapr_ccs_remove(sPAPREnvironment *spapr,
+static void spapr_ccs_remove(sPAPRMachineState *spapr,
                              sPAPRConfigureConnectorState *ccs)
 {
     QTAILQ_REMOVE(&spapr->ccs_list, ccs, next);
@@ -77,7 +77,7 @@ static void spapr_ccs_remove(sPAPREnvironment *spapr,
 
 void spapr_ccs_reset_hook(void *opaque)
 {
-    sPAPREnvironment *spapr = opaque;
+    sPAPRMachineState *spapr = opaque;
     sPAPRConfigureConnectorState *ccs, *ccs_tmp;
 
     QTAILQ_FOREACH_SAFE(ccs, &spapr->ccs_list, next, ccs_tmp) {
@@ -85,7 +85,7 @@ void spapr_ccs_reset_hook(void *opaque)
     }
 }
 
-static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_display_character(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                    uint32_t token, uint32_t nargs,
                                    target_ulong args,
                                    uint32_t nret, target_ulong rets)
@@ -101,7 +101,7 @@ static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     }
 }
 
-static void rtas_power_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_power_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            uint32_t token, uint32_t nargs, target_ulong args,
                            uint32_t nret, target_ulong rets)
 {
@@ -113,7 +113,7 @@ static void rtas_power_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void rtas_system_reboot(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_system_reboot(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                uint32_t token, uint32_t nargs,
                                target_ulong args,
                                uint32_t nret, target_ulong rets)
@@ -127,7 +127,7 @@ static void rtas_system_reboot(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 }
 
 static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
-                                         sPAPREnvironment *spapr,
+                                         sPAPRMachineState *spapr,
                                          uint32_t token, uint32_t nargs,
                                          target_ulong args,
                                          uint32_t nret, target_ulong rets)
@@ -157,7 +157,7 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
     rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
 }
 
-static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr,
+static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
                            uint32_t token, uint32_t nargs,
                            target_ulong args,
                            uint32_t nret, target_ulong rets)
@@ -204,7 +204,7 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr,
     rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
 }
 
-static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            uint32_t token, uint32_t nargs,
                            target_ulong args,
                            uint32_t nret, target_ulong rets)
@@ -227,7 +227,7 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 }
 
 static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
-                                          sPAPREnvironment *spapr,
+                                          sPAPRMachineState *spapr,
                                           uint32_t token, uint32_t nargs,
                                           target_ulong args,
                                           uint32_t nret, target_ulong rets)
@@ -262,7 +262,7 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
 }
 
 static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
-                                          sPAPREnvironment *spapr,
+                                          sPAPRMachineState *spapr,
                                           uint32_t token, uint32_t nargs,
                                           target_ulong args,
                                           uint32_t nret, target_ulong rets)
@@ -282,7 +282,7 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
 }
 
 static void rtas_ibm_os_term(PowerPCCPU *cpu,
-                            sPAPREnvironment *spapr,
+                            sPAPRMachineState *spapr,
                             uint32_t token, uint32_t nargs,
                             target_ulong args,
                             uint32_t nret, target_ulong rets)
@@ -294,7 +294,7 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu,
     rtas_st(rets, 0, ret);
 }
 
-static void rtas_set_power_level(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_set_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                  uint32_t token, uint32_t nargs,
                                  target_ulong args, uint32_t nret,
                                  target_ulong rets)
@@ -319,7 +319,7 @@ static void rtas_set_power_level(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     rtas_st(rets, 1, 100);
 }
 
-static void rtas_get_power_level(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_get_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                   uint32_t token, uint32_t nargs,
                                   target_ulong args, uint32_t nret,
                                   target_ulong rets)
@@ -356,7 +356,7 @@ static bool sensor_type_is_dr(uint32_t sensor_type)
     return false;
 }
 
-static void rtas_set_indicator(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                uint32_t token, uint32_t nargs,
                                target_ulong args, uint32_t nret,
                                target_ulong rets)
@@ -427,7 +427,7 @@ out_unimplemented:
     rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
 }
 
-static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                   uint32_t token, uint32_t nargs,
                                   target_ulong args, uint32_t nret,
                                   target_ulong rets)
@@ -481,7 +481,7 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 #define CC_WA_LEN 4096
 
 static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
-                                         sPAPREnvironment *spapr,
+                                         sPAPRMachineState *spapr,
                                          uint32_t token, uint32_t nargs,
                                          target_ulong args, uint32_t nret,
                                          target_ulong rets)
@@ -601,7 +601,7 @@ static struct rtas_call {
     spapr_rtas_fn fn;
 } rtas_table[RTAS_TOKEN_MAX - RTAS_TOKEN_BASE];
 
-target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                              uint32_t token, uint32_t nargs, target_ulong args,
                              uint32_t nret, target_ulong rets)
 {
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
index 9da3746..d20b8f2 100644
--- a/hw/ppc/spapr_rtc.c
+++ b/hw/ppc/spapr_rtc.c
@@ -76,7 +76,7 @@ int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset)
     return 0;
 }
 
-static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                  uint32_t token, uint32_t nargs,
                                  target_ulong args,
                                  uint32_t nret, target_ulong rets)
@@ -106,7 +106,7 @@ static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     rtas_st(rets, 7, ns);
 }
 
-static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                  uint32_t token, uint32_t nargs,
                                  target_ulong args,
                                  uint32_t nret, target_ulong rets)
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 8b59b64..c51eb8e 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -160,7 +160,7 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
 /*
  * CRQ handling
  */
-static target_ulong h_reg_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_reg_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                               target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
@@ -218,7 +218,7 @@ static target_ulong free_crq(VIOsPAPRDevice *dev)
     return H_SUCCESS;
 }
 
-static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
@@ -232,7 +232,7 @@ static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return free_crq(dev);
 }
 
-static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
@@ -255,7 +255,7 @@ static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_HARDWARE;
 }
 
-static target_ulong h_enable_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_enable_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                  target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
@@ -333,7 +333,7 @@ void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass)
     dev->tcet->bypass = bypass;
 }
 
-static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                 uint32_t token,
                                 uint32_t nargs, target_ulong args,
                                 uint32_t nret, target_ulong rets)
@@ -364,7 +364,7 @@ static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void rtas_quiesce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static void rtas_quiesce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                          uint32_t token,
                          uint32_t nargs, target_ulong args,
                          uint32_t nret, target_ulong rets)
@@ -426,6 +426,7 @@ static void spapr_vio_busdev_reset(DeviceState *qdev)
 
 static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
     VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
     char *id;
@@ -491,7 +492,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
     pc->realize(dev, errp);
 }
 
-static target_ulong h_vio_signal(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+static target_ulong h_vio_signal(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                  target_ulong opcode,
                                  target_ulong *args)
 {
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 9dca388..5322b56 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -119,21 +119,23 @@ struct sPAPRPHBVFIOState {
 
 static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+
     return xics_get_qirq(spapr->icp, phb->lsi_table[pin].irq);
 }
 
-PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index);
+PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index);
 
 int spapr_populate_pci_dt(sPAPRPHBState *phb,
                           uint32_t xics_phandle,
                           void *fdt);
 
-void spapr_pci_msi_init(sPAPREnvironment *spapr, hwaddr addr);
+void spapr_pci_msi_init(sPAPRMachineState *spapr, hwaddr addr);
 
 void spapr_pci_rtas_init(void);
 
-sPAPRPHBState *spapr_pci_find_phb(sPAPREnvironment *spapr, uint64_t buid);
-PCIDevice *spapr_pci_find_dev(sPAPREnvironment *spapr, uint64_t buid,
+sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid);
+PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid,
                               uint32_t config_addr);
 
 #endif /* __HW_SPAPR_PCI_H__ */
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 7b4b1bb..c3652aa 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -2,6 +2,7 @@
 #define __HW_SPAPR_H__
 
 #include "sysemu/dma.h"
+#include "hw/boards.h"
 #include "hw/ppc/xics.h"
 #include "hw/ppc/spapr_drc.h"
 
@@ -13,7 +14,19 @@ typedef struct sPAPREventLogEntry sPAPREventLogEntry;
 
 #define HPTE64_V_HPTE_DIRTY     0x0000000000000040ULL
 
-typedef struct sPAPREnvironment {
+typedef struct sPAPRMachineState sPAPRMachineState;
+
+#define TYPE_SPAPR_MACHINE      "spapr-machine"
+#define SPAPR_MACHINE(obj) \
+    OBJECT_CHECK(sPAPRMachineState, (obj), TYPE_SPAPR_MACHINE)
+
+/**
+ * sPAPRMachineState:
+ */
+struct sPAPRMachineState {
+    /*< private >*/
+    MachineState parent_obj;
+
     struct VIOsPAPRBus *vio_bus;
     QLIST_HEAD(, sPAPRPHBState) phbs;
     struct sPAPRNVRAM *nvram;
@@ -46,7 +59,10 @@ typedef struct sPAPREnvironment {
 
     /* RTAS state */
     QTAILQ_HEAD(, sPAPRConfigureConnectorState) ccs_list;
-} sPAPREnvironment;
+
+    /*< public >*/
+    char *kvm_type;
+};
 
 #define H_SUCCESS         0
 #define H_BUSY            1        /* Hardware busy -- retry later */
@@ -319,8 +335,6 @@ typedef struct sPAPREnvironment {
 #define KVMPPC_H_CAS            (KVMPPC_HCALL_BASE + 0x2)
 #define KVMPPC_HCALL_MAX        KVMPPC_H_CAS
 
-extern sPAPREnvironment *spapr;
-
 typedef struct sPAPRDeviceTreeUpdateHeader {
     uint32_t version_id;
 } sPAPRDeviceTreeUpdateHeader;
@@ -335,7 +349,7 @@ typedef struct sPAPRDeviceTreeUpdateHeader {
     do { } while (0)
 #endif
 
-typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm,
                                        target_ulong opcode,
                                        target_ulong *args);
 
@@ -490,12 +504,12 @@ static inline void rtas_st_buffer(target_ulong phys, target_ulong phys_len,
     rtas_st_buffer_direct(phys + 2, phys_len - 2, buffer, buffer_len);
 }
 
-typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm,
                               uint32_t token,
                               uint32_t nargs, target_ulong args,
                               uint32_t nret, target_ulong rets);
 void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn);
-target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *sm,
                              uint32_t token, uint32_t nargs, target_ulong args,
                              uint32_t nret, target_ulong rets);
 int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
@@ -546,9 +560,10 @@ struct sPAPREventLogEntry {
     QTAILQ_ENTRY(sPAPREventLogEntry) next;
 };
 
-void spapr_events_init(sPAPREnvironment *spapr);
+void spapr_events_init(sPAPRMachineState *sm);
 void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
-int spapr_h_cas_compose_response(target_ulong addr, target_ulong size);
+int spapr_h_cas_compose_response(sPAPRMachineState *sm,
+                                 target_ulong addr, target_ulong size);
 sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn,
                                    uint64_t bus_offset,
                                    uint32_t page_shift,
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index f95016a..2299a54 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -88,6 +88,8 @@ extern int spapr_vio_signal(VIOsPAPRDevice *dev, target_ulong mode);
 
 static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+
     return xics_get_qirq(spapr->icp, dev->irq);
 }
 
@@ -126,7 +128,7 @@ static inline int spapr_vio_dma_set(VIOsPAPRDevice *dev, uint64_t taddr,
 
 int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq);
 
-VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg);
+VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg);
 void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len);
 void spapr_vty_create(VIOsPAPRBus *bus, CharDriverState *chardev);
 void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd);
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 07/30] spapr: Remove obsolete ram_limit field from sPAPRMachineState
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (5 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 06/30] spapr: Merge sPAPREnvironment into sPAPRMachineState Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 08/30] spapr: Remove obsolete entry_point " Alexander Graf
                   ` (23 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, David Gibson

From: David Gibson <david@gibson.dropbear.id.au>

The ram_limit field was imported from sPAPREnvironment where it predates
the machine's ram size being available generically from machine->ram_size.

Worse, the existing code was inconsistent about where it got the ram size
from.  Sometimes it used spapr->ram_limit, sometimes the global 'ram_size'
and sometimes a local 'ram_size' masking the global.

This cleans up the code to consistently use machine->ram_size, eliminating
spapr->ram_limit in the process.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c         | 22 ++++++++++++----------
 hw/ppc/spapr_hcall.c   |  3 ++-
 include/hw/ppc/spapr.h |  1 -
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f820534..6adfb68 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -265,15 +265,18 @@ static size_t create_page_sizes_prop(CPUPPCState *env, uint32_t *prop,
 
 static hwaddr spapr_node0_size(void)
 {
+    MachineState *machine = MACHINE(qdev_get_machine());
+
     if (nb_numa_nodes) {
         int i;
         for (i = 0; i < nb_numa_nodes; ++i) {
             if (numa_info[i].node_mem) {
-                return MIN(pow2floor(numa_info[i].node_mem), ram_size);
+                return MIN(pow2floor(numa_info[i].node_mem),
+                           machine->ram_size);
             }
         }
     }
-    return ram_size;
+    return machine->ram_size;
 }
 
 #define _FDT(exp) \
@@ -649,6 +652,7 @@ static void spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start,
 
 static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt)
 {
+    MachineState *machine = MACHINE(spapr);
     hwaddr mem_start, node_size;
     int i, nb_nodes = nb_numa_nodes;
     NodeInfo *nodes = numa_info;
@@ -657,7 +661,7 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt)
     /* No NUMA nodes, assume there is just one node with whole RAM */
     if (!nb_numa_nodes) {
         nb_nodes = 1;
-        ramnode.node_mem = ram_size;
+        ramnode.node_mem = machine->ram_size;
         nodes = &ramnode;
     }
 
@@ -665,12 +669,12 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt)
         if (!nodes[i].node_mem) {
             continue;
         }
-        if (mem_start >= ram_size) {
+        if (mem_start >= machine->ram_size) {
             node_size = 0;
         } else {
             node_size = nodes[i].node_mem;
-            if (node_size > ram_size - mem_start) {
-                node_size = ram_size - mem_start;
+            if (node_size > machine->ram_size - mem_start) {
+                node_size = machine->ram_size - mem_start;
             }
         }
         if (!mem_start) {
@@ -1374,7 +1378,6 @@ static void spapr_boot_set(void *opaque, const char *boot_device,
 static void ppc_spapr_init(MachineState *machine)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
-    ram_addr_t ram_size = machine->ram_size;
     const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
@@ -1443,7 +1446,7 @@ static void ppc_spapr_init(MachineState *machine)
      * more than needed for the Linux guests we support. */
     spapr->htab_shift = 18; /* Minimum architected size */
     while (spapr->htab_shift <= 46) {
-        if ((1ULL << (spapr->htab_shift + 7)) >= ram_size) {
+        if ((1ULL << (spapr->htab_shift + 7)) >= machine->ram_size) {
             break;
         }
         spapr->htab_shift++;
@@ -1497,9 +1500,8 @@ static void ppc_spapr_init(MachineState *machine)
     }
 
     /* allocate RAM */
-    spapr->ram_limit = ram_size;
     memory_region_allocate_system_memory(ram, NULL, "ppc_spapr.ram",
-                                         spapr->ram_limit);
+                                         machine->ram_size);
     memory_region_add_subregion(sysmem, 0, ram);
 
     if (rma_alloc_size && rma) {
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 1a20884..652ddf6 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -87,6 +87,7 @@ static inline bool valid_pte_index(CPUPPCState *env, target_ulong pte_index)
 static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                             target_ulong opcode, target_ulong *args)
 {
+    MachineState *machine = MACHINE(spapr);
     CPUPPCState *env = &cpu->env;
     target_ulong flags = args[0];
     target_ulong pte_index = args[1];
@@ -118,7 +119,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 
     raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << page_shift) - 1);
 
-    if (raddr < spapr->ram_limit) {
+    if (raddr < machine->ram_size) {
         /* Regular RAM - should have WIMG=0010 */
         if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) {
             return H_PARAMETER;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index c3652aa..9e7cf0f 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -33,7 +33,6 @@ struct sPAPRMachineState {
     XICSState *icp;
     DeviceState *rtc;
 
-    hwaddr ram_limit;
     void *htab;
     uint32_t htab_shift;
     hwaddr rma_size;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 08/30] spapr: Remove obsolete entry_point field from sPAPRMachineState
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (6 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 07/30] spapr: Remove obsolete ram_limit field from sPAPRMachineState Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 09/30] spapr: Add sPAPRMachineClass Alexander Graf
                   ` (22 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, David Gibson

From: David Gibson <david@gibson.dropbear.id.au>

The sPAPRMachineState structure includes an entry_point field containing
the initial PC value for starting the machine, even though this always has
the value 0x100.

I think this is a hangover from very early versions which bypassed the
firmware when using -kernel.  In any case it has no function now, so remove
it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c         | 4 +---
 include/hw/ppc/spapr.h | 2 +-
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 6adfb68..3aeb2ea 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -932,7 +932,7 @@ static void ppc_spapr_reset(void)
     first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
     first_ppc_cpu->env.gpr[5] = 0;
     first_cpu->halted = 0;
-    first_ppc_cpu->env.nip = spapr->entry_point;
+    first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
 
 }
 
@@ -1645,8 +1645,6 @@ static void ppc_spapr_init(MachineState *machine)
     }
     g_free(filename);
 
-    spapr->entry_point = 0x100;
-
     /* FIXME: Should register things through the MachineState's qdev
      * interface, this is a legacy from the sPAPREnvironment structure
      * which predated MachineState but had a similar function */
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 9e7cf0f..785b094 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -13,6 +13,7 @@ typedef struct sPAPRConfigureConnectorState sPAPRConfigureConnectorState;
 typedef struct sPAPREventLogEntry sPAPREventLogEntry;
 
 #define HPTE64_V_HPTE_DIRTY     0x0000000000000040ULL
+#define SPAPR_ENTRY_POINT       0x100
 
 typedef struct sPAPRMachineState sPAPRMachineState;
 
@@ -41,7 +42,6 @@ struct sPAPRMachineState {
     ssize_t rtas_size;
     void *rtas_blob;
     void *fdt_skel;
-    target_ulong entry_point;
     uint64_t rtc_offset; /* Now used only during incoming migration */
     struct PPCTimebase tb;
     bool has_graphics;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 09/30] spapr: Add sPAPRMachineClass
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (7 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 08/30] spapr: Remove obsolete entry_point " Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 10/30] spapr_pci: encode missing 64-bit memory address space Alexander Graf
                   ` (21 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Michael Roth, peter.maydell, Bharata B Rao, qemu-devel, David Gibson

From: David Gibson <david@gibson.dropbear.id.au>

Currently although we have an sPAPRMachineState descended from MachineState
we don't have an sPAPRMAchineClass descended from MachineClass.  So far it
hasn't been needed, but several upcoming features are going to want it,
so this patch creates a stub implementation.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c         |  1 +
 include/hw/ppc/spapr.h | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3aeb2ea..0dba32f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1808,6 +1808,7 @@ static const TypeInfo spapr_machine_info = {
     .abstract      = true,
     .instance_size = sizeof(sPAPRMachineState),
     .instance_init = spapr_machine_initfn,
+    .class_size    = sizeof(sPAPRMachineClass),
     .class_init    = spapr_machine_class_init,
     .interfaces = (InterfaceInfo[]) {
         { TYPE_FW_PATH_PROVIDER },
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 785b094..0aeac50 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -15,11 +15,26 @@ typedef struct sPAPREventLogEntry sPAPREventLogEntry;
 #define HPTE64_V_HPTE_DIRTY     0x0000000000000040ULL
 #define SPAPR_ENTRY_POINT       0x100
 
+typedef struct sPAPRMachineClass sPAPRMachineClass;
 typedef struct sPAPRMachineState sPAPRMachineState;
 
 #define TYPE_SPAPR_MACHINE      "spapr-machine"
 #define SPAPR_MACHINE(obj) \
     OBJECT_CHECK(sPAPRMachineState, (obj), TYPE_SPAPR_MACHINE)
+#define SPAPR_MACHINE_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(sPAPRMachineClass, obj, TYPE_SPAPR_MACHINE)
+#define SPAPR_MACHINE_CLASS(klass) \
+    OBJECT_CLASS_CHECK(sPAPRMachineClass, klass, TYPE_SPAPR_MACHINE)
+
+/**
+ * sPAPRMachineClass:
+ */
+struct sPAPRMachineClass {
+    /*< private >*/
+    MachineClass parent_class;
+
+    /*< public >*/
+};
 
 /**
  * sPAPRMachineState:
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 10/30] spapr_pci: encode missing 64-bit memory address space
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (8 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 09/30] spapr: Add sPAPRMachineClass Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 11/30] spapr_pci: encode class code including Prog IF register Alexander Graf
                   ` (20 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, Nikunj A Dadhania, David Gibson

From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>

The properties reg/assigned-resources need to encode 64-bit memory
address space as part of phys.hi dword.

  00 if configuration space
  01 if IO region,
  10 if 32-bit MEM region
  11 if 64-bit MEM region

Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index eab4cfb..870fe81 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -787,7 +787,13 @@ typedef struct ResourceProps {
  * phys.hi = 0xYYXXXXZZ, where:
  *   0xYY = npt000ss
  *          |||   |
- *          |||   +-- space code: 1 if IO region, 2 if MEM region
+ *          |||   +-- space code
+ *          |||               |
+ *          |||               +  00 if configuration space
+ *          |||               +  01 if IO region,
+ *          |||               +  10 if 32-bit MEM region
+ *          |||               +  11 if 64-bit MEM region
+ *          |||
  *          ||+------ for non-relocatable IO: 1 if aliased
  *          ||        for relocatable IO: 1 if below 64KB
  *          ||        for MEM: 1 if below 1MB
@@ -847,6 +853,8 @@ static void populate_resource_props(PCIDevice *d, ResourceProps *rp)
         reg->phys_hi = cpu_to_be32(dev_id | b_rrrrrrrr(pci_bar(d, i)));
         if (d->io_regions[i].type & PCI_BASE_ADDRESS_SPACE_IO) {
             reg->phys_hi |= cpu_to_be32(b_ss(1));
+        } else if (d->io_regions[i].type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+            reg->phys_hi |= cpu_to_be32(b_ss(3));
         } else {
             reg->phys_hi |= cpu_to_be32(b_ss(2));
         }
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 11/30] spapr_pci: encode class code including Prog IF register
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (9 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 10/30] spapr_pci: encode missing 64-bit memory address space Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 12/30] spapr_pci: set device node unit address as hex Alexander Graf
                   ` (19 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, Nikunj A Dadhania, David Gibson

From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>

Current code missed the Prog IF register. All Class Code, Subclass,
and Prog IF registers are needed to identify the accurate device type.

For example: USB controllers use the PROG IF for denoting: USB
FullSpeed, HighSpeed or SuperSpeed.

Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 870fe81..7660a20 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -900,8 +900,7 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
     _FDT(fdt_setprop_cell(fdt, offset, "revision-id",
                           pci_default_read_config(dev, PCI_REVISION_ID, 1)));
     _FDT(fdt_setprop_cell(fdt, offset, "class-code",
-                          pci_default_read_config(dev, PCI_CLASS_DEVICE, 2)
-                            << 8));
+                          pci_default_read_config(dev, PCI_CLASS_PROG, 3)));
     if (pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)) {
         _FDT(fdt_setprop_cell(fdt, offset, "interrupts",
                  pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)));
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 12/30] spapr_pci: set device node unit address as hex
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (10 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 11/30] spapr_pci: encode class code including Prog IF register Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 13/30] spapr_iommu: drop erroneous check in h_put_tce_indirect() Alexander Graf
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, Nikunj A Dadhania, David Gibson

From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>

Device node names should encode the unit address as hex, while the
code was encodind it as integers.

Also, use FDT_NAME_MAX macro for allocating and composing the name.

Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7660a20..51196b5 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -50,6 +50,8 @@
 #define RTAS_TYPE_MSI           1
 #define RTAS_TYPE_MSIX          2
 
+#define FDT_NAME_MAX          128
+
 #define _FDT(exp) \
     do { \
         int ret = (exp);                                           \
@@ -973,13 +975,13 @@ static void *spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
     int offset, ret, fdt_size;
     int slot = PCI_SLOT(dev->devfn);
     int func = PCI_FUNC(dev->devfn);
-    char nodename[512];
+    char nodename[FDT_NAME_MAX];
 
     fdt = create_device_tree(&fdt_size);
     if (func != 0) {
-        sprintf(nodename, "pci@%d,%d", slot, func);
+        snprintf(nodename, FDT_NAME_MAX, "pci@%x,%x", slot, func);
     } else {
-        sprintf(nodename, "pci@%d", slot);
+        snprintf(nodename, FDT_NAME_MAX, "pci@%x", slot);
     }
     offset = fdt_add_subnode(fdt, 0, nodename);
     ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb->index, drc_index,
@@ -1489,7 +1491,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
                           void *fdt)
 {
     int bus_off, i, j, ret;
-    char nodename[256];
+    char nodename[FDT_NAME_MAX];
     uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
     const uint64_t mmiosize = memory_region_size(&phb->memwindow);
     const uint64_t w32max = (1ULL << 32) - SPAPR_PCI_MEM_WIN_BUS_OFFSET;
@@ -1525,7 +1527,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
     sPAPRTCETable *tcet;
 
     /* Start populating the FDT */
-    sprintf(nodename, "pci@%" PRIx64, phb->buid);
+    snprintf(nodename, FDT_NAME_MAX, "pci@%" PRIx64, phb->buid);
     bus_off = fdt_add_subnode(fdt, 0, nodename);
     if (bus_off < 0) {
         return bus_off;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 13/30] spapr_iommu: drop erroneous check in h_put_tce_indirect()
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (11 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 12/30] spapr_pci: set device node unit address as hex Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 14/30] spapr_iommu: translate sPAPRTCEAccess to IOMMUAccessFlags Alexander Graf
                   ` (17 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Greg Kurz

From: Greg Kurz <gkurz@linux.vnet.ibm.com>

The tce_list variable is not a TCE but the address to a TCE: we shouldn't
clear permission bits as we do now. And this is dead code anyway since we
check tce_list is 4K aligned a few lines above.

This patch doesn't fix any bug, it is only code cleanup.

Suggested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_iommu.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index d58d9ba..3121998 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -267,9 +267,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
     ioba &= page_mask;
 
     for (i = 0; i < npages; ++i, ioba += page_size) {
-        target_ulong off = (tce_list & ~SPAPR_TCE_RW) +
-                                i * sizeof(target_ulong);
-        tce = ldq_be_phys(cs->as, off);
+        tce = ldq_be_phys(cs->as, tce_list + i * sizeof(target_ulong));
 
         ret = put_tce_emu(tcet, ioba, tce);
         if (ret) {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 14/30] spapr_iommu: translate sPAPRTCEAccess to IOMMUAccessFlags
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (12 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 13/30] spapr_iommu: drop erroneous check in h_put_tce_indirect() Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 15/30] Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)" Alexander Graf
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Greg Kurz

From: Greg Kurz <gkurz@linux.vnet.ibm.com>

The fact that these enums have matching values is pure coincidence. We
actually need to translate from the PAPR definition to the QEMU one.

This patch doesn't fix any bug, it is only code cleanup.

Suggested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_iommu.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 3121998..f61504e 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -60,6 +60,20 @@ sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn)
     return NULL;
 }
 
+static IOMMUAccessFlags spapr_tce_iommu_access_flags(uint64_t tce)
+{
+    switch (tce & SPAPR_TCE_RW) {
+    case SPAPR_TCE_FAULT:
+        return IOMMU_NONE;
+    case SPAPR_TCE_RO:
+        return IOMMU_RO;
+    case SPAPR_TCE_WO:
+        return IOMMU_WO;
+    default: /* SPAPR_TCE_RW */
+        return IOMMU_RW;
+    }
+}
+
 /* Called from RCU critical section */
 static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr,
                                                bool is_write)
@@ -82,7 +96,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr,
         ret.iova = addr & page_mask;
         ret.translated_addr = tce & page_mask;
         ret.addr_mask = ~page_mask;
-        ret.perm = tce & IOMMU_RW;
+        ret.perm = spapr_tce_iommu_access_flags(tce);
     }
     trace_spapr_iommu_xlate(tcet->liobn, addr, ret.iova, ret.perm,
                             ret.addr_mask);
@@ -233,7 +247,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
     entry.iova = ioba & page_mask;
     entry.translated_addr = tce & page_mask;
     entry.addr_mask = ~page_mask;
-    entry.perm = tce & IOMMU_RW;
+    entry.perm = spapr_tce_iommu_access_flags(tce);
     memory_region_notify_iommu(&tcet->iommu, entry);
 
     return H_SUCCESS;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 15/30] Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)"
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (13 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 14/30] spapr_iommu: translate sPAPRTCEAccess to IOMMUAccessFlags Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 16/30] spapr: Consider max_cpus during xics initialization Alexander Graf
                   ` (15 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Markus Armbruster

From: Markus Armbruster <armbru@redhat.com>

Since we now require GLib 2.22+ (commit f40685c), we don't have to
work around lack of g_hash_table_iter_init() & friends anymore.

This reverts commit f8833a37c0c6b22ddd57b45e48cfb0f97dbd5af4.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci.c | 28 +++++++++++-----------------
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 51196b5..dc4a683 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1362,34 +1362,28 @@ static const VMStateDescription vmstate_spapr_pci_msi = {
     },
 };
 
-static void spapr_pci_fill_msi_devs(gpointer key, gpointer value,
-                                    gpointer opaque)
-{
-    sPAPRPHBState *sphb = opaque;
-
-    sphb->msi_devs[sphb->msi_devs_num].key = *(uint32_t *)key;
-    sphb->msi_devs[sphb->msi_devs_num].value = *(spapr_pci_msi *)value;
-    sphb->msi_devs_num++;
-}
-
 static void spapr_pci_pre_save(void *opaque)
 {
     sPAPRPHBState *sphb = opaque;
-    int msi_devs_num;
+    GHashTableIter iter;
+    gpointer key, value;
+    int i;
 
     if (sphb->msi_devs) {
         g_free(sphb->msi_devs);
         sphb->msi_devs = NULL;
     }
-    sphb->msi_devs_num = 0;
-    msi_devs_num = g_hash_table_size(sphb->msi);
-    if (!msi_devs_num) {
+    sphb->msi_devs_num = g_hash_table_size(sphb->msi);
+    if (!sphb->msi_devs_num) {
         return;
     }
-    sphb->msi_devs = g_malloc(msi_devs_num * sizeof(spapr_pci_msi_mig));
+    sphb->msi_devs = g_malloc(sphb->msi_devs_num * sizeof(spapr_pci_msi_mig));
 
-    g_hash_table_foreach(sphb->msi, spapr_pci_fill_msi_devs, sphb);
-    assert(sphb->msi_devs_num == msi_devs_num);
+    g_hash_table_iter_init(&iter, sphb->msi);
+    for (i = 0; g_hash_table_iter_next(&iter, &key, &value); ++i) {
+        sphb->msi_devs[i].key = *(uint32_t *) key;
+        sphb->msi_devs[i].value = *(spapr_pci_msi *) value;
+    }
 }
 
 static int spapr_pci_post_load(void *opaque, int version_id)
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 16/30] spapr: Consider max_cpus during xics initialization
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (14 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 15/30] Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)" Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 17/30] spapr: Support ibm, lrdr-capacity device tree property Alexander Graf
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Bharata B Rao

From: Bharata B Rao <bharata@linux.vnet.ibm.com>

Use max_cpus instead of smp_cpus when intializating xics system. Also
report max_cpus in ibm,interrupt-server-ranges device tree property of
interrupt controller node.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 0dba32f..61d04c6 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -308,7 +308,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
     GString *hypertas = g_string_sized_new(256);
     GString *qemu_hypertas = g_string_sized_new(256);
     uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
-    uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
+    uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(max_cpus)};
     int smt = kvmppc_smt_threads();
     unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
     QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
@@ -1454,7 +1454,7 @@ static void ppc_spapr_init(MachineState *machine)
 
     /* Set up Interrupt Controller before we create the VCPUs */
     spapr->icp = xics_system_init(machine,
-                                  DIV_ROUND_UP(smp_cpus * kvmppc_smt_threads(),
+                                  DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(),
                                                smp_threads),
                                   XICS_IRQS);
 
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 17/30] spapr: Support ibm, lrdr-capacity device tree property
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (15 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 16/30] spapr: Consider max_cpus during xics initialization Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 18/30] cpus: Add a macro to walk CPUs in reverse Alexander Graf
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Bharata B Rao

From: Bharata B Rao <bharata@linux.vnet.ibm.com>

Add support for ibm,lrdr-capacity since this is needed by the guest
kernel to know about the possible hot-pluggable CPUs and Memory. With
this, pseries kernels will start reporting correct maxcpus in
/sys/devices/system/cpu/possible.

Also define the minimum hotpluggable memory size as 256MB.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[agraf: Fix compile error on 32bit hosts]
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 docs/specs/ppc-spapr-hotplug.txt | 18 ++++++++++++++++++
 hw/ppc/spapr_rtas.c              | 16 ++++++++++++++++
 include/hw/ppc/spapr.h           |  2 ++
 3 files changed, 36 insertions(+)

diff --git a/docs/specs/ppc-spapr-hotplug.txt b/docs/specs/ppc-spapr-hotplug.txt
index d35771c..46e0719 100644
--- a/docs/specs/ppc-spapr-hotplug.txt
+++ b/docs/specs/ppc-spapr-hotplug.txt
@@ -284,4 +284,22 @@ struct rtas_event_log_v6_hp {
     } drc;
 } QEMU_PACKED;
 
+== ibm,lrdr-capacity ==
+
+ibm,lrdr-capacity is a property in the /rtas device tree node that identifies
+the dynamic reconfiguration capabilities of the guest. It consists of a triple
+consisting of <phys>, <size> and <maxcpus>.
+
+  <phys>, encoded in BE format represents the maximum address in bytes and
+  hence the maximum memory that can be allocated to the guest.
+
+  <size>, encoded in BE format represents the size increments in which
+  memory can be hot-plugged to the guest.
+
+  <maxcpus>, a BE-encoded integer, represents the maximum number of
+  processors that the guest can have.
+
+pseries guests use this property to note the maximum allowed CPUs for the
+guest.
+
 [1] http://thread.gmane.org/gmane.linux.ports.ppc.embedded/75350/focus=106867
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 3b95dfc..2986f94 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -29,6 +29,7 @@
 #include "sysemu/char.h"
 #include "hw/qdev.h"
 #include "sysemu/device_tree.h"
+#include "sysemu/cpus.h"
 
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
@@ -651,6 +652,8 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
 {
     int ret;
     int i;
+    uint32_t lrdr_capacity[5];
+    MachineState *machine = MACHINE(qdev_get_machine());
 
     ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
     if (ret < 0) {
@@ -699,6 +702,19 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
         }
 
     }
+
+    lrdr_capacity[0] = cpu_to_be32(((uint64_t)machine->maxram_size) >> 32);
+    lrdr_capacity[1] = cpu_to_be32(machine->maxram_size & 0xffffffff);
+    lrdr_capacity[2] = 0;
+    lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
+    lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
+    ret = qemu_fdt_setprop(fdt, "/rtas", "ibm,lrdr-capacity", lrdr_capacity,
+                     sizeof(lrdr_capacity));
+    if (ret < 0) {
+        fprintf(stderr, "Couldn't add ibm,lrdr-capacity rtas property\n");
+        return ret;
+    }
+
     return 0;
 }
 
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 0aeac50..91a61ab 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -607,4 +607,6 @@ void spapr_ccs_reset_hook(void *opaque);
 void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns);
 int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset);
 
+#define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */
+
 #endif /* !defined (__HW_SPAPR_H__) */
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 18/30] cpus: Add a macro to walk CPUs in reverse
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (16 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 17/30] spapr: Support ibm, lrdr-capacity device tree property Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 19/30] spapr: Reorganize CPU dt generation code Alexander Graf
                   ` (12 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Bharata B Rao

From: Bharata B Rao <bharata@linux.vnet.ibm.com>

Add CPU_FOREACH_REVERSE that walks CPUs in reverse.

Needed for PowerPC CPU device tree reorganization.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 include/qom/cpu.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 39f0f19..42f42f5 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -323,6 +323,8 @@ extern struct CPUTailQ cpus;
 #define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node)
 #define CPU_FOREACH_SAFE(cpu, next_cpu) \
     QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu)
+#define CPU_FOREACH_REVERSE(cpu) \
+    QTAILQ_FOREACH_REVERSE(cpu, &cpus, CPUTailQ, node)
 #define first_cpu QTAILQ_FIRST(&cpus)
 
 DECLARE_TLS(CPUState *, current_cpu);
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 19/30] spapr: Reorganize CPU dt generation code
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (17 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 18/30] cpus: Add a macro to walk CPUs in reverse Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 20/30] spapr: Consolidate cpu init code into a routine Alexander Graf
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Bharata B Rao

From: Bharata B Rao <bharata@linux.vnet.ibm.com>

Reorganize CPU device tree generation code so that it be reused from
hotplug path. CPU dt entries are now generated from spapr_finalize_fdt()
instead of spapr_create_fdt_skel().

Note: This is how the split-up looks like now:

Boot path
---------
spapr_finalize_fdt
 spapr_populate_cpus_dt_node
  spapr_populate_cpu_dt
   spapr_fixup_cpu_numa_dt
   spapr_fixup_cpu_smt_dt

ibm,cas path
------------
spapr_h_cas_compose_response
 spapr_fixup_cpu_dt
  spapr_fixup_cpu_numa_dt
  spapr_fixup_cpu_smt_dt

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c | 284 ++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 159 insertions(+), 125 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 61d04c6..bcf7ffa 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -165,6 +165,27 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
     return ret;
 }
 
+static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, CPUState *cs)
+{
+    int ret = 0;
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    int index = ppc_get_vcpu_dt_id(cpu);
+    uint32_t associativity[] = {cpu_to_be32(0x5),
+                                cpu_to_be32(0x0),
+                                cpu_to_be32(0x0),
+                                cpu_to_be32(0x0),
+                                cpu_to_be32(cs->numa_node),
+                                cpu_to_be32(index)};
+
+    /* Advertise NUMA via ibm,associativity */
+    if (nb_numa_nodes > 1) {
+        ret = fdt_setprop(fdt, offset, "ibm,associativity", associativity,
+                          sizeof(associativity));
+    }
+
+    return ret;
+}
+
 static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
 {
     int ret = 0, offset, cpus_offset;
@@ -177,12 +198,6 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
         PowerPCCPU *cpu = POWERPC_CPU(cs);
         DeviceClass *dc = DEVICE_GET_CLASS(cs);
         int index = ppc_get_vcpu_dt_id(cpu);
-        uint32_t associativity[] = {cpu_to_be32(0x5),
-                                    cpu_to_be32(0x0),
-                                    cpu_to_be32(0x0),
-                                    cpu_to_be32(0x0),
-                                    cpu_to_be32(cs->numa_node),
-                                    cpu_to_be32(index)};
 
         if ((index % smt) != 0) {
             continue;
@@ -206,20 +221,17 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
             }
         }
 
-        if (nb_numa_nodes > 1) {
-            ret = fdt_setprop(fdt, offset, "ibm,associativity", associativity,
-                              sizeof(associativity));
-            if (ret < 0) {
-                return ret;
-            }
-        }
-
         ret = fdt_setprop(fdt, offset, "ibm,pft-size",
                           pft_size_prop, sizeof(pft_size_prop));
         if (ret < 0) {
             return ret;
         }
 
+        ret = spapr_fixup_cpu_numa_dt(fdt, offset, cs);
+        if (ret < 0) {
+            return ret;
+        }
+
         ret = spapr_fixup_cpu_smt_dt(fdt, offset, cpu,
                                      ppc_get_compat_smt_threads(cpu));
         if (ret < 0) {
@@ -302,18 +314,13 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
                                    uint32_t epow_irq)
 {
     void *fdt;
-    CPUState *cs;
     uint32_t start_prop = cpu_to_be32(initrd_base);
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     GString *hypertas = g_string_sized_new(256);
     GString *qemu_hypertas = g_string_sized_new(256);
     uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
     uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(max_cpus)};
-    int smt = kvmppc_smt_threads();
     unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
-    QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
-    unsigned sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
-    uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
     char *buf;
 
     add_str(hypertas, "hcall-pft");
@@ -399,107 +406,6 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
 
     _FDT((fdt_end_node(fdt)));
 
-    /* cpus */
-    _FDT((fdt_begin_node(fdt, "cpus")));
-
-    _FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
-    _FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
-
-    CPU_FOREACH(cs) {
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
-        CPUPPCState *env = &cpu->env;
-        DeviceClass *dc = DEVICE_GET_CLASS(cs);
-        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
-        int index = ppc_get_vcpu_dt_id(cpu);
-        char *nodename;
-        uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
-                           0xffffffff, 0xffffffff};
-        uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
-        uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
-        uint32_t page_sizes_prop[64];
-        size_t page_sizes_prop_size;
-
-        if ((index % smt) != 0) {
-            continue;
-        }
-
-        nodename = g_strdup_printf("%s@%x", dc->fw_name, index);
-
-        _FDT((fdt_begin_node(fdt, nodename)));
-
-        g_free(nodename);
-
-        _FDT((fdt_property_cell(fdt, "reg", index)));
-        _FDT((fdt_property_string(fdt, "device_type", "cpu")));
-
-        _FDT((fdt_property_cell(fdt, "cpu-version", env->spr[SPR_PVR])));
-        _FDT((fdt_property_cell(fdt, "d-cache-block-size",
-                                env->dcache_line_size)));
-        _FDT((fdt_property_cell(fdt, "d-cache-line-size",
-                                env->dcache_line_size)));
-        _FDT((fdt_property_cell(fdt, "i-cache-block-size",
-                                env->icache_line_size)));
-        _FDT((fdt_property_cell(fdt, "i-cache-line-size",
-                                env->icache_line_size)));
-
-        if (pcc->l1_dcache_size) {
-            _FDT((fdt_property_cell(fdt, "d-cache-size", pcc->l1_dcache_size)));
-        } else {
-            fprintf(stderr, "Warning: Unknown L1 dcache size for cpu\n");
-        }
-        if (pcc->l1_icache_size) {
-            _FDT((fdt_property_cell(fdt, "i-cache-size", pcc->l1_icache_size)));
-        } else {
-            fprintf(stderr, "Warning: Unknown L1 icache size for cpu\n");
-        }
-
-        _FDT((fdt_property_cell(fdt, "timebase-frequency", tbfreq)));
-        _FDT((fdt_property_cell(fdt, "clock-frequency", cpufreq)));
-        _FDT((fdt_property_cell(fdt, "ibm,slb-size", env->slb_nr)));
-        _FDT((fdt_property_string(fdt, "status", "okay")));
-        _FDT((fdt_property(fdt, "64-bit", NULL, 0)));
-
-        if (env->spr_cb[SPR_PURR].oea_read) {
-            _FDT((fdt_property(fdt, "ibm,purr", NULL, 0)));
-        }
-
-        if (env->mmu_model & POWERPC_MMU_1TSEG) {
-            _FDT((fdt_property(fdt, "ibm,processor-segment-sizes",
-                               segs, sizeof(segs))));
-        }
-
-        /* Advertise VMX/VSX (vector extensions) if available
-         *   0 / no property == no vector extensions
-         *   1               == VMX / Altivec available
-         *   2               == VSX available */
-        if (env->insns_flags & PPC_ALTIVEC) {
-            uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
-
-            _FDT((fdt_property_cell(fdt, "ibm,vmx", vmx)));
-        }
-
-        /* Advertise DFP (Decimal Floating Point) if available
-         *   0 / no property == no DFP
-         *   1               == DFP available */
-        if (env->insns_flags2 & PPC2_DFP) {
-            _FDT((fdt_property_cell(fdt, "ibm,dfp", 1)));
-        }
-
-        page_sizes_prop_size = create_page_sizes_prop(env, page_sizes_prop,
-                                                      sizeof(page_sizes_prop));
-        if (page_sizes_prop_size) {
-            _FDT((fdt_property(fdt, "ibm,segment-page-sizes",
-                               page_sizes_prop, page_sizes_prop_size)));
-        }
-
-        _FDT((fdt_property_cell(fdt, "ibm,chip-id",
-                                cs->cpu_index / cpus_per_socket)));
-
-        _FDT((fdt_end_node(fdt)));
-    }
-
-    _FDT((fdt_end_node(fdt)));
-
     /* RTAS */
     _FDT((fdt_begin_node(fdt, "rtas")));
 
@@ -700,6 +606,137 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt)
     return 0;
 }
 
+static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
+                                  sPAPRMachineState *spapr)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
+    int index = ppc_get_vcpu_dt_id(cpu);
+    uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
+                       0xffffffff, 0xffffffff};
+    uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
+    uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
+    uint32_t page_sizes_prop[64];
+    size_t page_sizes_prop_size;
+    QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
+    unsigned sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
+    uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
+    uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
+
+    _FDT((fdt_setprop_cell(fdt, offset, "reg", index)));
+    _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));
+
+    _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR])));
+    _FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size",
+                           env->dcache_line_size)));
+    _FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size",
+                           env->dcache_line_size)));
+    _FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size",
+                           env->icache_line_size)));
+    _FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size",
+                           env->icache_line_size)));
+
+    if (pcc->l1_dcache_size) {
+        _FDT((fdt_setprop_cell(fdt, offset, "d-cache-size",
+                               pcc->l1_dcache_size)));
+    } else {
+        fprintf(stderr, "Warning: Unknown L1 dcache size for cpu\n");
+    }
+    if (pcc->l1_icache_size) {
+        _FDT((fdt_setprop_cell(fdt, offset, "i-cache-size",
+                               pcc->l1_icache_size)));
+    } else {
+        fprintf(stderr, "Warning: Unknown L1 icache size for cpu\n");
+    }
+
+    _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", env->slb_nr)));
+    _FDT((fdt_setprop_string(fdt, offset, "status", "okay")));
+    _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0)));
+
+    if (env->spr_cb[SPR_PURR].oea_read) {
+        _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0)));
+    }
+
+    if (env->mmu_model & POWERPC_MMU_1TSEG) {
+        _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes",
+                          segs, sizeof(segs))));
+    }
+
+    /* Advertise VMX/VSX (vector extensions) if available
+     *   0 / no property == no vector extensions
+     *   1               == VMX / Altivec 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
+     *   0 / no property == no DFP
+     *   1               == DFP available */
+    if (env->insns_flags2 & PPC2_DFP) {
+        _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
+    }
+
+    page_sizes_prop_size = create_page_sizes_prop(env, page_sizes_prop,
+                                                  sizeof(page_sizes_prop));
+    if (page_sizes_prop_size) {
+        _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes",
+                          page_sizes_prop, page_sizes_prop_size)));
+    }
+
+    _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
+                           cs->cpu_index / cpus_per_socket)));
+
+    _FDT((fdt_setprop(fdt, offset, "ibm,pft-size",
+                      pft_size_prop, sizeof(pft_size_prop))));
+
+    _FDT(spapr_fixup_cpu_numa_dt(fdt, offset, cs));
+
+    _FDT(spapr_fixup_cpu_smt_dt(fdt, offset, cpu,
+                                ppc_get_compat_smt_threads(cpu)));
+}
+
+static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr)
+{
+    CPUState *cs;
+    int cpus_offset;
+    char *nodename;
+    int smt = kvmppc_smt_threads();
+
+    cpus_offset = fdt_add_subnode(fdt, 0, "cpus");
+    _FDT(cpus_offset);
+    _FDT((fdt_setprop_cell(fdt, cpus_offset, "#address-cells", 0x1)));
+    _FDT((fdt_setprop_cell(fdt, cpus_offset, "#size-cells", 0x0)));
+
+    /*
+     * We walk the CPUs in reverse order to ensure that CPU DT nodes
+     * created by fdt_add_subnode() end up in the right order in FDT
+     * for the guest kernel the enumerate the CPUs correctly.
+     */
+    CPU_FOREACH_REVERSE(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+        int index = ppc_get_vcpu_dt_id(cpu);
+        DeviceClass *dc = DEVICE_GET_CLASS(cs);
+        int offset;
+
+        if ((index % smt) != 0) {
+            continue;
+        }
+
+        nodename = g_strdup_printf("%s@%x", dc->fw_name, index);
+        offset = fdt_add_subnode(fdt, cpus_offset, nodename);
+        g_free(nodename);
+        _FDT(offset);
+        spapr_populate_cpu_dt(cs, fdt, offset, spapr);
+    }
+
+}
+
 static void spapr_finalize_fdt(sPAPRMachineState *spapr,
                                hwaddr fdt_addr,
                                hwaddr rtas_addr,
@@ -745,11 +782,8 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr,
         fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
     }
 
-    /* Advertise NUMA via ibm,associativity */
-    ret = spapr_fixup_cpu_dt(fdt, spapr);
-    if (ret < 0) {
-        fprintf(stderr, "Couldn't finalize CPU device tree properties\n");
-    }
+    /* cpus */
+    spapr_populate_cpus_dt_node(fdt, spapr);
 
     bootlist = get_boot_devices_list(&cb, true);
     if (cb && bootlist) {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 20/30] spapr: Consolidate cpu init code into a routine
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (18 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 19/30] spapr: Reorganize CPU dt generation code Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 21/30] ppc: Update cpu_model in MachineState Alexander Graf
                   ` (10 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Bharata B Rao

From: Bharata B Rao <bharata@linux.vnet.ibm.com>

Factor out bits of sPAPR specific CPU initialization code into
a separate routine so that it can be called from CPU hotplug
path too.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c | 54 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 29 insertions(+), 25 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index bcf7ffa..fd371c1 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1408,6 +1408,34 @@ static void spapr_boot_set(void *opaque, const char *boot_device,
     machine->boot_order = g_strdup(boot_device);
 }
 
+static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu)
+{
+    CPUPPCState *env = &cpu->env;
+
+    /* Set time-base frequency to 512 MHz */
+    cpu_ppc_tb_init(env, TIMEBASE_FREQ);
+
+    /* PAPR always has exception vectors in RAM not ROM. To ensure this,
+     * MSR[IP] should never be set.
+     */
+    env->msr_mask &= ~(1 << 6);
+
+    /* Tell KVM that we're in PAPR mode */
+    if (kvm_enabled()) {
+        kvmppc_set_papr(cpu);
+    }
+
+    if (cpu->max_compat) {
+        if (ppc_set_compat(cpu, cpu->max_compat) < 0) {
+            exit(1);
+        }
+    }
+
+    xics_cpu_setup(spapr->icp, cpu);
+
+    qemu_register_reset(spapr_cpu_reset, cpu);
+}
+
 /* pSeries LPAR / sPAPR hardware init */
 static void ppc_spapr_init(MachineState *machine)
 {
@@ -1417,7 +1445,6 @@ static void ppc_spapr_init(MachineState *machine)
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
     PowerPCCPU *cpu;
-    CPUPPCState *env;
     PCIHostState *phb;
     int i;
     MemoryRegion *sysmem = get_system_memory();
@@ -1502,30 +1529,7 @@ static void ppc_spapr_init(MachineState *machine)
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
         }
-        env = &cpu->env;
-
-        /* Set time-base frequency to 512 MHz */
-        cpu_ppc_tb_init(env, TIMEBASE_FREQ);
-
-        /* PAPR always has exception vectors in RAM not ROM. To ensure this,
-         * MSR[IP] should never be set.
-         */
-        env->msr_mask &= ~(1 << 6);
-
-        /* Tell KVM that we're in PAPR mode */
-        if (kvm_enabled()) {
-            kvmppc_set_papr(cpu);
-        }
-
-        if (cpu->max_compat) {
-            if (ppc_set_compat(cpu, cpu->max_compat) < 0) {
-                exit(1);
-            }
-        }
-
-        xics_cpu_setup(spapr->icp, cpu);
-
-        qemu_register_reset(spapr_cpu_reset, cpu);
+        spapr_cpu_init(spapr, cpu);
     }
 
     if (kvm_enabled()) {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 21/30] ppc: Update cpu_model in MachineState
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (19 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 20/30] spapr: Consolidate cpu init code into a routine Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 22/30] xics_kvm: Don't enable KVM_CAP_IRQ_XICS if already enabled Alexander Graf
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Bharata B Rao

From: Bharata B Rao <bharata@linux.vnet.ibm.com>

Keep cpu_model field in MachineState uptodate so that it can be used
from the CPU hotplug path.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/mac_newworld.c  | 10 +++++-----
 hw/ppc/mac_oldworld.c  |  7 +++----
 hw/ppc/ppc440_bamboo.c |  7 +++----
 hw/ppc/prep.c          |  7 +++----
 hw/ppc/spapr.c         |  7 +++----
 hw/ppc/virtex_ml507.c  |  7 +++----
 6 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 0f3e341..77d5c81 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -145,7 +145,6 @@ static void ppc_core99_reset(void *opaque)
 static void ppc_core99_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -182,14 +181,15 @@ static void ppc_core99_init(MachineState *machine)
     linux_boot = (kernel_filename != NULL);
 
     /* init CPUs */
-    if (cpu_model == NULL)
+    if (machine->cpu_model == NULL) {
 #ifdef TARGET_PPC64
-        cpu_model = "970fx";
+        machine->cpu_model = "970fx";
 #else
-        cpu_model = "G4";
+        machine->cpu_model = "G4";
 #endif
+    }
     for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(cpu_model);
+        cpu = cpu_ppc_init(machine->cpu_model);
         if (cpu == NULL) {
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 99879dd..06fdbaf 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -75,7 +75,6 @@ static void ppc_heathrow_reset(void *opaque)
 static void ppc_heathrow_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -107,10 +106,10 @@ static void ppc_heathrow_init(MachineState *machine)
     linux_boot = (kernel_filename != NULL);
 
     /* init CPUs */
-    if (cpu_model == NULL)
-        cpu_model = "G3";
+    if (machine->cpu_model == NULL)
+        machine->cpu_model = "G3";
     for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(cpu_model);
+        cpu = cpu_ppc_init(machine->cpu_model);
         if (cpu == NULL) {
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 778970a..032fa80 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -159,7 +159,6 @@ static void main_cpu_reset(void *opaque)
 static void bamboo_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -184,10 +183,10 @@ static void bamboo_init(MachineState *machine)
     int i;
 
     /* Setup CPU. */
-    if (cpu_model == NULL) {
-        cpu_model = "440EP";
+    if (machine->cpu_model == NULL) {
+        machine->cpu_model = "440EP";
     }
-    cpu = cpu_ppc_init(cpu_model);
+    cpu = cpu_ppc_init(machine->cpu_model);
     if (cpu == NULL) {
         fprintf(stderr, "Unable to initialize CPU!\n");
         exit(1);
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 998ee2d..45b5f62 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -506,7 +506,6 @@ static int PPC_NVRAM_set_params (Nvram *nvram, uint16_t NVRAM_size,
 static void ppc_prep_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -536,10 +535,10 @@ static void ppc_prep_init(MachineState *machine)
     linux_boot = (kernel_filename != NULL);
 
     /* init CPUs */
-    if (cpu_model == NULL)
-        cpu_model = "602";
+    if (machine->cpu_model == NULL)
+        machine->cpu_model = "602";
     for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(cpu_model);
+        cpu = cpu_ppc_init(machine->cpu_model);
         if (cpu == NULL) {
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index fd371c1..5ca817c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1440,7 +1440,6 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu)
 static void ppc_spapr_init(MachineState *machine)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -1520,11 +1519,11 @@ static void ppc_spapr_init(MachineState *machine)
                                   XICS_IRQS);
 
     /* init CPUs */
-    if (cpu_model == NULL) {
-        cpu_model = kvm_enabled() ? "host" : "POWER7";
+    if (machine->cpu_model == NULL) {
+        machine->cpu_model = kvm_enabled() ? "host" : "POWER7";
     }
     for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(cpu_model);
+        cpu = cpu_ppc_init(machine->cpu_model);
         if (cpu == NULL) {
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 439732f..de86f7c 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -197,7 +197,6 @@ static int xilinx_load_device_tree(hwaddr addr,
 static void virtex_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     hwaddr initrd_base = 0;
@@ -214,11 +213,11 @@ static void virtex_init(MachineState *machine)
     int i;
 
     /* init CPUs */
-    if (cpu_model == NULL) {
-        cpu_model = "440-Xilinx";
+    if (machine->cpu_model == NULL) {
+        machine->cpu_model = "440-Xilinx";
     }
 
-    cpu = ppc440_init_xilinx(&ram_size, 1, cpu_model, 400000000);
+    cpu = ppc440_init_xilinx(&ram_size, 1, machine->cpu_model, 400000000);
     env = &cpu->env;
     qemu_register_reset(main_cpu_reset, cpu);
 
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 22/30] xics_kvm: Don't enable KVM_CAP_IRQ_XICS if already enabled
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (20 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 21/30] ppc: Update cpu_model in MachineState Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 23/30] spapr_pci: enumerate and add PCI device tree Alexander Graf
                   ` (8 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Bharata B Rao

From: Bharata B Rao <bharata@linux.vnet.ibm.com>

When supporting CPU hot removal by parking the vCPU fd and reusing
it during hotplug again, there can be cases where we try to reenable
KVM_CAP_IRQ_XICS CAP for the vCPU for which it was already enabled.
Introduce a boolean member in ICPState to track this and don't
reenable the CAP if it was already enabled earlier.

Re-enabling this CAP should ideally work, but currently it results in
kernel trying to create and associate ICP with this vCPU and that
fails since there is already an ICP associated with it. Hence this
patch is needed to work around this problem in the kernel.

This change allows CPU hot removal to work for sPAPR.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/intc/xics_kvm.c    | 10 ++++++++++
 include/hw/ppc/xics.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index ea886da..d58729c 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -331,6 +331,15 @@ static void xics_kvm_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
         abort();
     }
 
+    /*
+     * If we are reusing a parked vCPU fd corresponding to the CPU
+     * which was hot-removed earlier we don't have to renable
+     * KVM_CAP_IRQ_XICS capability again.
+     */
+    if (ss->cap_irq_xics_enabled) {
+        return;
+    }
+
     if (icpkvm->kernel_xics_fd != -1) {
         int ret;
 
@@ -343,6 +352,7 @@ static void xics_kvm_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
                     kvm_arch_vcpu_id(cs), strerror(errno));
             exit(1);
         }
+        ss->cap_irq_xics_enabled = true;
     }
 }
 
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index a214dd7..355a966 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -109,6 +109,7 @@ struct ICPState {
     uint8_t pending_priority;
     uint8_t mfrr;
     qemu_irq output;
+    bool cap_irq_xics_enabled;
 };
 
 #define TYPE_ICS "ics"
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 23/30] spapr_pci: enumerate and add PCI device tree
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (21 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 22/30] xics_kvm: Don't enable KVM_CAP_IRQ_XICS if already enabled Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 24/30] spapr_pci: populate ibm,loc-code Alexander Graf
                   ` (7 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc
  Cc: peter.maydell, David Gibson, qemu-devel, Nikunj A Dadhania, Michael Roth

From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>

All the PCI enumeration and device node creation was off-loaded to
SLOF. With PCI hotplug support, code needed to be added to add device
node. This creates multiple copy of the code one in SLOF and other in
hotplug code. To unify this, the patch adds the pci device node
creation in Qemu. For backward compatibility, a flag
"qemu,phb-enumerated" is added to the phb, suggesting to SLOF to not
do device node creation.

Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
[ Squashed Michael's drc_index changes ]
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 133 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index dc4a683..7c3621c 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -23,6 +23,7 @@
  * THE SOFTWARE.
  */
 #include "hw/hw.h"
+#include "hw/sysbus.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
@@ -35,6 +36,7 @@
 #include "qemu/error-report.h"
 #include "qapi/qmp/qerror.h"
 
+#include "hw/pci/pci_bridge.h"
 #include "hw/pci/pci_bus.h"
 #include "hw/ppc/spapr_drc.h"
 #include "sysemu/device_tree.h"
@@ -966,30 +968,32 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
     return 0;
 }
 
+static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
+                                            PCIDevice *pdev);
+
 /* create OF node for pci device and required OF DT properties */
-static void *spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
-                                       int drc_index, const char *drc_name,
-                                       int *dt_offset)
+static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
+                                     int drc_index, const char *drc_name,
+                                     void *fdt, int node_offset)
 {
-    void *fdt;
-    int offset, ret, fdt_size;
+    int offset, ret;
     int slot = PCI_SLOT(dev->devfn);
     int func = PCI_FUNC(dev->devfn);
     char nodename[FDT_NAME_MAX];
 
-    fdt = create_device_tree(&fdt_size);
     if (func != 0) {
         snprintf(nodename, FDT_NAME_MAX, "pci@%x,%x", slot, func);
     } else {
         snprintf(nodename, FDT_NAME_MAX, "pci@%x", slot);
     }
-    offset = fdt_add_subnode(fdt, 0, nodename);
+    offset = fdt_add_subnode(fdt, node_offset, nodename);
     ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb->index, drc_index,
                                       drc_name);
     g_assert(!ret);
-
-    *dt_offset = offset;
-    return fdt;
+    if (ret) {
+        return 0;
+    }
+    return offset;
 }
 
 static void spapr_phb_add_pci_device(sPAPRDRConnector *drc,
@@ -1002,19 +1006,22 @@ static void spapr_phb_add_pci_device(sPAPRDRConnector *drc,
     int drc_index = drck->get_index(drc);
     const char *drc_name = drck->get_name(drc);
     void *fdt = NULL;
-    int fdt_start_offset = 0;
+    int fdt_start_offset = 0, fdt_size;
 
-    /* boot-time devices get their device tree node created by SLOF, but for
-     * hotplugged devices we need QEMU to generate it so the guest can fetch
-     * it via RTAS
-     */
     if (dev->hotplugged) {
-        fdt = spapr_create_pci_child_dt(phb, pdev, drc_index, drc_name,
-                                        &fdt_start_offset);
+        fdt = create_device_tree(&fdt_size);
+        fdt_start_offset = spapr_create_pci_child_dt(phb, pdev,
+                                                     drc_index, drc_name,
+                                                     fdt, 0);
+        if (!fdt_start_offset) {
+            error_setg(errp, "Failed to create pci child device tree node");
+            goto out;
+        }
     }
 
     drck->attach(drc, DEVICE(pdev),
                  fdt, fdt_start_offset, !dev->hotplugged, errp);
+out:
     if (*errp) {
         g_free(fdt);
     }
@@ -1056,6 +1063,20 @@ static sPAPRDRConnector *spapr_phb_get_pci_drc(sPAPRPHBState *phb,
                                     pdev->devfn);
 }
 
+static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
+                                            PCIDevice *pdev)
+{
+    sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
+    sPAPRDRConnectorClass *drck;
+
+    if (!drc) {
+        return 0;
+    }
+
+    drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+    return drck->get_index(drc);
+}
+
 static void spapr_phb_hot_plug_child(HotplugHandler *plug_handler,
                                      DeviceState *plugged_dev, Error **errp)
 {
@@ -1480,6 +1501,87 @@ PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index)
     return PCI_HOST_BRIDGE(dev);
 }
 
+typedef struct sPAPRFDT {
+    void *fdt;
+    int node_off;
+    sPAPRPHBState *sphb;
+} sPAPRFDT;
+
+static void spapr_populate_pci_devices_dt(PCIBus *bus, PCIDevice *pdev,
+                                          void *opaque)
+{
+    PCIBus *sec_bus;
+    sPAPRFDT *p = opaque;
+    int offset;
+    sPAPRFDT s_fdt;
+    uint32_t drc_index = spapr_phb_get_pci_drc_index(p->sphb, pdev);
+
+    offset = spapr_create_pci_child_dt(p->sphb, pdev,
+                                       drc_index, NULL,
+                                       p->fdt, p->node_off);
+    if (!offset) {
+        error_report("Failed to create pci child device tree node");
+        return;
+    }
+
+    if ((pci_default_read_config(pdev, PCI_HEADER_TYPE, 1) !=
+         PCI_HEADER_TYPE_BRIDGE)) {
+        return;
+    }
+
+    sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
+    if (!sec_bus) {
+        return;
+    }
+
+    s_fdt.fdt = p->fdt;
+    s_fdt.node_off = offset;
+    s_fdt.sphb = p->sphb;
+    pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
+                        spapr_populate_pci_devices_dt,
+                        &s_fdt);
+}
+
+static void spapr_phb_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
+                                           void *opaque)
+{
+    unsigned int *bus_no = opaque;
+    unsigned int primary = *bus_no;
+    unsigned int subordinate = 0xff;
+    PCIBus *sec_bus = NULL;
+
+    if ((pci_default_read_config(pdev, PCI_HEADER_TYPE, 1) !=
+         PCI_HEADER_TYPE_BRIDGE)) {
+        return;
+    }
+
+    (*bus_no)++;
+    pci_default_write_config(pdev, PCI_PRIMARY_BUS, primary, 1);
+    pci_default_write_config(pdev, PCI_SECONDARY_BUS, *bus_no, 1);
+    pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, *bus_no, 1);
+
+    sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
+    if (!sec_bus) {
+        return;
+    }
+
+    pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, subordinate, 1);
+    pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
+                        spapr_phb_pci_enumerate_bridge, bus_no);
+    pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, *bus_no, 1);
+}
+
+static void spapr_phb_pci_enumerate(sPAPRPHBState *phb)
+{
+    PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus;
+    unsigned int bus_no = 0;
+
+    pci_for_each_device(bus, pci_bus_num(bus),
+                        spapr_phb_pci_enumerate_bridge,
+                        &bus_no);
+
+}
+
 int spapr_populate_pci_dt(sPAPRPHBState *phb,
                           uint32_t xics_phandle,
                           void *fdt)
@@ -1519,6 +1621,8 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
         cpu_to_be32(b_ddddd(-1)|b_fff(0)), 0x0, 0x0, cpu_to_be32(-1)};
     uint32_t interrupt_map[PCI_SLOT_MAX * PCI_NUM_PINS][7];
     sPAPRTCETable *tcet;
+    PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus;
+    sPAPRFDT s_fdt;
 
     /* Start populating the FDT */
     snprintf(nodename, FDT_NAME_MAX, "pci@%" PRIx64, phb->buid);
@@ -1568,6 +1672,18 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
                  tcet->liobn, tcet->bus_offset,
                  tcet->nb_table << tcet->page_shift);
 
+    /* Walk the bridges and program the bus numbers*/
+    spapr_phb_pci_enumerate(phb);
+    _FDT(fdt_setprop_cell(fdt, bus_off, "qemu,phb-enumerated", 0x1));
+
+    /* Populate tree nodes with PCI devices attached */
+    s_fdt.fdt = fdt;
+    s_fdt.node_off = bus_off;
+    s_fdt.sphb = phb;
+    pci_for_each_device(bus, pci_bus_num(bus),
+                        spapr_populate_pci_devices_dt,
+                        &s_fdt);
+
     ret = spapr_drc_populate_dt(fdt, bus_off, OBJECT(phb),
                                 SPAPR_DR_CONNECTOR_TYPE_PCI);
     if (ret) {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 24/30] spapr_pci: populate ibm,loc-code
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (22 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 23/30] spapr_pci: enumerate and add PCI device tree Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2021-08-09  9:57   ` Peter Maydell
  2015-07-07 15:49 ` [Qemu-devel] [PULL 25/30] spapr_pci: drop redundant args in spapr_[populate, create]_pci_child_dt Alexander Graf
                   ` (6 subsequent siblings)
  30 siblings, 1 reply; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, Nikunj A Dadhania, David Gibson

From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>

Each hardware instance has a platform unique location code.  The OF
device tree that describes a part of a hardware entity must include
the “ibm,loc-code” property with a value that represents the location
code for that hardware entity.

Populate ibm,loc-code.

1) PCI passthru devices need to identify with its own ibm,loc-code
   available on the host. In failure cases use:
   vfio_<name>:<phb-index>:<bus>:<slot>.<fn>

2) Emulated devices encode as following:
   qemu_<name>:<phb-index>:<bus>:<slot>.<fn>

Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 71 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7c3621c..7585983 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -747,6 +747,60 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
     return &phb->iommu_as;
 }
 
+static char *spapr_phb_vfio_get_loc_code(sPAPRPHBState *sphb,  PCIDevice *pdev)
+{
+    char *path = NULL, *buf = NULL, *host = NULL;
+
+    /* Get the PCI VFIO host id */
+    host = object_property_get_str(OBJECT(pdev), "host", NULL);
+    if (!host) {
+        goto err_out;
+    }
+
+    /* Construct the path of the file that will give us the DT location */
+    path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
+    g_free(host);
+    if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) {
+        goto err_out;
+    }
+    g_free(path);
+
+    /* Construct and read from host device tree the loc-code */
+    path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
+    g_free(buf);
+    if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) {
+        goto err_out;
+    }
+    return buf;
+
+err_out:
+    g_free(path);
+    return NULL;
+}
+
+static char *spapr_phb_get_loc_code(sPAPRPHBState *sphb, PCIDevice *pdev)
+{
+    char *buf;
+    const char *devtype = "qemu";
+    uint32_t busnr = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(pdev))));
+
+    if (object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
+        buf = spapr_phb_vfio_get_loc_code(sphb, pdev);
+        if (buf) {
+            return buf;
+        }
+        devtype = "vfio";
+    }
+    /*
+     * For emulated devices and VFIO-failure case, make up
+     * the loc-code.
+     */
+    buf = g_strdup_printf("%s_%s:%04x:%02x:%02x.%x",
+                          devtype, pdev->name, sphb->index, busnr,
+                          PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+    return buf;
+}
+
 /* Macros to operate with address in OF binding to PCI */
 #define b_x(x, p, l)    (((x) & ((1<<(l))-1)) << (p))
 #define b_n(x)          b_x((x), 31, 1) /* 0 if relocatable */
@@ -885,11 +939,12 @@ static void populate_resource_props(PCIDevice *d, ResourceProps *rp)
 
 static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
                                        int phb_index, int drc_index,
-                                       const char *drc_name)
+                                       sPAPRPHBState *sphb)
 {
     ResourceProps rp;
     bool is_bridge = false;
-    int pci_status;
+    int pci_status, err;
+    char *buf = NULL;
 
     if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) ==
         PCI_HEADER_TYPE_BRIDGE) {
@@ -950,7 +1005,18 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
      * processed by OF beforehand
      */
     _FDT(fdt_setprop_string(fdt, offset, "name", "pci"));
-    _FDT(fdt_setprop(fdt, offset, "ibm,loc-code", drc_name, strlen(drc_name)));
+    buf = spapr_phb_get_loc_code(sphb, dev);
+    if (!buf) {
+        error_report("Failed setting the ibm,loc-code");
+        return -1;
+    }
+
+    err = fdt_setprop_string(fdt, offset, "ibm,loc-code", buf);
+    g_free(buf);
+    if (err < 0) {
+        return err;
+    }
+
     _FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index));
 
     _FDT(fdt_setprop_cell(fdt, offset, "#address-cells",
@@ -988,7 +1054,7 @@ static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
     }
     offset = fdt_add_subnode(fdt, node_offset, nodename);
     ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb->index, drc_index,
-                                      drc_name);
+                                      phb);
     g_assert(!ret);
     if (ret) {
         return 0;
@@ -1004,14 +1070,13 @@ static void spapr_phb_add_pci_device(sPAPRDRConnector *drc,
     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
     DeviceState *dev = DEVICE(pdev);
     int drc_index = drck->get_index(drc);
-    const char *drc_name = drck->get_name(drc);
     void *fdt = NULL;
     int fdt_start_offset = 0, fdt_size;
 
     if (dev->hotplugged) {
         fdt = create_device_tree(&fdt_size);
         fdt_start_offset = spapr_create_pci_child_dt(phb, pdev,
-                                                     drc_index, drc_name,
+                                                     drc_index, NULL,
                                                      fdt, 0);
         if (!fdt_start_offset) {
             error_setg(errp, "Failed to create pci child device tree node");
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 25/30] spapr_pci: drop redundant args in spapr_[populate, create]_pci_child_dt
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (23 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 24/30] spapr_pci: populate ibm,loc-code Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 26/30] spapr_vty: lookup should only return valid VTY objects Alexander Graf
                   ` (5 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, Nikunj A Dadhania, David Gibson

From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>

* phb_index is not being used and if required can be obtained from sphb
* use helper to get drc_index in spapr_populate_pci_child_dt()
* Check if drc_index is zero

Suggested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci.c | 27 +++++++++++----------------
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7585983..a139aea 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -937,14 +937,17 @@ static void populate_resource_props(PCIDevice *d, ResourceProps *rp)
     rp->assigned_len = assigned_idx * sizeof(ResourceFields);
 }
 
+static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
+                                            PCIDevice *pdev);
+
 static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
-                                       int phb_index, int drc_index,
                                        sPAPRPHBState *sphb)
 {
     ResourceProps rp;
     bool is_bridge = false;
     int pci_status, err;
     char *buf = NULL;
+    uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev);
 
     if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) ==
         PCI_HEADER_TYPE_BRIDGE) {
@@ -1017,7 +1020,9 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
         return err;
     }
 
-    _FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index));
+    if (drc_index) {
+        _FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index));
+    }
 
     _FDT(fdt_setprop_cell(fdt, offset, "#address-cells",
                           RESOURCE_CELLS_ADDRESS));
@@ -1034,12 +1039,8 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
     return 0;
 }
 
-static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
-                                            PCIDevice *pdev);
-
 /* create OF node for pci device and required OF DT properties */
 static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
-                                     int drc_index, const char *drc_name,
                                      void *fdt, int node_offset)
 {
     int offset, ret;
@@ -1053,8 +1054,8 @@ static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
         snprintf(nodename, FDT_NAME_MAX, "pci@%x", slot);
     }
     offset = fdt_add_subnode(fdt, node_offset, nodename);
-    ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb->index, drc_index,
-                                      phb);
+    ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb);
+
     g_assert(!ret);
     if (ret) {
         return 0;
@@ -1069,15 +1070,12 @@ static void spapr_phb_add_pci_device(sPAPRDRConnector *drc,
 {
     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
     DeviceState *dev = DEVICE(pdev);
-    int drc_index = drck->get_index(drc);
     void *fdt = NULL;
     int fdt_start_offset = 0, fdt_size;
 
     if (dev->hotplugged) {
         fdt = create_device_tree(&fdt_size);
-        fdt_start_offset = spapr_create_pci_child_dt(phb, pdev,
-                                                     drc_index, NULL,
-                                                     fdt, 0);
+        fdt_start_offset = spapr_create_pci_child_dt(phb, pdev, fdt, 0);
         if (!fdt_start_offset) {
             error_setg(errp, "Failed to create pci child device tree node");
             goto out;
@@ -1579,11 +1577,8 @@ static void spapr_populate_pci_devices_dt(PCIBus *bus, PCIDevice *pdev,
     sPAPRFDT *p = opaque;
     int offset;
     sPAPRFDT s_fdt;
-    uint32_t drc_index = spapr_phb_get_pci_drc_index(p->sphb, pdev);
 
-    offset = spapr_create_pci_child_dt(p->sphb, pdev,
-                                       drc_index, NULL,
-                                       p->fdt, p->node_off);
+    offset = spapr_create_pci_child_dt(p->sphb, pdev, p->fdt, p->node_off);
     if (!offset) {
         error_report("Failed to create pci child device tree node");
         return;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 26/30] spapr_vty: lookup should only return valid VTY objects
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (24 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 25/30] spapr_pci: drop redundant args in spapr_[populate, create]_pci_child_dt Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 27/30] spapr-vty: Use TYPE_ definition instead of hardcoding Alexander Graf
                   ` (4 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, Greg Kurz, qemu-devel, David Gibson

From: David Gibson <david@gibson.dropbear.id.au>

If a guest passes the reg property of a valid VIO object that is not a VTY
to either H_GET_TERM_CHAR or H_PUT_TERM_CHAR, QEMU hits a dynamic cast
assertion and aborts.

PAPR+ says "Hypervisor checks the termno parameter for validity against the
Vterm IOA unit addresses assigned to the partition, else return H_Parameter."

This patch adds a type check to ensure vty_lookup() either returns a pointer
to a valid VTY object or NULL.  H_GET_TERM_CHAR and H_PUT_TERM_CHAR will
now return H_PARAMETER to the guest instead of crashing.

The patch has no effect on the reg == 0 hack used to implement the RTAS call
display-character.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/char/spapr_vty.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 1d53035..2d532af 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -228,6 +228,10 @@ VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg)
         return spapr_vty_get_default(spapr->vio_bus);
     }
 
+    if (!object_dynamic_cast(OBJECT(sdev), TYPE_VIO_SPAPR_VTY_DEVICE)) {
+        return NULL;
+    }
+
     return sdev;
 }
 
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 27/30] spapr-vty: Use TYPE_ definition instead of hardcoding
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (25 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 26/30] spapr_vty: lookup should only return valid VTY objects Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 28/30] sPAPR: Don't enable EEH on emulated PCI devices Alexander Graf
                   ` (3 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, qemu-devel, David Gibson

From: David Gibson <david@gibson.dropbear.id.au>

There's a call to object_dynamic_cast() in spapr_vty which uses the type
name "spapr-vty" directly, instead of the usual idiom of using the #defined
TYPE_VIO_SPAPR_VTY_DEVICE.  Fix it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/char/spapr_vty.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 2d532af..36b328b 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -193,7 +193,7 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
         DeviceState *iter = kid->child;
 
         /* Only look at VTY devices */
-        if (!object_dynamic_cast(OBJECT(iter), "spapr-vty")) {
+        if (!object_dynamic_cast(OBJECT(iter), TYPE_VIO_SPAPR_VTY_DEVICE)) {
             continue;
         }
 
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 28/30] sPAPR: Don't enable EEH on emulated PCI devices
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (26 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 27/30] spapr-vty: Use TYPE_ definition instead of hardcoding Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 29/30] sPAPR: Reenable EEH functionality on reboot Alexander Graf
                   ` (2 subsequent siblings)
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Gavin Shan

From: Gavin Shan <gwshan@linux.vnet.ibm.com>

There might have emulated PCI devices, together with VFIO PCI
devices under one PHB. The EEH capability shouldn't enabled
on emulated PCI devices.

The patch returns error when enabling EEH capability on emulated
PCI devices by RTAS call "ibm,set-eeh-option".

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index a139aea..a8f79d8 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -429,6 +429,7 @@ static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
 {
     sPAPRPHBState *sphb;
     sPAPRPHBClass *spc;
+    PCIDevice *pdev;
     uint32_t addr, option;
     uint64_t buid;
     int ret;
@@ -446,6 +447,12 @@ static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
         goto param_error_exit;
     }
 
+    pdev = pci_find_device(PCI_HOST_BRIDGE(sphb)->bus,
+                           (addr >> 16) & 0xFF, (addr >> 8) & 0xFF);
+    if (!pdev || !object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
+        goto param_error_exit;
+    }
+
     spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
     if (!spc->eeh_set_option) {
         goto param_error_exit;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 29/30] sPAPR: Reenable EEH functionality on reboot
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (27 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 28/30] sPAPR: Don't enable EEH on emulated PCI devices Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 15:49 ` [Qemu-devel] [PULL 30/30] sPAPR: Clear stale MSIx table during EEH reset Alexander Graf
  2015-07-07 22:16 ` [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Peter Maydell
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Gavin Shan

From: Gavin Shan <gwshan@linux.vnet.ibm.com>

When rebooting the guest, some PEs might be in frozen state. The
contained PCI devices won't work properly if their frozen states
aren't cleared in time. One case running into this situation would
be maximal EEH error times encountered in the guest.

The patch reenables the EEH functinality on PEs on PHB's reset
callback, which will clear their frozen states if needed.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci_vfio.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index 99a1be5..8104074 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -71,9 +71,26 @@ static void spapr_phb_vfio_finish_realize(sPAPRPHBState *sphb, Error **errp)
                                 spapr_tce_get_iommu(tcet));
 }
 
+static void spapr_phb_vfio_eeh_reenable(sPAPRPHBVFIOState *svphb)
+{
+    struct vfio_eeh_pe_op op = {
+        .argsz = sizeof(op),
+        .op    = VFIO_EEH_PE_ENABLE
+    };
+
+    vfio_container_ioctl(&svphb->phb.iommu_as,
+                         svphb->iommugroupid, VFIO_EEH_PE_OP, &op);
+}
+
 static void spapr_phb_vfio_reset(DeviceState *qdev)
 {
-    /* Do nothing */
+    /*
+     * The PE might be in frozen state. To reenable the EEH
+     * functionality on it will clean the frozen state, which
+     * ensures that the contained PCI devices will work properly
+     * after reboot.
+     */
+    spapr_phb_vfio_eeh_reenable(SPAPR_PCI_VFIO_HOST_BRIDGE(qdev));
 }
 
 static int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 30/30] sPAPR: Clear stale MSIx table during EEH reset
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (28 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 29/30] sPAPR: Reenable EEH functionality on reboot Alexander Graf
@ 2015-07-07 15:49 ` Alexander Graf
  2015-07-07 22:16 ` [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Peter Maydell
  30 siblings, 0 replies; 41+ messages in thread
From: Alexander Graf @ 2015-07-07 15:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: peter.maydell, David Gibson, qemu-devel, Gavin Shan

From: Gavin Shan <gwshan@linux.vnet.ibm.com>

The PCI device MSIx table is cleaned out in hardware after EEH PE
reset. However, we still hold the stale MSIx entries in QEMU, which
should be cleared accordingly. Otherwise, we will run into another
(recursive) EEH error and the PCI devices contained in the PE have
to be offlined exceptionally.

The patch introduces function spapr_phb_vfio_eeh_pre_reset(), which
is called by sPAPR when asserting hot or fundamental reset, to clear
stale MSIx table for VFIO PCI devices before EEH PE reset so that
MSIx table could be restored properly after EEH PE reset.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci_vfio.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index 8104074..cca45ed 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -19,6 +19,7 @@
 
 #include "hw/ppc/spapr.h"
 #include "hw/pci-host/spapr.h"
+#include "hw/pci/msix.h"
 #include "linux/vfio.h"
 #include "hw/vfio/vfio.h"
 
@@ -159,6 +160,49 @@ static int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state)
     return RTAS_OUT_SUCCESS;
 }
 
+static void spapr_phb_vfio_eeh_clear_dev_msix(PCIBus *bus,
+                                              PCIDevice *pdev,
+                                              void *opaque)
+{
+    /* Check if the device is VFIO PCI device */
+    if (!object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
+        return;
+    }
+
+    /*
+     * The MSIx table will be cleaned out by reset. We need
+     * disable it so that it can be reenabled properly. Also,
+     * the cached MSIx table should be cleared as it's not
+     * reflecting the contents in hardware.
+     */
+    if (msix_enabled(pdev)) {
+        uint16_t flags;
+
+        flags = pci_host_config_read_common(pdev,
+                                            pdev->msix_cap + PCI_MSIX_FLAGS,
+                                            pci_config_size(pdev), 2);
+        flags &= ~PCI_MSIX_FLAGS_ENABLE;
+        pci_host_config_write_common(pdev,
+                                     pdev->msix_cap + PCI_MSIX_FLAGS,
+                                     pci_config_size(pdev), flags, 2);
+    }
+
+    msix_reset(pdev);
+}
+
+static void spapr_phb_vfio_eeh_clear_bus_msix(PCIBus *bus, void *opaque)
+{
+       pci_for_each_device(bus, pci_bus_num(bus),
+                           spapr_phb_vfio_eeh_clear_dev_msix, NULL);
+}
+
+static void spapr_phb_vfio_eeh_pre_reset(sPAPRPHBState *sphb)
+{
+       PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
+
+       pci_for_each_bus(phb->bus, spapr_phb_vfio_eeh_clear_bus_msix, NULL);
+}
+
 static int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
 {
     sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);
@@ -170,9 +214,11 @@ static int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
         op.op = VFIO_EEH_PE_RESET_DEACTIVATE;
         break;
     case RTAS_SLOT_RESET_HOT:
+        spapr_phb_vfio_eeh_pre_reset(sphb);
         op.op = VFIO_EEH_PE_RESET_HOT;
         break;
     case RTAS_SLOT_RESET_FUNDAMENTAL:
+        spapr_phb_vfio_eeh_pre_reset(sphb);
         op.op = VFIO_EEH_PE_RESET_FUNDAMENTAL;
         break;
     default:
-- 
1.8.1.4

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

* Re: [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4
  2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
                   ` (29 preceding siblings ...)
  2015-07-07 15:49 ` [Qemu-devel] [PULL 30/30] sPAPR: Clear stale MSIx table during EEH reset Alexander Graf
@ 2015-07-07 22:16 ` Peter Maydell
  30 siblings, 0 replies; 41+ messages in thread
From: Peter Maydell @ 2015-07-07 22:16 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc, QEMU Developers

On 7 July 2015 at 16:49, Alexander Graf <agraf@suse.de> wrote:
> Hi Peter,
>
> This is my current patch queue for ppc.  Please pull.
>
> Alex
>
>
> The following changes since commit 1452673888f6d7f0454276d049846c9bec659233:
>
>   Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20150706.0' into staging (2015-07-07 09:22:40 +0100)
>
> are available in the git repository at:
>
>
>   git://github.com/agraf/qemu.git tags/signed-ppc-for-upstream
>
> for you to fetch changes up to 6319b1dad04e66f450fb3ac6c31d2bf3940068b8:
>
>   sPAPR: Clear stale MSIx table during EEH reset (2015-07-07 17:44:54 +0200)
>
> ----------------------------------------------------------------
> Patch queue for ppc - 2015-07-07
>
> A few last minute PPC changes for 2.4:
>
>   - spapr: Update SLOF
>   - spapr: Fix a few bugs
>   - spapr: Preparation for hotplug
>   - spapr: Minor code cleanups
>   - linux-user: Add mftb handling
>   - kvm: Enable hugepage support with memory-backend-file
>   - mac99: Remove nonexistent interrupt pin (Mac OS 9 fix)

Applied, thanks.

-- PMM

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

* Re: [PULL 24/30] spapr_pci: populate ibm,loc-code
  2015-07-07 15:49 ` [Qemu-devel] [PULL 24/30] spapr_pci: populate ibm,loc-code Alexander Graf
@ 2021-08-09  9:57   ` Peter Maydell
  2021-08-10  4:29     ` David Gibson
  0 siblings, 1 reply; 41+ messages in thread
From: Peter Maydell @ 2021-08-09  9:57 UTC (permalink / raw)
  Cc: Greg Kurz, qemu-ppc, QEMU Developers, Nikunj A Dadhania, David Gibson

On Tue, 7 Jul 2015 at 16:49, Alexander Graf <agraf@suse.de> wrote:
>
> From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
>
> Each hardware instance has a platform unique location code.  The OF
> device tree that describes a part of a hardware entity must include
> the “ibm,loc-code” property with a value that represents the location
> code for that hardware entity.
>
> Populate ibm,loc-code.

Ancient patch, but Coverity has just noticed a bug in it
which is still present in current QEMU (CID 1460454):

> +static char *spapr_phb_vfio_get_loc_code(sPAPRPHBState *sphb,  PCIDevice *pdev)
> +{
> +    char *path = NULL, *buf = NULL, *host = NULL;
> +
> +    /* Get the PCI VFIO host id */
> +    host = object_property_get_str(OBJECT(pdev), "host", NULL);
> +    if (!host) {
> +        goto err_out;
> +    }
> +
> +    /* Construct the path of the file that will give us the DT location */
> +    path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
> +    g_free(host);
> +    if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) {
> +        goto err_out;
> +    }
> +    g_free(path);

Here we create a 'path' string, use it as the argument to
g_file_get_contents() and then free it (either here or in the err_out path)...

> +
> +    /* Construct and read from host device tree the loc-code */
> +    path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
> +    g_free(buf);
> +    if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) {
> +        goto err_out;
> +    }
> +    return buf;

...but here we forget to free it before returning in the success case.

> +
> +err_out:
> +    g_free(path);
> +    return NULL;
> +}

Cleanest fix would be to declare 'path' and 'host' as
   g_autofree char *path = NULL;
   g_autofree char *host = NULL;
and then you can remove all the manual g_free(path) and g_free(host) calls.

thanks
-- PMM


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

* Re: [PULL 24/30] spapr_pci: populate ibm,loc-code
  2021-08-09  9:57   ` Peter Maydell
@ 2021-08-10  4:29     ` David Gibson
  2021-08-10  5:07       ` Philippe Mathieu-Daudé
  2021-08-13 15:17       ` Peter Maydell
  0 siblings, 2 replies; 41+ messages in thread
From: David Gibson @ 2021-08-10  4:29 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-ppc, QEMU Developers, Nikunj A Dadhania, Greg Kurz

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

On Mon, Aug 09, 2021 at 10:57:00AM +0100, Peter Maydell wrote:
> On Tue, 7 Jul 2015 at 16:49, Alexander Graf <agraf@suse.de> wrote:
> >
> > From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
> >
> > Each hardware instance has a platform unique location code.  The OF
> > device tree that describes a part of a hardware entity must include
> > the “ibm,loc-code” property with a value that represents the location
> > code for that hardware entity.
> >
> > Populate ibm,loc-code.
> 
> Ancient patch, but Coverity has just noticed a bug in it
> which is still present in current QEMU (CID 1460454):
> 
> > +static char *spapr_phb_vfio_get_loc_code(sPAPRPHBState *sphb,  PCIDevice *pdev)
> > +{
> > +    char *path = NULL, *buf = NULL, *host = NULL;
> > +
> > +    /* Get the PCI VFIO host id */
> > +    host = object_property_get_str(OBJECT(pdev), "host", NULL);
> > +    if (!host) {
> > +        goto err_out;
> > +    }
> > +
> > +    /* Construct the path of the file that will give us the DT location */
> > +    path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
> > +    g_free(host);
> > +    if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) {
> > +        goto err_out;
> > +    }
> > +    g_free(path);
> 
> Here we create a 'path' string, use it as the argument to
> g_file_get_contents() and then free it (either here or in the err_out path)...
> 
> > +
> > +    /* Construct and read from host device tree the loc-code */
> > +    path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
> > +    g_free(buf);
> > +    if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) {
> > +        goto err_out;
> > +    }
> > +    return buf;
> 
> ...but here we forget to free it before returning in the success case.
> 
> > +
> > +err_out:
> > +    g_free(path);
> > +    return NULL;
> > +}
> 
> Cleanest fix would be to declare 'path' and 'host' as
>    g_autofree char *path = NULL;
>    g_autofree char *host = NULL;
> and then you can remove all the manual g_free(path) and g_free(host) calls.

Thanks for the report.  I've committed the fix (I hope) below to ppc-for-6.1:

From 70ae61b510dc571c407b28c46498cae60e60ca66 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Tue, 10 Aug 2021 14:28:19 +1000
Subject: [PATCH] spapr_pci: Fix leak in spapr_phb_vfio_get_loc_code() with
 g_autofree

This uses g_autofree to simplify logic in spapr_phb_vfio_get_loc_code(),
in the process fixing a leak in one of the paths.  I'm told this fixes
Coverity error CID 1460454

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Fixes: 16b0ea1d852 ("spapr_pci: populate ibm,loc-code")
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_pci.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7a725855f9..13d806f390 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -782,33 +782,28 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
 
 static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb,  PCIDevice *pdev)
 {
-    char *path = NULL, *buf = NULL, *host = NULL;
+    g_autofree char *path = NULL;
+    g_autofree char *host = NULL;
+    char *buf = NULL;
 
     /* Get the PCI VFIO host id */
     host = object_property_get_str(OBJECT(pdev), "host", NULL);
     if (!host) {
-        goto err_out;
+        return NULL;
     }
 
     /* Construct the path of the file that will give us the DT location */
     path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
-    g_free(host);
     if (!g_file_get_contents(path, &buf, NULL, NULL)) {
-        goto err_out;
+        return NULL;
     }
-    g_free(path);
 
     /* Construct and read from host device tree the loc-code */
     path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
-    g_free(buf);
     if (!g_file_get_contents(path, &buf, NULL, NULL)) {
-        goto err_out;
+        return NULL;
     }
     return buf;
-
-err_out:
-    g_free(path);
-    return NULL;
 }
 
 static char *spapr_phb_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
-- 
2.31.1



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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PULL 24/30] spapr_pci: populate ibm,loc-code
  2021-08-10  4:29     ` David Gibson
@ 2021-08-10  5:07       ` Philippe Mathieu-Daudé
  2021-08-13 15:17       ` Peter Maydell
  1 sibling, 0 replies; 41+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-10  5:07 UTC (permalink / raw)
  To: David Gibson, Peter Maydell
  Cc: qemu-ppc, QEMU Developers, Nikunj A Dadhania, Greg Kurz

On 8/10/21 6:29 AM, David Gibson wrote:
> On Mon, Aug 09, 2021 at 10:57:00AM +0100, Peter Maydell wrote:
>> On Tue, 7 Jul 2015 at 16:49, Alexander Graf <agraf@suse.de> wrote:
>>>
>>> From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
>>>
>>> Each hardware instance has a platform unique location code.  The OF
>>> device tree that describes a part of a hardware entity must include
>>> the “ibm,loc-code” property with a value that represents the location
>>> code for that hardware entity.
>>>
>>> Populate ibm,loc-code.
>>
>> Ancient patch, but Coverity has just noticed a bug in it
>> which is still present in current QEMU (CID 1460454):
>>
>>> +static char *spapr_phb_vfio_get_loc_code(sPAPRPHBState *sphb,  PCIDevice *pdev)
>>> +{
>>> +    char *path = NULL, *buf = NULL, *host = NULL;
>>> +
>>> +    /* Get the PCI VFIO host id */
>>> +    host = object_property_get_str(OBJECT(pdev), "host", NULL);
>>> +    if (!host) {
>>> +        goto err_out;
>>> +    }
>>> +
>>> +    /* Construct the path of the file that will give us the DT location */
>>> +    path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
>>> +    g_free(host);
>>> +    if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) {
>>> +        goto err_out;
>>> +    }
>>> +    g_free(path);
>>
>> Here we create a 'path' string, use it as the argument to
>> g_file_get_contents() and then free it (either here or in the err_out path)...
>>
>>> +
>>> +    /* Construct and read from host device tree the loc-code */
>>> +    path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
>>> +    g_free(buf);
>>> +    if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) {
>>> +        goto err_out;
>>> +    }
>>> +    return buf;
>>
>> ...but here we forget to free it before returning in the success case.
>>
>>> +
>>> +err_out:
>>> +    g_free(path);
>>> +    return NULL;
>>> +}
>>
>> Cleanest fix would be to declare 'path' and 'host' as
>>    g_autofree char *path = NULL;
>>    g_autofree char *host = NULL;
>> and then you can remove all the manual g_free(path) and g_free(host) calls.
> 
> Thanks for the report.  I've committed the fix (I hope) below to ppc-for-6.1:
> 
> From 70ae61b510dc571c407b28c46498cae60e60ca66 Mon Sep 17 00:00:00 2001
> From: David Gibson <david@gibson.dropbear.id.au>
> Date: Tue, 10 Aug 2021 14:28:19 +1000
> Subject: [PATCH] spapr_pci: Fix leak in spapr_phb_vfio_get_loc_code() with
>  g_autofree
> 
> This uses g_autofree to simplify logic in spapr_phb_vfio_get_loc_code(),
> in the process fixing a leak in one of the paths.  I'm told this fixes
> Coverity error CID 1460454
> 
> Reported-by: Peter Maydell <peter.maydell@linaro.org>
> Fixes: 16b0ea1d852 ("spapr_pci: populate ibm,loc-code")
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> ---
>  hw/ppc/spapr_pci.c | 17 ++++++-----------
>  1 file changed, 6 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 7a725855f9..13d806f390 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -782,33 +782,28 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
>  
>  static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb,  PCIDevice *pdev)
>  {
> -    char *path = NULL, *buf = NULL, *host = NULL;
> +    g_autofree char *path = NULL;
> +    g_autofree char *host = NULL;
> +    char *buf = NULL;
>  
>      /* Get the PCI VFIO host id */
>      host = object_property_get_str(OBJECT(pdev), "host", NULL);
>      if (!host) {
> -        goto err_out;
> +        return NULL;
>      }
>  
>      /* Construct the path of the file that will give us the DT location */
>      path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
> -    g_free(host);
>      if (!g_file_get_contents(path, &buf, NULL, NULL)) {
> -        goto err_out;
> +        return NULL;
>      }
> -    g_free(path);
>  
>      /* Construct and read from host device tree the loc-code */
>      path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
> -    g_free(buf);
>      if (!g_file_get_contents(path, &buf, NULL, NULL)) {
> -        goto err_out;
> +        return NULL;
>      }
>      return buf;
> -
> -err_out:
> -    g_free(path);
> -    return NULL;
>  }
>  
>  static char *spapr_phb_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
> 



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

* Re: [PULL 24/30] spapr_pci: populate ibm,loc-code
  2021-08-10  4:29     ` David Gibson
  2021-08-10  5:07       ` Philippe Mathieu-Daudé
@ 2021-08-13 15:17       ` Peter Maydell
  2021-08-15 14:36         ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 41+ messages in thread
From: Peter Maydell @ 2021-08-13 15:17 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, QEMU Developers, Nikunj A Dadhania, Greg Kurz

On Tue, 10 Aug 2021 at 05:40, David Gibson <david@gibson.dropbear.id.au> wrote:
>
> On Mon, Aug 09, 2021 at 10:57:00AM +0100, Peter Maydell wrote:
> >
> > Cleanest fix would be to declare 'path' and 'host' as
> >    g_autofree char *path = NULL;
> >    g_autofree char *host = NULL;
> > and then you can remove all the manual g_free(path) and g_free(host) calls.
>
> Thanks for the report.  I've committed the fix (I hope) below to ppc-for-6.1:
>
> From 70ae61b510dc571c407b28c46498cae60e60ca66 Mon Sep 17 00:00:00 2001
> From: David Gibson <david@gibson.dropbear.id.au>
> Date: Tue, 10 Aug 2021 14:28:19 +1000
> Subject: [PATCH] spapr_pci: Fix leak in spapr_phb_vfio_get_loc_code() with
>  g_autofree
>
> This uses g_autofree to simplify logic in spapr_phb_vfio_get_loc_code(),
> in the process fixing a leak in one of the paths.  I'm told this fixes
> Coverity error CID 1460454
>
> Reported-by: Peter Maydell <peter.maydell@linaro.org>
> Fixes: 16b0ea1d852 ("spapr_pci: populate ibm,loc-code")
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/ppc/spapr_pci.c | 17 ++++++-----------
>  1 file changed, 6 insertions(+), 11 deletions(-)
>
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 7a725855f9..13d806f390 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -782,33 +782,28 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
>
>  static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb,  PCIDevice *pdev)
>  {
> -    char *path = NULL, *buf = NULL, *host = NULL;
> +    g_autofree char *path = NULL;
> +    g_autofree char *host = NULL;
> +    char *buf = NULL;
>
>      /* Get the PCI VFIO host id */
>      host = object_property_get_str(OBJECT(pdev), "host", NULL);
>      if (!host) {
> -        goto err_out;
> +        return NULL;
>      }
>
>      /* Construct the path of the file that will give us the DT location */
>      path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
> -    g_free(host);
>      if (!g_file_get_contents(path, &buf, NULL, NULL)) {
> -        goto err_out;
> +        return NULL;
>      }
> -    g_free(path);
>
>      /* Construct and read from host device tree the loc-code */
>      path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
> -    g_free(buf);

This deletion doesn't look right -- 'buf' is not autofree
(and shouldn't be, since we're returning it).

If you want to delete this 'g_free' you need to make the
first g_file_get_contents() use a separate char* variable from
the variable we use to return the eventual result data buffer;
then you can make that new variable be g_autofree.

>      if (!g_file_get_contents(path, &buf, NULL, NULL)) {
> -        goto err_out;
> +        return NULL;
>      }
>      return buf;
> -
> -err_out:
> -    g_free(path);
> -    return NULL;
>  }

thanks
-- PMM


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

* Re: [PULL 24/30] spapr_pci: populate ibm,loc-code
  2021-08-13 15:17       ` Peter Maydell
@ 2021-08-15 14:36         ` Philippe Mathieu-Daudé
  2021-08-16  4:37           ` David Gibson
  0 siblings, 1 reply; 41+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-15 14:36 UTC (permalink / raw)
  To: Peter Maydell, David Gibson
  Cc: qemu-ppc, QEMU Developers, Nikunj A Dadhania, Greg Kurz

On 8/13/21 5:17 PM, Peter Maydell wrote:
> On Tue, 10 Aug 2021 at 05:40, David Gibson <david@gibson.dropbear.id.au> wrote:
>>
>> On Mon, Aug 09, 2021 at 10:57:00AM +0100, Peter Maydell wrote:
>>>
>>> Cleanest fix would be to declare 'path' and 'host' as
>>>    g_autofree char *path = NULL;
>>>    g_autofree char *host = NULL;
>>> and then you can remove all the manual g_free(path) and g_free(host) calls.
>>
>> Thanks for the report.  I've committed the fix (I hope) below to ppc-for-6.1:
>>
>> From 70ae61b510dc571c407b28c46498cae60e60ca66 Mon Sep 17 00:00:00 2001
>> From: David Gibson <david@gibson.dropbear.id.au>
>> Date: Tue, 10 Aug 2021 14:28:19 +1000
>> Subject: [PATCH] spapr_pci: Fix leak in spapr_phb_vfio_get_loc_code() with
>>  g_autofree
>>
>> This uses g_autofree to simplify logic in spapr_phb_vfio_get_loc_code(),
>> in the process fixing a leak in one of the paths.  I'm told this fixes
>> Coverity error CID 1460454
>>
>> Reported-by: Peter Maydell <peter.maydell@linaro.org>
>> Fixes: 16b0ea1d852 ("spapr_pci: populate ibm,loc-code")
>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
>> ---
>>  hw/ppc/spapr_pci.c | 17 ++++++-----------
>>  1 file changed, 6 insertions(+), 11 deletions(-)
>>
>> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
>> index 7a725855f9..13d806f390 100644
>> --- a/hw/ppc/spapr_pci.c
>> +++ b/hw/ppc/spapr_pci.c
>> @@ -782,33 +782,28 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
>>
>>  static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb,  PCIDevice *pdev)
>>  {
>> -    char *path = NULL, *buf = NULL, *host = NULL;
>> +    g_autofree char *path = NULL;
>> +    g_autofree char *host = NULL;
>> +    char *buf = NULL;
>>
>>      /* Get the PCI VFIO host id */
>>      host = object_property_get_str(OBJECT(pdev), "host", NULL);
>>      if (!host) {
>> -        goto err_out;
>> +        return NULL;
>>      }
>>
>>      /* Construct the path of the file that will give us the DT location */
>>      path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
>> -    g_free(host);
>>      if (!g_file_get_contents(path, &buf, NULL, NULL)) {
>> -        goto err_out;
>> +        return NULL;
>>      }
>> -    g_free(path);
>>
>>      /* Construct and read from host device tree the loc-code */
>>      path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
>> -    g_free(buf);
> 
> This deletion doesn't look right -- 'buf' is not autofree
> (and shouldn't be, since we're returning it).

Oops, good catch!

> If you want to delete this 'g_free' you need to make the
> first g_file_get_contents() use a separate char* variable from
> the variable we use to return the eventual result data buffer;
> then you can make that new variable be g_autofree.
> 
>>      if (!g_file_get_contents(path, &buf, NULL, NULL)) {
>> -        goto err_out;
>> +        return NULL;
>>      }
>>      return buf;
>> -
>> -err_out:
>> -    g_free(path);
>> -    return NULL;
>>  }
> 
> thanks
> -- PMM
> 



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

* Re: [PULL 24/30] spapr_pci: populate ibm,loc-code
  2021-08-15 14:36         ` Philippe Mathieu-Daudé
@ 2021-08-16  4:37           ` David Gibson
  2021-08-16  9:07             ` Peter Maydell
  2021-08-17  8:42             ` Philippe Mathieu-Daudé
  0 siblings, 2 replies; 41+ messages in thread
From: David Gibson @ 2021-08-16  4:37 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Peter Maydell, qemu-ppc, QEMU Developers, Nikunj A Dadhania, Greg Kurz

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

On Sun, Aug 15, 2021 at 04:36:18PM +0200, Philippe Mathieu-Daudé wrote:
> On 8/13/21 5:17 PM, Peter Maydell wrote:
> > On Tue, 10 Aug 2021 at 05:40, David Gibson <david@gibson.dropbear.id.au> wrote:
> >>
> >> On Mon, Aug 09, 2021 at 10:57:00AM +0100, Peter Maydell wrote:
> >>>
> >>> Cleanest fix would be to declare 'path' and 'host' as
> >>>    g_autofree char *path = NULL;
> >>>    g_autofree char *host = NULL;
> >>> and then you can remove all the manual g_free(path) and g_free(host) calls.
> >>
> >> Thanks for the report.  I've committed the fix (I hope) below to ppc-for-6.1:
> >>
> >> From 70ae61b510dc571c407b28c46498cae60e60ca66 Mon Sep 17 00:00:00 2001
> >> From: David Gibson <david@gibson.dropbear.id.au>
> >> Date: Tue, 10 Aug 2021 14:28:19 +1000
> >> Subject: [PATCH] spapr_pci: Fix leak in spapr_phb_vfio_get_loc_code() with
> >>  g_autofree
> >>
> >> This uses g_autofree to simplify logic in spapr_phb_vfio_get_loc_code(),
> >> in the process fixing a leak in one of the paths.  I'm told this fixes
> >> Coverity error CID 1460454
> >>
> >> Reported-by: Peter Maydell <peter.maydell@linaro.org>
> >> Fixes: 16b0ea1d852 ("spapr_pci: populate ibm,loc-code")
> >> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> >> ---
> >>  hw/ppc/spapr_pci.c | 17 ++++++-----------
> >>  1 file changed, 6 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> >> index 7a725855f9..13d806f390 100644
> >> --- a/hw/ppc/spapr_pci.c
> >> +++ b/hw/ppc/spapr_pci.c
> >> @@ -782,33 +782,28 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
> >>
> >>  static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb,  PCIDevice *pdev)
> >>  {
> >> -    char *path = NULL, *buf = NULL, *host = NULL;
> >> +    g_autofree char *path = NULL;
> >> +    g_autofree char *host = NULL;
> >> +    char *buf = NULL;
> >>
> >>      /* Get the PCI VFIO host id */
> >>      host = object_property_get_str(OBJECT(pdev), "host", NULL);
> >>      if (!host) {
> >> -        goto err_out;
> >> +        return NULL;
> >>      }
> >>
> >>      /* Construct the path of the file that will give us the DT location */
> >>      path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
> >> -    g_free(host);
> >>      if (!g_file_get_contents(path, &buf, NULL, NULL)) {
> >> -        goto err_out;
> >> +        return NULL;
> >>      }
> >> -    g_free(path);
> >>
> >>      /* Construct and read from host device tree the loc-code */
> >>      path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
> >> -    g_free(buf);
> > 
> > This deletion doesn't look right -- 'buf' is not autofree
> > (and shouldn't be, since we're returning it).
> 
> Oops, good catch!

Indeed.  Revised version below.  I'll only attempt to push this to 6.1
if we're going to rc4 for other reasons though.

From 705a10b1cfbe6bcdde37f37f3548845970dc4986 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Tue, 10 Aug 2021 14:28:19 +1000
Subject: [PATCH] spapr_pci: Fix leak in spapr_phb_vfio_get_loc_code() with
 g_autofree
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This uses g_autofree to simplify logic in spapr_phb_vfio_get_loc_code(),
in the process fixing a leak in one of the paths.  I'm told this fixes
Coverity error CID 1460454

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Fixes: 16b0ea1d852 ("spapr_pci: populate ibm,loc-code")
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_pci.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7a725855f9..7430bd6314 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -782,33 +782,29 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
 
 static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb,  PCIDevice *pdev)
 {
-    char *path = NULL, *buf = NULL, *host = NULL;
+    g_autofree char *path = NULL;
+    g_autofree char *host = NULL;
+    g_autofree char *devspec = NULL;
+    char *buf = NULL;
 
     /* Get the PCI VFIO host id */
     host = object_property_get_str(OBJECT(pdev), "host", NULL);
     if (!host) {
-        goto err_out;
+        return NULL;
     }
 
     /* Construct the path of the file that will give us the DT location */
     path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
-    g_free(host);
-    if (!g_file_get_contents(path, &buf, NULL, NULL)) {
-        goto err_out;
+    if (!g_file_get_contents(path, &devspec, NULL, NULL)) {
+        return NULL;
     }
-    g_free(path);
 
     /* Construct and read from host device tree the loc-code */
-    path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
-    g_free(buf);
+    path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", devspec);
     if (!g_file_get_contents(path, &buf, NULL, NULL)) {
-        goto err_out;
+        return NULL;
     }
     return buf;
-
-err_out:
-    g_free(path);
-    return NULL;
 }
 
 static char *spapr_phb_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
-- 
2.31.1



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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PULL 24/30] spapr_pci: populate ibm,loc-code
  2021-08-16  4:37           ` David Gibson
@ 2021-08-16  9:07             ` Peter Maydell
  2021-08-17  3:02               ` David Gibson
  2021-08-17  8:42             ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 41+ messages in thread
From: Peter Maydell @ 2021-08-16  9:07 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, Philippe Mathieu-Daudé,
	QEMU Developers, Nikunj A Dadhania, Greg Kurz

On Mon, 16 Aug 2021 at 06:41, David Gibson <david@gibson.dropbear.id.au> wrote:
>
> Indeed.  Revised version below.  I'll only attempt to push this to 6.1
> if we're going to rc4 for other reasons though.

We are doing an rc4, but I don't think we really need this in 6.1,
given that the original leak only happens on a very rare error case
("/sys/ not mounted").

-- PMM


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

* Re: [PULL 24/30] spapr_pci: populate ibm,loc-code
  2021-08-16  9:07             ` Peter Maydell
@ 2021-08-17  3:02               ` David Gibson
  0 siblings, 0 replies; 41+ messages in thread
From: David Gibson @ 2021-08-17  3:02 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-ppc, Philippe Mathieu-Daudé,
	QEMU Developers, Nikunj A Dadhania, Greg Kurz

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

On Mon, Aug 16, 2021 at 10:07:12AM +0100, Peter Maydell wrote:
> On Mon, 16 Aug 2021 at 06:41, David Gibson <david@gibson.dropbear.id.au> wrote:
> >
> > Indeed.  Revised version below.  I'll only attempt to push this to 6.1
> > if we're going to rc4 for other reasons though.
> 
> We are doing an rc4, but I don't think we really need this in 6.1,
> given that the original leak only happens on a very rare error case
> ("/sys/ not mounted").

Fair enough, I'll punt it to 6.2.

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PULL 24/30] spapr_pci: populate ibm,loc-code
  2021-08-16  4:37           ` David Gibson
  2021-08-16  9:07             ` Peter Maydell
@ 2021-08-17  8:42             ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 41+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-17  8:42 UTC (permalink / raw)
  To: David Gibson
  Cc: Peter Maydell, qemu-ppc, QEMU Developers, Nikunj A Dadhania, Greg Kurz

On 8/16/21 6:37 AM, David Gibson wrote:

> From 705a10b1cfbe6bcdde37f37f3548845970dc4986 Mon Sep 17 00:00:00 2001
> From: David Gibson <david@gibson.dropbear.id.au>
> Date: Tue, 10 Aug 2021 14:28:19 +1000
> Subject: [PATCH] spapr_pci: Fix leak in spapr_phb_vfio_get_loc_code() with
>  g_autofree
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> 
> This uses g_autofree to simplify logic in spapr_phb_vfio_get_loc_code(),
> in the process fixing a leak in one of the paths.  I'm told this fixes
> Coverity error CID 1460454
> 
> Reported-by: Peter Maydell <peter.maydell@linaro.org>
> Fixes: 16b0ea1d852 ("spapr_pci: populate ibm,loc-code")
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/ppc/spapr_pci.c | 22 +++++++++-------------
>  1 file changed, 9 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 7a725855f9..7430bd6314 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -782,33 +782,29 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
>  
>  static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb,  PCIDevice *pdev)
>  {
> -    char *path = NULL, *buf = NULL, *host = NULL;
> +    g_autofree char *path = NULL;
> +    g_autofree char *host = NULL;
> +    g_autofree char *devspec = NULL;
> +    char *buf = NULL;
>  
>      /* Get the PCI VFIO host id */
>      host = object_property_get_str(OBJECT(pdev), "host", NULL);
>      if (!host) {
> -        goto err_out;
> +        return NULL;
>      }
>  
>      /* Construct the path of the file that will give us the DT location */
>      path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
> -    g_free(host);
> -    if (!g_file_get_contents(path, &buf, NULL, NULL)) {
> -        goto err_out;
> +    if (!g_file_get_contents(path, &devspec, NULL, NULL)) {
> +        return NULL;
>      }
> -    g_free(path);
>  
>      /* Construct and read from host device tree the loc-code */
> -    path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
> -    g_free(buf);
> +    path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", devspec);
>      if (!g_file_get_contents(path, &buf, NULL, NULL)) {
> -        goto err_out;
> +        return NULL;
>      }
>      return buf;
> -
> -err_out:
> -    g_free(path);
> -    return NULL;
>  }
>  
>  static char *spapr_phb_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
> 

LGTM.



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

end of thread, other threads:[~2021-08-17  8:44 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-07 15:49 [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 01/30] linux-user, ppc: mftbl can be used by user application Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 02/30] macio: remove nonexistent interrupt on pin 1 Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 03/30] target-ppc: fix hugepage support when using memory-backend-file Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 04/30] spapr: ensure we have at least one XICS server Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 05/30] pseries: Update SLOF firmware image to qemu-slof-20150429 Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 06/30] spapr: Merge sPAPREnvironment into sPAPRMachineState Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 07/30] spapr: Remove obsolete ram_limit field from sPAPRMachineState Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 08/30] spapr: Remove obsolete entry_point " Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 09/30] spapr: Add sPAPRMachineClass Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 10/30] spapr_pci: encode missing 64-bit memory address space Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 11/30] spapr_pci: encode class code including Prog IF register Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 12/30] spapr_pci: set device node unit address as hex Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 13/30] spapr_iommu: drop erroneous check in h_put_tce_indirect() Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 14/30] spapr_iommu: translate sPAPRTCEAccess to IOMMUAccessFlags Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 15/30] Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)" Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 16/30] spapr: Consider max_cpus during xics initialization Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 17/30] spapr: Support ibm, lrdr-capacity device tree property Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 18/30] cpus: Add a macro to walk CPUs in reverse Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 19/30] spapr: Reorganize CPU dt generation code Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 20/30] spapr: Consolidate cpu init code into a routine Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 21/30] ppc: Update cpu_model in MachineState Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 22/30] xics_kvm: Don't enable KVM_CAP_IRQ_XICS if already enabled Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 23/30] spapr_pci: enumerate and add PCI device tree Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 24/30] spapr_pci: populate ibm,loc-code Alexander Graf
2021-08-09  9:57   ` Peter Maydell
2021-08-10  4:29     ` David Gibson
2021-08-10  5:07       ` Philippe Mathieu-Daudé
2021-08-13 15:17       ` Peter Maydell
2021-08-15 14:36         ` Philippe Mathieu-Daudé
2021-08-16  4:37           ` David Gibson
2021-08-16  9:07             ` Peter Maydell
2021-08-17  3:02               ` David Gibson
2021-08-17  8:42             ` Philippe Mathieu-Daudé
2015-07-07 15:49 ` [Qemu-devel] [PULL 25/30] spapr_pci: drop redundant args in spapr_[populate, create]_pci_child_dt Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 26/30] spapr_vty: lookup should only return valid VTY objects Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 27/30] spapr-vty: Use TYPE_ definition instead of hardcoding Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 28/30] sPAPR: Don't enable EEH on emulated PCI devices Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 29/30] sPAPR: Reenable EEH functionality on reboot Alexander Graf
2015-07-07 15:49 ` [Qemu-devel] [PULL 30/30] sPAPR: Clear stale MSIx table during EEH reset Alexander Graf
2015-07-07 22:16 ` [Qemu-devel] [PULL 00/30] ppc patch queue 2015-07-07 for 2.4 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.