From 613e7a764501a236cdfce39561f9bcf60c78cf49 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Thu, 30 Jul 2015 20:25:15 +0530 Subject: [PATCH 01/36] spapr: Provide an error message when migration fails due to htab_shift mismatch Include an error message when migration fails due to mismatch in htab_shift values at source and target. This should provide a bit more verbose message in addition to the current migration failure message that reads like: qemu-system-ppc64: error while loading state for instance 0x0 of device 'spapr/htab' After this patch, the failure message will look like this: qemu-system-ppc64: htab_shift mismatch: source 29 target 24 qemu-system-ppc64: error while loading state for instance 0x0 of device 'spapr/htab' Signed-off-by: Bharata B Rao Signed-off-by: David Gibson --- hw/ppc/spapr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 05926a3eb2..dd58eb433a 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1329,6 +1329,8 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id) if (section_hdr) { /* First section, just the hash shift */ if (spapr->htab_shift != section_hdr) { + error_report("htab_shift mismatch: source %d target %d", + section_hdr, spapr->htab_shift); return -EINVAL; } return 0; From fb0fc8f62c16b5b0910545f56c64aaafc91533ce Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 12 Aug 2015 13:15:56 +1000 Subject: [PATCH 02/36] spapr: Create pseries-2.5 machine Add pseries-2.5 machine version. Signed-off-by: Bharata B Rao [Altered to merge before memory hotplug -- dwg] [Altered to work with b9f072d01 -- dwg] Signed-off-by: David Gibson --- hw/ppc/spapr.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index dd58eb433a..df76cb7a39 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1976,7 +1976,7 @@ static void spapr_machine_2_4_class_init(ObjectClass *oc, void *data) mc->desc = "pSeries Logical Partition (PAPR compliant) v2.4"; mc->alias = "pseries"; - mc->is_default = 1; + mc->is_default = 0; } static const TypeInfo spapr_machine_2_4_info = { @@ -1985,6 +1985,22 @@ static const TypeInfo spapr_machine_2_4_info = { .class_init = spapr_machine_2_4_class_init, }; +static void spapr_machine_2_5_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->name = "pseries-2.5"; + mc->desc = "pSeries Logical Partition (PAPR compliant) v2.5"; + mc->alias = "pseries"; + mc->is_default = 1; +} + +static const TypeInfo spapr_machine_2_5_info = { + .name = MACHINE_TYPE_NAME("pseries-2.5"), + .parent = TYPE_SPAPR_MACHINE, + .class_init = spapr_machine_2_5_class_init, +}; + static void spapr_machine_register_types(void) { type_register_static(&spapr_machine_info); @@ -1992,6 +2008,7 @@ static void spapr_machine_register_types(void) type_register_static(&spapr_machine_2_2_info); type_register_static(&spapr_machine_2_3_info); type_register_static(&spapr_machine_2_4_info); + type_register_static(&spapr_machine_2_5_info); } type_init(spapr_machine_register_types) From 2c1aaa819a0d68a51086f5d7e8f9a0114ae0305c Mon Sep 17 00:00:00 2001 From: Sam Bobroff Date: Tue, 1 Sep 2015 11:23:19 +1000 Subject: [PATCH 03/36] spapr: Add /ibm,partition-name QEMU has a notion of the guest name, so if it's present we might as well put that into the device tree as /ibm,partition-name. This is specificed by PAPR. Signed-off-by: Sam Bobroff Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index df76cb7a39..09962c4f8e 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -375,6 +375,11 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, _FDT((fdt_property_string(fdt, "vm,uuid", buf))); g_free(buf); + if (qemu_get_vm_name()) { + _FDT((fdt_property_string(fdt, "ibm,partition-name", + qemu_get_vm_name()))); + } + _FDT((fdt_property_cell(fdt, "#address-cells", 0x2))); _FDT((fdt_property_cell(fdt, "#size-cells", 0x2))); From a95f99224c08efcf91b4259c34754f69d962bf23 Mon Sep 17 00:00:00 2001 From: Sam Bobroff Date: Tue, 1 Sep 2015 11:23:34 +1000 Subject: [PATCH 04/36] spapr: Add /rtas/ibm,change-msix-capable QEMU is MSI-X capable and makes it available via ibm,change-msi, so we should indicate this by adding /rtas/ibm,change-msix-capable to the device tree. This is specificed by PAPR. Signed-off-by: Sam Bobroff Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 09962c4f8e..ed0abd8498 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -432,6 +432,10 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, _FDT((fdt_property_cell(fdt, "rtas-event-scan-rate", RTAS_EVENT_SCAN_RATE))); + if (msi_supported) { + _FDT((fdt_property(fdt, "ibm,change-msix-capable", NULL, 0))); + } + /* * According to PAPR, rtas ibm,os-term does not guarantee a return * back to the guest cpu. From b359bd6a424b8de7db994d7120e87a7465b69337 Mon Sep 17 00:00:00 2001 From: Sam Bobroff Date: Tue, 1 Sep 2015 11:23:47 +1000 Subject: [PATCH 05/36] spapr: Make ibm, change-msi respect 3 return values Currently, rtas_ibm_change_msi() always returns four values even if less are specified. Correct this by only returning the fourth parameter if it was requested. This is specified by PAPR. Signed-off-by: Sam Bobroff Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index a2feb4c985..6782fd0b4d 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -375,7 +375,9 @@ out: rtas_st(rets, 0, RTAS_OUT_SUCCESS); rtas_st(rets, 1, req_num); rtas_st(rets, 2, ++seq_num); - rtas_st(rets, 3, ret_intr_type); + if (nret > 3) { + rtas_st(rets, 3, ret_intr_type); + } trace_spapr_pci_rtas_ibm_change_msi(config_addr, func, req_num, irq); } From e39432282e2d2db42645c2ce183dfcaa1488752b Mon Sep 17 00:00:00 2001 From: Sam Bobroff Date: Tue, 1 Sep 2015 11:24:37 +1000 Subject: [PATCH 06/36] spapr: SPLPAR Characteristics Improve the SPLPAR Characteristics information: Add MaxPlatProcs: set to max_cpus, the maximum CPUs that could be addded to the system. Add DesMem: set to the initial memory of the system. Add DesProcs: set to smp_cpus, the inital number of CPUs in the system. These tokens and values are specified by PAPR. Signed-off-by: Sam Bobroff Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr_rtas.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 9869bc9587..5cbf9a071a 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -34,6 +34,7 @@ #include "hw/ppc/spapr.h" #include "hw/ppc/spapr_vio.h" #include "qapi-event.h" +#include "hw/boards.h" #include #include "hw/ppc/spapr_drc.h" @@ -240,8 +241,14 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, switch (parameter) { case RTAS_SYSPARM_SPLPAR_CHARACTERISTICS: { - char *param_val = g_strdup_printf("MaxEntCap=%d,MaxPlatProcs=%d", - max_cpus, smp_cpus); + char *param_val = g_strdup_printf("MaxEntCap=%d," + "DesMem=%llu," + "DesProcs=%d," + "MaxPlatProcs=%d", + max_cpus, + current_machine->ram_size / M_BYTE, + smp_cpus, + max_cpus); rtas_st_buffer(buffer, length, (uint8_t *)param_val, strlen(param_val)); g_free(param_val); break; From ad440b4ae0727dbef5cace419d94d774de96886c Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 1 Sep 2015 11:25:35 +1000 Subject: [PATCH 07/36] spapr: add dumpdtb support dumpdtb (-machine dumpdtb=) allows one to inspect the generated device tree of machine types that generate device trees. This is useful for a) seeing what's there b) debugging/testing device tree generator patches. It can be used as follows $QEMU_CMDLINE -machine dumpdtb=dtb dtc -I dtb -O dts dtb Signed-off-by: Andrew Jones Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index ed0abd8498..a69d7e4754 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -30,6 +30,7 @@ #include "hw/fw-path-provider.h" #include "elf.h" #include "net/net.h" +#include "sysemu/device_tree.h" #include "sysemu/block-backend.h" #include "sysemu/cpus.h" #include "sysemu/kvm.h" @@ -831,6 +832,7 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr, exit(1); } + qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt)); cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt)); g_free(bootlist); From 627c2ef7898794a28d706ecdf094491bebbb083a Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 3 Sep 2015 10:08:23 +1000 Subject: [PATCH 08/36] spapr_drc: Fix potential undefined behaviour The DRC_INDEX_ID_MASK macro does a left shift on ~0, which is a signed quantity, and therefore undefined behaviour according to the C spec. In particular this causes warnings from the clang sanitizer. This fixes it by calculating the same mask without using ~0 (I think the new method is a more common idiom for generating masks anyway). For good measure I also use 1ULL to force the expression's type to unsigned long long, which should be good for assigning to anything we're going to want to. Reported-by: Peter Maydell Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr_drc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index ee874326ee..8cbcf4d346 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -32,7 +32,7 @@ #define DRC_CONTAINER_PATH "/dr-connector" #define DRC_INDEX_TYPE_SHIFT 28 -#define DRC_INDEX_ID_MASK (~(~0 << DRC_INDEX_TYPE_SHIFT)) +#define DRC_INDEX_ID_MASK ((1ULL << DRC_INDEX_TYPE_SHIFT) - 1) static sPAPRDRConnectorTypeShift get_type_shift(sPAPRDRConnectorType type) { From aaf87c6616370685a7cff6a21616fc5db7495014 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 1 Sep 2015 11:29:02 +1000 Subject: [PATCH 09/36] ppc/spapr: Use qemu_log_mask() for hcall_dprintf() To see the output of the hcall_dprintf statements, you currently have to enable the DEBUG_SPAPR_HCALLS macro in include/hw/ppc/spapr.h. This is ugly because a) not every user who wants to debug guest problems can or wants to recompile QEMU to be able to see such issues, and b) since this macro is disabled by default, the code in the hcall_dprintf() brackets tends to bitrot until somebody temporarily enables that macro again. Since the hcall_dprintf statements except one indicate guest problems, let's always use qemu_log_mask(LOG_GUEST_ERROR, ...) for this macro instead. One spot indicated an unimplemented host feature, so this is changed into qemu_log_mask(LOG_UNIMP, ...) instead. Now it's possible to see all those messages by simply adding the CLI parameter "-d guest_errors,unimp", without the need to re-compile the binary. Signed-off-by: Thomas Huth Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 3 ++- include/hw/ppc/spapr.h | 11 +++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 652ddf6e37..71fc9f23a1 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -971,7 +971,8 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, } } - hcall_dprintf("Unimplemented hcall 0x" TARGET_FMT_lx "\n", opcode); + qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x" TARGET_FMT_lx "\n", + opcode); return H_FUNCTION; } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 91a61abbc4..d2509677fb 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -353,15 +353,10 @@ typedef struct sPAPRDeviceTreeUpdateHeader { uint32_t version_id; } sPAPRDeviceTreeUpdateHeader; -/*#define DEBUG_SPAPR_HCALLS*/ - -#ifdef DEBUG_SPAPR_HCALLS #define hcall_dprintf(fmt, ...) \ - do { fprintf(stderr, "%s: " fmt, __func__, ## __VA_ARGS__); } while (0) -#else -#define hcall_dprintf(fmt, ...) \ - do { } while (0) -#endif + do { \ + qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt, __func__, ## __VA_ARGS__); \ + } while (0) typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm, target_ulong opcode, From e6fc9568c865f2f81499475a4e322cd563fdfd90 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Tue, 1 Sep 2015 09:53:52 +1000 Subject: [PATCH 10/36] spapr_rtas: Prevent QEMU crash during hotplug without a prior device_add If drmgr is used in the guest to hotplug a device before a device_add has been issued via the QEMU monitor, QEMU segfaults in configure_connector call. This occurs due to accessing of NULL FDT which otherwise would have been created and associated with the DRC during device_add command. Check for NULL FDT and return failure from configure_connector call. As per PAPR+, an error value of -9003 seems appropriate for this failure. Signed-off-by: Bharata B Rao Cc: Michael Roth Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr_rtas.c | 6 ++++++ include/hw/ppc/spapr_drc.h | 15 ++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 5cbf9a071a..2f8e25cfb2 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -522,6 +522,12 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu, drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); fdt = drck->get_fdt(drc, NULL); + if (!fdt) { + DPRINTF("rtas_ibm_configure_connector: Missing FDT for DRC index: %xh\n", + drc_index); + rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE; + goto out; + } ccs = spapr_ccs_find(spapr, drc_index); if (!ccs) { diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h index 60cda35ed2..28ffeaeb1c 100644 --- a/include/hw/ppc/spapr_drc.h +++ b/include/hw/ppc/spapr_drc.h @@ -119,13 +119,14 @@ typedef enum { } sPAPRDREntitySense; typedef enum { - SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */ - SPAPR_DR_CC_RESPONSE_NEXT_CHILD = 2, - SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY = 3, - SPAPR_DR_CC_RESPONSE_PREV_PARENT = 4, - SPAPR_DR_CC_RESPONSE_SUCCESS = 0, - SPAPR_DR_CC_RESPONSE_ERROR = -1, - SPAPR_DR_CC_RESPONSE_CONTINUE = -2, + SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */ + SPAPR_DR_CC_RESPONSE_NEXT_CHILD = 2, + SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY = 3, + SPAPR_DR_CC_RESPONSE_PREV_PARENT = 4, + SPAPR_DR_CC_RESPONSE_SUCCESS = 0, + SPAPR_DR_CC_RESPONSE_ERROR = -1, + SPAPR_DR_CC_RESPONSE_CONTINUE = -2, + SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003, } sPAPRDRCCResponse; typedef void (spapr_drc_detach_cb)(DeviceState *d, void *opaque); From a14aa92b20c5482b9b694901304b8100b3c4b5a1 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Tue, 1 Sep 2015 11:05:12 +1000 Subject: [PATCH 11/36] sPAPR: Introduce rtas_ldq() This introduces rtas_ldq() to load 64-bits parameter from continuous two 4-bytes memory chunk of RTAS parameter buffer, to simplify the code. Signed-off-by: Gavin Shan Reviewed-by: Thomas Huth Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 20 ++++++++++---------- include/hw/ppc/spapr.h | 5 +++++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 6782fd0b4d..54292c9d81 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -140,7 +140,7 @@ static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr, return; } - buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); + buid = rtas_ldq(args, 1); size = rtas_ld(args, 3); addr = rtas_ld(args, 0); @@ -206,7 +206,7 @@ static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr, return; } - buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); + buid = rtas_ldq(args, 1); val = rtas_ld(args, 4); size = rtas_ld(args, 3); addr = rtas_ld(args, 0); @@ -269,7 +269,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong rets) { uint32_t config_addr = rtas_ld(args, 0); - uint64_t buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); + uint64_t buid = rtas_ldq(args, 1); unsigned int func = rtas_ld(args, 3); unsigned int req_num = rtas_ld(args, 4); /* 0 == remove all */ unsigned int seq_num = rtas_ld(args, 5); @@ -391,7 +391,7 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu, target_ulong rets) { uint32_t config_addr = rtas_ld(args, 0); - uint64_t buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); + uint64_t buid = rtas_ldq(args, 1); unsigned int intr_src_num = -1, ioa_intr_num = rtas_ld(args, 3); sPAPRPHBState *phb = NULL; PCIDevice *pdev = NULL; @@ -440,7 +440,7 @@ static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu, goto param_error_exit; } - buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); + buid = rtas_ldq(args, 1); addr = rtas_ld(args, 0); option = rtas_ld(args, 3); @@ -484,7 +484,7 @@ static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu, goto param_error_exit; } - buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); + buid = rtas_ldq(args, 1); sphb = spapr_pci_find_phb(spapr, buid); if (!sphb) { goto param_error_exit; @@ -539,7 +539,7 @@ static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu, goto param_error_exit; } - buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); + buid = rtas_ldq(args, 1); sphb = spapr_pci_find_phb(spapr, buid); if (!sphb) { goto param_error_exit; @@ -584,7 +584,7 @@ static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu, goto param_error_exit; } - buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); + buid = rtas_ldq(args, 1); option = rtas_ld(args, 3); sphb = spapr_pci_find_phb(spapr, buid); if (!sphb) { @@ -619,7 +619,7 @@ static void rtas_ibm_configure_pe(PowerPCCPU *cpu, goto param_error_exit; } - buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); + buid = rtas_ldq(args, 1); sphb = spapr_pci_find_phb(spapr, buid); if (!sphb) { goto param_error_exit; @@ -654,7 +654,7 @@ static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu, goto param_error_exit; } - buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); + buid = rtas_ldq(args, 1); sphb = spapr_pci_find_phb(spapr, buid); if (!sphb) { goto param_error_exit; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index d2509677fb..cbe3463e32 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -489,6 +489,11 @@ static inline uint32_t rtas_ld(target_ulong phys, int n) return ldl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n)); } +static inline uint64_t rtas_ldq(target_ulong phys, int n) +{ + return (uint64_t)rtas_ld(phys, n) << 32 | rtas_ld(phys, n + 1); +} + static inline void rtas_st(target_ulong phys, int n, uint32_t val) { stl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n), val); From 785652dc4db2023aeda4e381eb08e0beae67b870 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Thu, 13 Aug 2015 14:53:02 +0200 Subject: [PATCH 12/36] pseries: define coldplugged devices as "configured" When a device is hotplugged, attach() sets "configured" to false, waiting an action from the OS to configure it and then to call ibm,configure-connector. On ibm,configure-connector, the hypervisor sets "configured" to true. In case of coldplugged device, attach() sets "configured" to false, but firmware and OS never call the ibm,configure-connector in this case, so it remains set to false. It could be harmless, but when we unplug a device, hypervisor waits the device becomes configured because for it, a not configured device is a device being configured, so it waits the end of configuration to unplug it... and it never happens, so it is never unplugged. This patch set by default coldplugged device to "configured=true", hotplugged device to "configured=false". Signed-off-by: Laurent Vivier Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 8cbcf4d346..9ce844ab1e 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -310,7 +310,7 @@ static void attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt, drc->dev = d; drc->fdt = fdt; drc->fdt_start_offset = fdt_start_offset; - drc->configured = false; + drc->configured = coldplug; object_property_add_link(OBJECT(drc), "device", object_get_typename(OBJECT(drc->dev)), From 92d7a30cb3656f577f87b19042d9b66ff3b20e3b Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Thu, 13 Aug 2015 19:24:16 +1000 Subject: [PATCH 13/36] pseries: Update SLOF firmware image to qemu-slof-20150813 The changes are: 1. GPT support; 2. Much faster VGA support. The full changelog is: > Add missing half word access case to _FASTRMOVE and _FASTMOVE > Remove unused RMOVE64 stub > fbuffer: Implement RFILL as an accelerated primitive > fbuffer: Implement MRMOVE as an accelerated primitive > fbuffer: Precalculate line length in bytes > terminal: Disable the terminal-write trace by default > boot: remove trailing ":" in the bootpath > ci: implement boot client interface > boot: bootpath should be complete device path > fbuffer: Use a smaller cursor > fbuffer: Improve invert-region helper > usb-hid: Caps is not always shift > cas: Increase FDT buffer size to accomodate larger ibm, cas node properties > README: Update with patch submittion note > disk-label: add support for booting from GPT FAT partition > disk-label: introduce helper to check fat filesystem > introduce 8-byte LE helpers > disk-label: simplify gpt-prep-partition? routine > fbuffer: introduce the invert-region-x helper > fbuffer: introduce the invert-region helper > fbuffer: simplify address computations in fb8-toggle-cursor Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- pc-bios/README | 2 +- pc-bios/slof.bin | Bin 912720 -> 915584 bytes roms/SLOF | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pc-bios/README b/pc-bios/README index 05cf0421be..e4154ab9f0 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-20150429. + built from git tag qemu-slof-20150813. - 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 0398ac67bc8d07410fe2ccc9d62c376ef3cf87c3..701933f7dc7b20f6cfcbb538a95142d0a598ada8 100644 GIT binary patch delta 165318 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 ad5RqSDQUjTVn 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 E0D_6E4*&oF delta 163955 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

^Q`x+xc>E zFwL?68^btj`hPbLaj#jRtbpt~Xcn0TiZT>4Ace~;P*fnRhsOD=46w1&%j`G=r}MjW zurtn@-tW#KE;$PnL)Z+OzTcfgoN3k!us)_)3qVP5`ZYTa0V8Ely#VqDs6N7`735E3 zH!PTD&mlJ5&lBXm3m|hCXHBp7;1JiE1qyp?CV+g2WP+l?^aQvOvl&1}IL!v-9V9i% zpkj}KPjEIU)UlX38xa zraP2@hK?O!{+t7fJS3GWAcuoY#>hg`7dV0<0_Kqnut`jF3Lp*y#T$|_s-W})G6qKm zngc3FkkrGK{*V`45bCr4V*Y2BlKExKp})A zsS0u+$S}*udYcPEQXhvi%T7FXjIUS_W0X!ct{hJeq!1R6L92`t@1Evdrb$}ub$>DGv z3E(-D>1xiy8aAvS%P3x~$^ zbrBpK)33R32ynr&=ez=lG@C1j!1TB}kcI}ZJI!1<1f!q9F#Q|I1#&?g97gkSR1fn& zQHg92DD*(C`vEp+dYBu?cBtTd4v1iz8;1sy`iAKn+&IMGzMgLYo}HTh%ng*#4s&o! z|L4Y`A*BwofPqhNJ}9-Jde_07Lu~rK!yFt;^D`iN%iN)QndVnabLSA(1jRR!>olMR z#e7hnK{f1xJBRpm{xA-9ruhpXhOv1-(l4hYs7OFI1>_WvlR$BeVhW_Fm=DTwNb2Qh zOi%FO5aW`9=Ir@5z-|LoXh^CwK$!t#D#*hqrcOWL!680ev_(*g$2Oy2ZwAg8VK z=ip#kAOI3zS|Bm~fES1ObahV-ekBc1QN_R~xB!$=P)vfjZ-E6wj{_tVEbxGE1HhSX z`ZiAvf$8VGI5-&-rW<5%h)FE~Yn7#ny8HkS$Ky0}NHV~Re7hC|_!nEK9n4Zq&4RQiZ@&(wo>E_-X z{L|lsb8tv41o<1q0+0Zo;6e^?1{PWfY7ZbeOzpz-3EmuH;9M@X5L9p?Nos&%mw``k zp#j)oLJL8@K$4f=G5rHbvtJnp2h&22X?r-tq!xlw43Zk~;j|z#5+D<_3kx9rX!GF^ zP=W>JLbSvy4~^D^9pK7v`Zga>`rO08G5whjhX#}8iRl8qNcm~u0kG$$yZLemaKSCS z0JZP|)bXHfjpQ(m6Vn&?f_lxMw6*XDIAJVe0IQW+1d3uLwJ`TA5`ege%@67xsYPf( z2D5#U0oeBGX&{yB{5d!o!AVaFyoU~($q`_anHD90LXl|^xb~m^&5uJsNedJ>419u% zK)D7>)Gh*7A>z}+{WI6Q3>~z#%Ywy*~#B;|H*SAgHKA@`}cZ=?(#)VhU7qF6IE)JH0G`LxV|s!Sn?I zNYS+zQV&nR1~L$wwHG@~H^}A?V_FQYE!YAi@-{Jd4Hui$QH(B=w+FAIKrbB@N0A zAbWOz!cq%7q=ckQ2h@!PNrNh86l13c1c53qXc}MqV7fsYhuHMCAW)ie=ip#mJUu?1 zLtF?vD2}S}K@f+S5-c$;LCeb0Pz#qxO#cwfAwFF^n1kO)2bzVK;3y!MfINZZYH5q< z1;HG8OgcZNF9=48vn2@-S6&O|5Sacin1j<1R8%5q)P>eJOF*d=#nq4kXbC7bkkm_O zOg9MO5CfZ~398?bzF2RwQ!COL+tpYh0r2Yli5KU0pL6!!k2?jpFr65lrxr9q$dP69On3pazc$b2F zk0KA!z$dsA6zs_6feImzd7%Cjl6uab=>lPpHWMdf!1RPX4l$;s5z`AoIY8$bD`awr z34u4KqH5^~#5;>493#An6U$FQjmY zO*aeY5SU&U%E1Xr7s|kI3CWyucQZxRt7#n z@Ge;tM?f?$;{bbfx>^K>!1Q}592`u`B&L6e_A6QszFkwuL0E#Dq64^3knG&_3|^O7l4h0#>27|U}L8*kL2L@(gziJAiHq1xt4*# z1;sF^<)Ao164$#iEeaY8hG-2ieNbiuSpiD!*xdVLxqP_K1PTv{+DS;m*OKwE|=ok|PX2O-u$p!4)8{p#oqMF)Cex&;9y$e0cnG*2$)_F$006>7UFP?3DXr~ImD-bkLBP8kK}5t zKnrFAkhefi0A&+YCj`WCh)u7Hi27}5)20p=67{v!9N>*ur4VGGk z7L2g^Yn27q7fh?bjccY=0Z=<4Aa*QI;^3Du0!25-4p1URas2cPNgQI+=ecljFs*8U z=wMIg;I}e{R-UUsu0zoQbrq;mMG7-mgKX6baBiKRmdqhAy)T)A(-EzFFb35+Ag6#* zD>j2c;frGM^aIJDBn9eUt$F});&-qULAeKH5-71^F$sK303M}597d}_ zi58ptKp}zTK4VbifUL~`FNU7(n#v)_1slRzT>&w+Je7lA3brL@H7Ep7OrE|Vl|u|N zh_reEBqpw644`eS!j7&F3;}Dw;9&uZJWBP#-P;Hn74Kz(q zl0tI53CJxBe1hOLny79%kj5d#1>2dmMgZJtkz9io=&($;2E3x1X^qD81?iv>j&u(G z>EQm+8t^d2^ssaef$89oUgH6(j+xd3OfM+r5EEJh3QkmuH>AUyzor1}e5N%O;LIYl z22}YYyZ**>fedJEVzdU7=8+^#LFoYGHBfStl0o6eWsUXKs#(qYoLAcWeAZA z(8$Q(5Cm7(Ol!bBN-?1|XyGUuFf9|-BVPmVkxw_vgn4-_xCJ7#7OmG~S};8!6RD_M zt1-PGi$i?+^h^$ZE>lni#K0%G)?)eskl^u54t~gt&{}W+YOMv8Y{=dPxd@~IGe8xx zIK-q(p!sMmD7_-<`!PKr3mS$@Ya6B~lyis)tpz0ulrWpV0i>udi-VI9GOo+Cb_FDI z)@}ehTM#XM8Zt~5$OZ)oNXrRu{4uS)0jh|^1<~4crVY~z;7UJ$lE?IA*&G7X=aqAC zIIaUVAW)nFiN1Acp$V&0)}f_P&FTNMImD;u&EVjeZkEF#U<6kPDl3r!LKak?Fz^Yk zLu=ldWlT@V0o8mbI5?(H%K@bp&}im5$W+y_91Z~`Gf?RV(h6#zU~_8&xH4c`*8%SL zO;^k15QGdBuA2eQSJT6CIRvlMIm6j~3; zP)N=(WSG7Hqz#qgxJ>sN=jnWr-4Mk1H%e^)ISfe$tSsLE9UW#Xf~9~B zGr&58Hh_v!6dltOia=#Y7zc;c22dEINJ7GR!vSzPI}K#oy#fwSO;Bb*QfC1zxHf=N zF-jaw{{S)^T#;?~01gtS4L`s+X}Vf5sC;PP;9%Ow0V;;Xr-v7F@Pntmq&A|J02a`M zw^0Ec&{7-G(y=}?gf~J4_k=cr_(%?vZkWEI7}oWA2D13yT9CyN(+x^M&A}25jp_cL z9PHEGN;m|j+m&!|GFCu(QDq=3Qh(-!Hpmq#pjTa z+lZF`VI|kb9T1z@OF8(tVDY^11lVNs(6s{PD3BePp_@?3p~qyhVETkoP-nD^gF_Hx zEt1DAcT7J}3W{D(XKfQ&vbF*_nt@Mn6GpP0u29AyCS?Um4j_57W|v0B^nfxBJtnIc z(;GnQVDo94(9*Bfj_Dgf^V0i3h3%#caINsHj6*=l8Wg=CgF(p`OQ>z?04EipO`r^b z+fmPHu{ryyE8*mB48f^rT$CToxB3(7gfq~MMMl^;lESVv61P|hL7r2*=- zgWLd`Bodp>RspK&TRAwSHi6O_7DsJ{&P%3Ma0o~#fLbaHe1egR;`h*JT1eefe zP`Dyltza?zKm};gOB)9V(`NAU3!}|wDb*Sp=9@uf1U6ShfXjBF&7g_~+3X$D11dq| z!k{1pIjjJjW!ow_1h^DH@d6TS01u-wZSDX^#kNWg0VW%P=?_5qV8OL{1K9lOVpSkt zf>InvBdA@DWSMlsbcZUqFVPAEg^K9~Rd8QICVrPyaR?aMKtmk7R27TYwt$)mNVeE$ zOsfX<*K0U91wjc0Ny_@dbOVswyJ`+jNwl)S8sr`ZKEW*p(-o>Y#HXiMbMQ;qfP4TF z#0b{u2dX*5xNM-owk2VDK@Dhlp_+rA%LZgJNK?V|2OyKwYmfySAjXH+aPS-1f|3D9 zB`8s1^BO3pA-UhCVfqG;HT5+d9O$hsn;X*~fQA=9eiKAXyf!zc3)FJxG1(?ecc|qM zGlIq17SNanlKBdtR0VPmC@mw2g9g}ZL47*VFu_)En|AuLS`GmzTTnU0z$dsBlw?sn zF#SR;hnN&B32j9y3ZyNjfhO2N!w!sF!OOR_wxTr}Y@wCIR!}NLH9Db=LyXH78Z}!p zz?pvfv^ov}gkS}v>N^G&1o;N!NJ#qqR>vV=We0LFNDN2FZ$%4vSnAliVfu$!&=5mC z2S36#$i!4zJ%@ml9W=FW1+^JaoxPzRlwzQXW9tiuLC?Vk!Cd$QoWsN#Kn8(a#=s}I z4U|Su4RUAz1udw>36cl-1TC%_U~#n#Tv|+D*1#cPWCwB)NCPOKQ49nX{(OSlKxrJw zAe)A1ji4$ZjDtgH8(Ohp_hPyMSkj$?!)Y6+qCwJV4{|ZcB2ebQW)WIn&gRDS35~E~ zVH>D~L^4d%WBP$c4m~D2gXte&HhOIXm3Byq>_J`v*$7Ja*lYylZ6x)!(D2@NWBP#x z4vb!j?T_gVO&sE&c|&%gZD@JK?#1*CO&oem_7kQ*XyOo)gyp5}Xl0G~_I6MH*aJlTOVB?F(}_KN8S%^c#Apy)!f%MO|Ww|7iW0Qtncg@fPA0hHQ6dO)cY zOGs}=%QvtBayzJ?Kr-AuV)}#@Se$PMWo1;!11%h4TyPg$fVkj$3kN@wL&kK4R-}r0 zJ18!ZG%GHc9?%M!LIAbYc0h-Y+FCgTtYGW=cA&)+to6GC%{r0POI9lssZ>pcY{^2M5!R2ym6^1`+_p1JjNSuz7-L(c#E3 zy`T+gP+$kNF}@6>5!{sA0qN&Vzt+Yf2pMzU0iG$J&ejg=KgVq5Ck`=nRZ4@-vAEv z4$$xiXuZQua8podCtA2UF-(8Z!69Y@+xNW_t$1+)z?gBMqP@D%TmUn?d2uZyRD1<@kp{v_=DL{tycY$&%@isJ=qd<^(D#LB@ls7i`XH05|lccA1G$WR(0A93Qr_8&LAH!@Coh)6$e;s-Hlcpm}E>h=mm|vuj1fv z+6_w2NQQxjq(O#(yn-YSi>=+DM2IAAS22A;FNc^ETpy@FN0OIun0}xaw89o-9?0B` z=?1eo#F%!2*3F4|fseCAQtk{&f*@s}#DvW+pyC=yy$LARLF!jbpRkHUOlUV+h3Y6V zeM29In3N32Ss-U11Jr6K_9<02gd&_wE-^H$%c7bag!P zZU7gk*?Vw={~pZnzt9g2f5$yI!ha7aypS9U^S~ao@VB3?KY>FW?*2Uy5cj7|Kyv>c zXqfK-hq==pwEEEn8s>X&g!vwfFrTh45$gWwVG}t7f?%Py2bAuS9Su#Hd(cAN0hA{h z_yqTW@+gvexH&hbC(Ppzo4#!#$QK~zf)qnzVGlSKri)GD5U_HE2K`s~`CV`R*)Zu&4L;J<_3zLwN%iaixL)j)HIdm^1xTl*ggOhI-wG;*g#{ic`R8Y&H|>W~Ti&!0p8}kN~K0DzzUJ^hh?q7Dey>03ODiJ`JQ2 z+#Ear-dr^O*h~%qB@a-BXW$b&07};=-T*}qpWp!n$P}sSEDk{~4`}8%0PdU$9Y8Bg zJRVFBn8hK^xM6z3EKn7`jDw^80I0q~GM5XK)~AbDiL4gskxd4<1f(A1T@)8Vg8Lv^kcxwn4M;tt_^^g= zUxe)H<`X;!ia%rvKng(`K;eKat}y)osGgStWtW2>{~=3)_#jOgkW}_<4u=4I!P`N! zm{Mbyt}vHFj0<)!*g?qPOxRowfqGA9$#oFqY$Wf&HqRae#TJsqUZB(gvKSOw*wll9 z3t2rVb%4}^A`DagbkTVnf>K_fo-6~OAm}Dnjp(2$kdAI4XZiCgbsn6iX_k3GkwB*4lyoR z1MbiaaE(0u*nAEFcx&bmc(;wzAyAQr?8Q(&5g*k$4y_8GD1`k%3R} zFj^48YQ4jt1b8FVVQ|nJ9R`IevQ41c0pvl9SO5htpWtEW;cth3Ocz+pAub6LMbZvi zka7gPj-BZUWImVahy-~4km-oR^ni67V$+W;;t=4HgNFSP$kf;LZ;POX6Vnlg=@V2r z#e|N4k_3vcrUxvBdFx05xbeVrqyS6{9Rbx}NKP?0G5x_}4)N*vksR#P#g>5PduMQP zFdbO|S*>>je1x0P5wsNQ3rZjie1b+J7@F)X#+LGz00N8m1kAfJ;8bAdH zNCR4#2TSBfK_P*x9$M)hMJo$oCo3L>^r@MSKA65?DTg@Yi|Gv;ImC>Pg7Q0(`(ef( z19=*B@KKAyDrJiU*Ju5RDXIuqyl*TDbdz z3U-is99jJss18JOx*{mRLFz$HLlXCggy8hhl^lZ8L9JM(l zU^)&S<(po%ibFst0OVAV8c@NE&CCao0_fT*PLih2p9#z+z3j}*bGDqzJQGB1#3CP zrt7Wa;AG?gx0{(x3QYg7mP1?;R5>8o4I4T>sQ~i!^lNKDGw~q5oiqT|bK=w4*TL3$ zp9GcaNLm9y-ecesJc(JwC4g#3@M4*h(9M4*3#JRK$DAGs1QoC#GawDuZ|gV&jDkQ; z1c{-Q;;=k+5-qs>XG~XE5ACjModh`w*^!`(2QmyT%t4z7)^ms{1%PSp29hf}pj08+D_QULGyI|c5; zIh{f)r-ML#0qF-730R{26e!@4+^oScyIf0 zcw)N3CTR2C=`>m{3x@g|eDN7J2ZBmEB*TJlOm6@g1};oaXF$@~=?ZW4sS8YB08#{ASa=$e zg|2Pp5HJdXCe72JXuxJGS{4eNFl`Hmm{JHRBpLVw&!ELd2sDSC5tuHpl|x(;I& zgn-fi6bok1(r;2uWHJQ^pa3v2^*&OnD_pLqe<%i*>S zRMAFqa4?-^0I&RGI?DkrDW;c!WaF7NG1m z{n|DT0jW?>IDo`JUO;jBwCx;X)8B39;M4?ZLkbF55S<03A0%;&6VnYqdd`6yezpSa zaHg{jkW_zm0@&Hpr)>w7yP%yEXBSK_I0)*zfkgN~yUM?TSRj`RodpFXlF{A?(-n4r z0ur=3<1AW0hJjKV$P1v-2E_}YB*Q0o7Sw7(GR%L*^ahY&pdlZovycVu+jejWNcn?o zW#AJ$hnBKK8Kytjfz*sUCjn^|oKu*7VFzf{9sY=-Vz1 z0V%klpxlY%I7f-;3cEo=p`e6to&nSv5}O{j8)Q{52Zz*oP&J37JQV7e^AeD8p7R>u z1iWoGhk#NzsLW;H6Fd(JUo8GS?*T3rrOtyAI5smQz-Ec<;Sf-Y07X2=EKpg5&8!M= zA{IK27S_HR(+l>%1`^IsfV9TXLt5oR=g|sngA>#C!rIg4Pe9e)fMn*hy`UffcgsL5 zaFKof2c(65Y%hm^6l_c71&~XTd?P<&`UjAy>-J%;5j4=4uCNbkqtFGkG6A%NbsuQW z0H_pV;1j&y04hY7E(CyUoax*4A$1-vBut;MAGEP(9|u2EgvE4${TztXR4#Ntoawe7 zw00b{jram&rSB0`sn9=lQ`#A*QeWME}!0{w>0WDEQcucxEsE0NW&W5!4z% z3PWR1(~f~p@S+AdGafsDzJDLyXH5n$s^9fYnWJJIEn0{hc=l2h+s{un5z|4sh0Bx;Oz8E7PBW6o9kf zMQ}&m=ptI$iUef>kjp@|7?uQl5jxydb_f>AKBR;+T2xx`;VGd5l4WNW7j=pwO z_r~-MM?jS*DA`>)0iIi%{tRRqC~0V20;P7On1eNRFM(nfMSQxzQCJW268OLkvFUC{ zIRum1Gbv_GGy3@=`y5uF@4!lP|$(ae_z&^zTp^$`1I>XLEG~{14?Yi zI0U3%Yql<0P?gL(`CphL_(KAXMj@=?{)`h)<6{$-%+MFnz*x z4l%7OpsbI@zAK=n0+Ra{UzqN20<>Lm9S4Wd6;RU3bfh?)T09F(*PGN)3=@C5PI2Z2k=XRKGtf#! z=qg%}%kP*z;S7fu7tFG243O1L*90J?%QXpb%jnw~4gsk+P!KWj30}i!-A)fUi&SV_ zgB~5!c9ug>5)?`xJ)m@h;<@P?&T@!J!IJhhw5$*pG5x_=Sm|}Gf`I{fja3}9&b$UH z#ZZEJy2ClBCZ}tl)PiKAIH=JBatSCnku>7~kK;ob@j_R5X7eM>UA`)B!B`JWGIFgrWah~5aWWm^*VHa%0&(Vr36sP0@4Et zYb3j1gMK#{z=?M{+a*x#44MS~*;t=C<0JTjR_yli& z2im4j0~wNcmxDv-1}Kf8SU3H^B@QvE1dx|O8qm^F!iDJ{Ejuc5NP(6J3Pg}5 zj4U}l;4-LV>kYCIy$SL%l6?G% z=@+hmDpP+B4xyW9u@SRk+EorQu0&`OzG*Q1z!eU0M^N@gG6L2vx(V_-l6VZr?F@W^ zH$hQ`Bpxp?Jpp8FEKELP+I7$_@T(mBmWiP70qFr13rOJs_Z}#`kj#QRZ8|?_C-Aqc z90Ks9a1$-!5+kN7T;mXvN(99X$PVzE#J4H^_uH$jS!EQ*JwubVr-VZe9*Iqei51fgZg7YxC4$5m_yljEWs4+G@cs&emXV(1gUT72q228%Q8;4+n?PEs%GR z%+dWZUEwA)Z#vxqg%Ofu5-1EojsS%jir+ygoKNr;T7j9+Fnz{N4n6RWSfSgXQWMFr z_y^M;+~g4Bf^EsZEdlOkFx`e6S~A`37BsAwZbSNTLbuTpv&xO>1-GDy!{|1sJ%?m` z63Fcge1f+@0g5CJTgG-9GN&SR8n1AHmo0T8xp$H%|IgS zKzZ~wD9s?5p=vNa;Wj7`K?7>Hq08T<)(jC#+Py13oQ7>JD1tIRP4OcML!c z9Hu)KpbA3j4qDK|rnm2a&w((ygBJKHpqvVF0;oBJ#mRRv!1+Py4qD)+fIc`_Lei%DWBP_Wp!jm<;E1{das!fN zDky+JZUQBKB)`CxfZYK_3$l8U-3)w!cR}eLNj+!JbceefVpgdj%R%yJEnnCkpSz%f z1<5?v&hWe7u`{Q;pe7NLbSlWXAmczKI*N6WJb4!_YT{Q+y9doPLU%#YgJhPpisk)vIE914s|}=F58u;9_U`w)>zH%0QlF;1j%O0V*b$ z?s-7QLc|`xa**2t4gpEnBKLb}Wwhh;{0AK3Qm{mL4`djUQ#CTCFL;17Vs{U^q~jXM z^m8XTIGFB%2T8=Hvps~CHA445841Y@-5=8p9)gBP9&m7Kg7P_%TpGwekmEr)7&VY5 zfb@U{P=xM*QZbSyPlxFT9)cD>g2X|ZKS0OJKu!P!s?>c@IzrL`Tc&fLWBP%|9O8m# zf$RBTy22xn3mlPgMyh)@PPn0{Fxp|fQKTdr#%7rHh_ae=mDr4 zLek+?F@3@l(AkR6Xn$ZaeZf->aZOM;fTRo-d=Joq*Ym;j4eOLIAg)I zXP`~RPeBV7o^fz8g6FfRw>{+$Fv@`01j^kgAqRCksG>r$I-_IygQuVsn=pN#+>a!m zzGAun$THB)7Euq-a(^bMY+~ROd;m(ANS47`?GMn3-As_982AJqg4}|np0j8Ag=ZXM zO5&jC1j&Pv1d<~%L5>26Lk5?b9zr&;F+DVZ+&Nx4{HOiz0b zI=~!e9ON>I>C-^kL1~ofA!L&S)58i#q4EtR13n%8;RJBMeY)BUq*clfLHtpl? z6pl#Nrh^hbNFQ2wf^sZqXX+#Hc*1nG*Bk;?*&wGe@CiN!8HvS?$2bax$B=?ydfRKz z3BqeRID{UfH55D_OyBUDLwvfwKL@+eW3*<1H^cM?uQ|k|U`~CEmY6jdrVG4*Hi7CN zgTevHf7zh)1adPdPa?S)mKPtRHRE!?9_JH$4C1*F`aB?|;3IjP4W2V=7UvMy|T+FMYm z3fcqv7%j?jpef`rsCdEVbhO4c%;`@UrZ0HMA4L%?ZIzIUTz8hWZ2`Esp=zj`w5UNWi zd;pyh26o9)@HHmWk9`0I2((gv3QBn>CQbhUvM~pgAQ<=rpIU%zoUZl}ngE2Jg8YDL zN5Dr=KOZCx(gBJVB>9|(=?x#D8O7--S_?22lxjelK;e(#43JOw1fPQ93)!#}(;t8g z104(}^c3U=BuP;9_z86O!(R?|p{Hn(qLwh-;S+}#S1u@@gKXRZp2anK3M#sg41o>! zJOu>+k~pmFetH2sAU%EAC!`_hr!PS5=;_x$VsHa~fJ>Bn3)ZhjknEwovDUb|=RhiFL zfWvos8%!nBGw}HaLeJ0wTyDek4PQW63{+1)gRHZg{tToGG&t$>3@uCKK~u~#5RE0p zJOgD7B=_VqOn3MSYK4M^7M?@TlqmZOYI%T?4+Edza|v*tY}r@P!D(MPI2kn{b=@_P z0LTqm&q2j4vYF5l=s76Kqqt$Z!8Z;uE?AsAkASpIpF@XEo`XtgWOEp%PxuB)u+Pzw zx_83#10cg-3HCW;6ou*e3~-Tc^c*dL!=mUpsHjJ>1hy9HIk+6sdX5(S1)$~~C=@U| zK@HzQYbj=Ma2P#DYof#L0!0EgyM9bp_{kw|2uiX@(gn~Ee*sGKDB%WD$S3$h0lXMM z>IEq6Bk6+;-M=sZrzxfv(6nCmgF^tGpuuAy_s0>1~wGfokK)6^aDS@ z8$up%aEb}NK#MKVKE7WZVpcF?UV>r)$(RC=dImnhm!J|1O8~qCmta~iL9vOXtq@w| zyadG}ini$+et}L2E8t|;7JP}8r(i+x66AIy)0_mRKlp`|r(Qy?$YOdK0ckkA%zzYF zZofGMxZo~^9OWnV5-m@`0_J50IAcyP`whBR3gm5&H=*$c+qk^=!t@2dK@%t(oE%aw z(P9p^zxXA%V=?_2$e==4c!8n`)#C<#kZSRl55Pk+)6@QN2*9VMUVead{a=EY=`p=x zfULZG1>Oil=c|-1Yd!gv?x}AJi{mW3KaH8>I*@|K1jU*s2UKTuKpL) zT?LJ2zd{S|T!ZNWe>udAV2R=tC^nHyf{netLd#vb2GbkC3jTZAcC#ENW3|se?gM;ZccqRYzY5zfOOK5TR8bl*m4hxyrXc-Q)hVegA&HoyF zrn%H>wD^Yk={0!upwnwmLP9dV7!*Vx=Yy&?l$eDC)oW0UBdIS;m>R$-#s!O(*Wk6` zQ`Os<=7{KC#Hy|G(sRuv#Y##Xyv<92T#3?Ynj+v8lx_=#q`1E5;oQPWPO~&*B zW=?U&0`QoK)*H0oh57vrTESNwFkOL}Qw(e>BV_bM=nW|4Avp(>^FeArGc-(Zz{~EY zw=r`HSe1a1EXZG=Y=X^SXia5U-{B49%%ADcm_b1cYR7>LftANgwKDJt zzQvLF-=amp;tSIYSU3@L`EMcPrPG(OAO+D|gXs;doZ$(Zy~PM^P-5Z} ze2Z3)l|Gn$0OSx@T6?=5*W&ETMyMZIR&PJr_ zJq)A)yf*s10JxND0}Ft9O79h>Cvb6!3xdiT6ceUD;N%nopW1Kq9xY&DQT-m&Z$Z)o z^TYc9NTcIDxU8S<#>FXMR1PZG8TbU>gJ=~0L!$aUT6h*FOkco-6fWD{;w8RfP&HX*797b{=+~J@|KoXaqG2MV0*|Gy*4@^(v=7e1Ot@R$Q5~u)` z3Lx)*(in<&rXS$u6jOq=MBbz226zzt0Jj{OJ}^uV;Nt`hUx5zcny$u!RPlTOB`G9V zF1|25fQM5|2^PB_&>Ckjvp*PsU9a^46C#_@FU1pEYA1{s)A6Q0aC~(_)!3yRHq-~;}npR z1C?taLqIf=;#`C2A3zqvV)CN_IF$%}M2pGA7p5!lBc<1m(1VD=_>taFZUUSF@MTsX zK{1Bpg7Spv1p=V51+;|YBd9TeBncYy1WAGhOpHFFMOYOm96-(h)jik(|HJeH0-WOL zH#~YeOg9kZ)MN5Yn4TcWDF!JzKS55doIXvEQviMh%_j|T=U?g*T5$-Qd;J6*F*qj3 z3At)n=o4BQ2%6p#OuNI2_7j-xj+sBiKF?l24oIM98_c@s|S^c419uL7^Y89;uI750xFh~_acDX2^#$Y`B+a!TSA#4AwI8urhL)b-4u;$r$Mgkq z1M74(320Il`U3J2k`3V*(*q9Rs=q>qt<9u31t6CweQf{_lQMms0PZO;> z0Q+6&8z}iBd9$`)`U7cD@c-rDkoty}muf(P%)lr3O#{>+W%_0T9sr&0Cc`NJPPfd0 z-#oznn_dPI0?m$3Uj|}F%u8q+VxaEeL!fYKPqR8XCW`~58ozCTdIc01Nc!CuOg{iJ0Mx`4`i52q_%uxaAj>Jn1&hva z4Q(;Q|V5Ea~qDD3p=Z!`k#e(ULi=Iq;JM zTq{fcL<@h|MDF9{X|RZ4GhziL2(Vre`d;@ z0$hzC2Qlyo{wx5MI8r~+f*2MYKfwccT0hZ}wkW791?dK*UzA{&en6R1j7t<$D1hX_ z!{%B)LCTRrr3so4eu9*tYFAJJITLiX-cQIz&go$)oB~|#Ad5f-{s4#9^fnb}vY);U zBn><6>6Zk!uwnWIKI&ZP7swmP_D-1oK!p==gUl~bVS^-}7cgBwl~a8B`oA3PTEEbO zunClR8TbT$p{43vgXs>cAV-51$^HWQ49Uc1XfXdm3&3WO%^<@-ZEuti0BPV8{Dl@` znKz~zsDWxh&|cMFC%}1M=ocvXkS&Xto}k7Fxx1F}*Yy9OT?W(CI0fJ%kH4TxmyW4{ z%3{#HP`^ReAsGQXbM7|>c##v+Z-MC(G&sele^=w=pAK4sB=j4t>M|~vuAmNTu6lBC zF#U!M`24nj=n7ZoEd)Hx9+-u;H|AASZ> z4yvD>exs$&W>7dY@Cp6~g)5fu`;As4WL8Xf(BKr~N`>}Ney@NWf>x%%DLCChi@}OzO^a~o$$ane;Djbjkvjvn=K#l|z3RoQZ2QBbH z4M0c0p>DaG_-nw$bw zu(KHdpmmL42a^0jOZa}EWX8ZJ_y;l-C-est_DJ6JVVJI<11EqeDCTL^s4|sVx(;x8E_Vj03oC01gp!fnQ0YwN>*ur`b zf6(Hh6_g+t_yqrg!W>2Y^aa|SVo9w~^ZtT@4@DlNflu%+DB&PEu@z)K$UIPBA*qMW z8vg~wJ+k@@(-U++t${rp>`Z^5XM|1Dfi~8q{-OmNY#GYm2JkWzroYe*<~NWIaE|)B z0F)r7tLZ|GVEVfOoTH|PfkeQAiGL4(MVS7AFPNC#29f}sWuo;L6lh3}^9K15W%>!tporB_%L@J|BVgBALRmR^kuraS0? zx@EILClG>+0d-%Q{yBh^PhY0TDZteVawh|y;J<)rdYt0m9qLG~YXjK`k_9!^utdQ> zv@nI$ssGTDVw=Wv1AR~)*5l-KL`#Y7p!ybM2dMDJW(TPJMsic)h3OMOW`Ww}M*l!* z3Rx30S^op&2_#Lh2IRjBkaGPW$lFNr@d?vE=yQr$!PZCo1EoDAdANR1qXbDj36#M> zjt6f+j`|OZWhCi#P(Ehh6Z{VfM`UOAfE4lx{s(nQk<`P&?>|~hwl_>~FaU)g=q9@V zpa4VC)DH3s$P$oSP%N4L0Hg^N=|=z2G7HS3|Ir$XupM;&A%~6${RhQ7l4Xes(;Ws($Mgr*oMKuax1b(y3=-iJVgR`w z#rEk5Mu;ZA5Cd8aCV5PsV8kgl{hkdchZX~JJ|PBBNrw^?(?5U=g+{*+ z11Khu^d(-Hu3*e5HvOG7Cx;LNC?=6Ka|KKfFh+I}D9s^h1}!Hr<`mIC@`7V`1uFe7Dy?C zX~pyluAE}ir&(|caK(UfHOK`!raKsOiU~1+Vi?KfB#-F_KqiBdg%J~4^maq~S3*pn zV89lfAHdN*J%Ply>51=tKjtK~8)rZ2GK6q|l-4+p!j5Hngtq@0+3 z0VI1bg@c`0hF116keLd}0>VEO@TPH{$q={Kx7^0LM))9 zg{n-!hEoi7Uzre#0w{3Ar-$2c@_Y4w(mey85DO?ou>=kaD58-J%LbKPAoXaqRQG}D z8$cDyJsVC=Pf)3cq^B2@S3!DkL;wp~1iO9jZ^;?u=#Ir%}=AEzK%;s*^4*dj$c z%M6Im%56FMm3l#G2V^U#M8oDY@XB@3=~rzz1(l#fxk4;x4GQQGrw|JyDuh@-afIYG z&=H1qpmBr4ptQmQN@+;4x;LgLfMtz1Iiy%Yp@1X_i*8m9a4b)sX2&VO1wGVBh*e>_ zfe)wH^kX1FT~Hawz$e6N01^CV2O73^;N;Xqi=19iVFFT!Q7BChu;&z0f(0xqC=!vJ z0v+WNV$GO-0Ay>MJ*U9*b0(Y|)3@29COI{R=@0BV#U-I(%L*!RkPHINhdO{d9X^~K zLad-nj3lXYW4Z%Kvd@>3gNb#=bOQ%YarC{UeV`T<$OoWiElQ+KU*Ldfc?z+0jYkFb3uk+WQyqzoItH4kRc%X1Ca0)bLJF~ zN(9xJAVH9yk!%2EKW9!orv8HI1>rU$rlir1q>!31bB-~gq1Bv;CpKvFjcsJ1||a{{Q~ zW8f3w0HtnZ^(;{JpjbdsKM_<#fz*Raentj{de~xdc^jw(P)UZY0pt*n22k4;$pUGZ zLqXXcSv|-hAoXbJT>1{wd{FX0sF!A#2yzKX11OCnSs=e>x`GF%nAAj&#UOc*Pm$ym z7^XLXOtumNxj^b z=>?vgVqBA;A;_69-NAuF)JTXEt+<#3t=Kt1A&G223M2$Lr}u|)iaT+F{DmYfD*}~9 z3(!fR7zDWoRH!4X515|d#VI!ZUnnPsBqv&;mIbwnK$@n@hjEJ6bArlTWWCVH;6$rb zCqcD=#~P8;D}+GY#sw+~5s}9*2^5(Od_r7kVXpwbZ;?+3d}0PO!}MNnPEOBBAj?3C zK>?0rxFQeKa8L<}Y&bL`xIhI4vij-vKAhrGlROmHQ)T3ooRhMZ2oMK*6 zK*lrh3GsmP50Y`ppa=kogW?m}IFRumakS*3;xhd}0H>JL6p%F_d5|-a%u{KYt`Nv6 zRzDSF9!MVKEF^hVP*wqngVGI>eN#d9fW$%WL{hJ&0|`$aP&z_Z4@#CG^&od5tA`}4 z>7_xOf>KjKmVgw2(lWB5HPbHyfgA}klz~r(7gRYR%R@cK3rao6mO=xI7p-tohZY{Z zpu~fuej3Q_AoD?mERy-^5YN^N@q$thvIdZaAPu18j;tXDWD=hcFIwp|4P+rmJ;)=- z>Oty2;-GARY(B^#AaQW0)gw}&`W2`JARi)Y067Gt0Td!g7HB|A4PH>lBC7{Egn>_p z4=tH#xIoP310@TX`cwu6hG`&|fHZ)D1la;;KH>xAKbQuPdXPgv>e14j2DBjH1EmWj z_0uJ$7ld+(d1<_XIslX&k>x@5g3JSj7?S;(Dp2*H{EDnTVpDaxStw z$R3b5C?O!(rv(iTeo!zWshOmd{iG$)BSv|-?kT^&lSv@E|K;qy8hE!h809nYuCnNy!36cgK zXdV9OOP^$ zEI*w;np3>q78?ITAnTE(LB@fcgXUdBXqhC0=H1yK<3Z}tvZN6-;R%6)0oiKLB^2p?khC?lh!+OcK`7GuV>rd@Z9stz(v9ZbIiTbO5(gEfu-IZ? zV6cG(n=mLCkd1?QS4afZ5JOfEHAe(gFd?f41v@DHi+~(}q`?we#fgAI1z7{gAq;#% zBA`%0R{sT*&iI5xK=F*EelEx%AoZYpgrwdIWG+Y?9GajGCUpFCF32Gu36P7CH9#X? z1TB2$dQ5*1%PCfG1qwNkKC}Ry3$hp_4)Q6IdDbv{K>Cm!46+xb9^_GE_0S9}f)?U) zAt4?uBnt8=vIdBRkSJP^&jmSzflo*jLNo6Z`~DadIK zt;j^D^QUo&ONyeEYUa?El<0JOurw&kAX#DF0(H{#{4`E+E%0gyWNB!-KonGnBfDV6 z^a=5tVwUF6JS2)11@k~r&cG)m1~MJVJPT;oRBZZxkZZ(1MK`jv3`jknkl1wnbWU+C zF;KW8OG7)VVj%w`yXMDqg#=EqdJCv$#6asO!Z*2@+X7C>?;* zgTft2y(P?fpoEXC9#XJRZ%yD7w6p}TU*Z!I1J&oqia?10WGE;RA{lB5$~_?Q>HZm< z;`L&nG>0VZ0P+h+8k9znje}+iF;L7Ps|Q6eNIhDuJ|C1WK;od7LQ-!J@(V~DQc7#V zcahJB8YB)%%t#s>pc=%d^Jj93ONxWiE|Ro8D3dbq35id)&*T)>5(h;UvNSYdh=YO* z$vX=erWYh~igDV4oDJ4KAFLe|Gf3JUKnVsU4azCV+6|^JNaPgDv;*ZtkUS`KkmX_G zph!V7&kmY0z}H?Qs|TeNkU1ddBC7}SLE_WnvpB`;#X*sREDcI9AZfG`YymWm#X*6C zq~0Fp9Z;koTMtSj417WoXkl*$4IK%PvzZwXw{tH5IRvBulyZ?Qu!Xu;0+f@GEqF0~ zLK3G~kUcb9BtWSQNq!;7Vvu>Da6mH85fpwPaZtPLo!%0g}3fpy&sw1BEJ*z0M#{gTz6eMN+>A6q_J%P%1}O53>&x z#>ncSu`CG*+ZhS!!XbFBXD9S@ZM;z`!RY4T=&_D5L8G)d)x)TnNg+AoZY3fz2FHjCf&sP#O{=h{U`El$JmS zff6G&gFv3xiNzqa7+DMsD?TAf99XlLLPW4JN>KryFSJp)>Za)6>4B##!N9H0yb5=RSB4v0I%7(g+BzYLLCl}eIRj22qV%Z2gqQM1X>Vtf^!m|7$c}CL9&1oqzjOhhnc~CWlB+m)+c*XPuV0lo+LXzhKxeMfuj_DV`@}LZg zED!VWjA>;c>p}Su?mq?wZfFEC?wD=>mIv{Xv~z=;12X=^^aQXxD2pJ;bAcijB!6T2 z1h70P0+HmoVZrob`T?*!$UDgL(0F1JnEnAI&jgA`Bzf>yHv^v-lfra`a!xTR@X|PB zd8qf89Hs|=Osi~*&K*J1v@|) zotXjAlL3#&fHa^bAn?cwNPN0}C8xM#2PpoL%ma^`fTiOrImPQcLD7vY4M|>tooLxn z1mr9RKEX~<@dj7&dC2NPt_7(F1rM@!L_p~rBmvThtO4r(>@1 zoZ^z5ATF{rDEWf4P4@>$cY*RSk~DZsgn>`6YkGYZr?^)asO&(N2Kf>s4T?l$aZqG} z#6e{PvN%W`1D_ZR!}JGLoMKEY3hh6tINN_zac%!m#m(*tp8scHU@*S5o#O!a0)goV zFL3YKKJ6lR71wsHJKPHxr*q!pmY**6l$&q*+q>MABITJWB^e4@3dPAqsi}FoDX9e| z8QTl)aT_zU87SDh_;XEv_lR3c6UknK8MUXseZ(!zsJorz5w{TI^prQ;qT3Z8bN4fWm}1lSJmroBu|&74JmaD|2i?R;Oj zxAT4Bxsc2y07@GS3=9GZ(*;)X%4}ze;JwbnmYG+UT2wM!`vtc`bXrkjZmMolXE`68XC^1+=;o&8<`-~*U3VdcS6(3_ zIWZ?k7h>GNK5D{r??<1JvE&ar`)Z~MM<-h(}ikES<# w;a$p|k)NBYUtC#SlA1f+^c$}ZTT*78zMkH8|F67?%+r&*c?DTMbzhVP0Lrn|Qvd(} diff --git a/roms/SLOF b/roms/SLOF index 7d766a3ac9..811277ac91 160000 --- a/roms/SLOF +++ b/roms/SLOF @@ -1 +1 @@ -Subproject commit 7d766a3ac9b2474f6c7da0084d43590cbbf047bf +Subproject commit 811277ac91f674a9273e2b529791e9b75350f3e8 From 22419c2a90b859dcab49f9472259ad8a3ce091d6 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 8 Sep 2015 11:21:31 +1000 Subject: [PATCH 14/36] pseries: Fix incorrect calculation of threads per socket for chip-id The device tree presented to pseries machine type guests includes an ibm,chip-id property which gives essentially the socket number of each vcpu core (individual vcpu threads don't get a node in the device tree). To calculate this, it uses a vcpus_per_socket variable computed as (smp_cpus / #sockets). This is correct for the usual case where smp_cpus == smp_threads * smp_cores * #sockets. However, you can start QEMU with the number of cores and threads mismatching the total number of vcpus (whether that _should_ be permitted is a topic for another day). It's a bit hard to say what the "real" number of vcpus per socket here is, but for most purposes (smp_threads * smp_cores) will more meaningfully match how QEMU behaves with respect to socket boundaries. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index a69d7e4754..ac0d2fe892 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -630,9 +630,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, 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 vcpus_per_socket = smp_threads * smp_cores; uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)}; _FDT((fdt_setprop_cell(fdt, offset, "reg", index))); @@ -701,7 +699,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, } _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id", - cs->cpu_index / cpus_per_socket))); + cs->cpu_index / vcpus_per_socket))); _FDT((fdt_setprop(fdt, offset, "ibm,pft-size", pft_size_prop, sizeof(pft_size_prop)))); From ef9971dd69bdd84b0987b0e1e4f421223b080afd Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Tue, 8 Sep 2015 11:25:13 +1000 Subject: [PATCH 15/36] spapr: Enable in-kernel H_SET_MODE handling For setting debug watchpoints, sPAPR guests use H_SET_MODE hypercall. The existing QEMU H_SET_MODE handler does not support this but the KVM handler in HV KVM does. However it is not enabled. This enables the in-kernel H_SET_MODE handler which handles: - Completed Instruction Address Breakpoint Register - Watch point 0 registers. The rest is still handled in QEMU. Reported-by: Anton Blanchard Signed-off-by: Alexey Kardashevskiy Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 1 + target-ppc/kvm.c | 5 +++++ target-ppc/kvm_ppc.h | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index ac0d2fe892..d49f322fcc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1546,6 +1546,7 @@ static void ppc_spapr_init(MachineState *machine) if (kvm_enabled()) { /* Enable H_LOGICAL_CI_* so SLOF can talk to in-kernel devices */ kvmppc_enable_logical_ci_hcalls(); + kvmppc_enable_set_mode_hcall(); } /* allocate RAM */ diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 110436d088..9cf5308ac3 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -1953,6 +1953,11 @@ void kvmppc_enable_logical_ci_hcalls(void) kvmppc_enable_hcall(kvm_state, H_LOGICAL_CI_STORE); } +void kvmppc_enable_set_mode_hcall(void) +{ + kvmppc_enable_hcall(kvm_state, H_SET_MODE); +} + void kvmppc_set_papr(PowerPCCPU *cpu) { CPUState *cs = CPU(cpu); diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 5c1d334ae0..f790d50e51 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -23,6 +23,7 @@ int kvmppc_get_hasidle(CPUPPCState *env); int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len); int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level); void kvmppc_enable_logical_ci_hcalls(void); +void kvmppc_enable_set_mode_hcall(void); void kvmppc_set_papr(PowerPCCPU *cpu); int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version); void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy); @@ -110,6 +111,10 @@ static inline void kvmppc_enable_logical_ci_hcalls(void) { } +static inline void kvmppc_enable_set_mode_hcall(void) +{ +} + static inline void kvmppc_set_papr(PowerPCCPU *cpu) { } From a8ad731a001d41582c9cec4015f73ab3bc11a28d Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Tue, 15 Sep 2015 16:34:59 -0500 Subject: [PATCH 16/36] spapr_pci: fix device tree props for MSI/MSI-X PAPR requires ibm,req#msi and ibm,req#msi-x to be present in the device node to define the number of msi/msi-x interrupts the device supports, respectively. Currently we have ibm,req#msi-x hardcoded to a non-sensical constant that happens to be 2, and are missing ibm,req#msi entirely. The result of that is that msi-x capable devices get limited to 2 msi-x interrupts (which can impact performance), and msi-only devices likely wouldn't work at all. Additionally, if devices expect a minimum that exceeds 2, the guest driver may fail to load entirely. SLOF still owns the generation of these properties at boot-time (although other device properties have since been offloaded to QEMU), but for hotplugged devices we rely on the values generated by QEMU and thus hit the limitations above. Fix this by generating these properties in QEMU as expected by guests. In the future it may make sense to modify SLOF to pass through these values directly as we do with other props since we're duplicating SLOF code. Cc: qemu-ppc@nongnu.org Cc: qemu-stable@nongnu.org Cc: David Gibson Cc: Nikunj A Dadhania Signed-off-by: Michael Roth Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 54292c9d81..d2188c854d 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -957,6 +957,7 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, int pci_status, err; char *buf = NULL; uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev); + uint32_t max_msi, max_msix; if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) == PCI_HEADER_TYPE_BRIDGE) { @@ -1037,8 +1038,15 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, RESOURCE_CELLS_ADDRESS)); _FDT(fdt_setprop_cell(fdt, offset, "#size-cells", RESOURCE_CELLS_SIZE)); - _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi-x", - RESOURCE_CELLS_SIZE)); + + max_msi = msi_nr_vectors_allocated(dev); + if (max_msi) { + _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi", max_msi)); + } + max_msix = dev->msix_entries_nr; + if (max_msix) { + _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi-x", max_msix)); + } populate_resource_props(dev, &rp); _FDT(fdt_setprop(fdt, offset, "reg", (uint8_t *)rp.reg, rp.reg_len)); From 9d1852ce11c888e3ad5096be505d14045d8b49ae Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Thu, 10 Sep 2015 16:11:03 -0500 Subject: [PATCH 17/36] spapr_drc: don't allow 'empty' DRCs to be unisolated or allocated Logical resources start with allocation-state:UNUSABLE / isolation-state:ISOLATED. During hotplug, guests will transition them to allocation-state:USABLE, and then to isolation-state:UNISOLATED. For cases where we cannot transition to allocation-state:USABLE, in this case due to no device/resource being association with the logical DRC, we should return an error -3. For physical DRCs, we default to allocation-state:USABLE and stay there, so in this case we should report an error -3 when the guest attempts to make the isolation-state:ISOLATED transition for a DRC with no device associated. These are as documented in PAPR 2.7, 13.5.3.4. We also ensure allocation-state:USABLE when the guest attempts transition to isolation-state:UNISOLATED to deal with misbehaving guests attempting to bring online an unallocated logical resource. This is as documented in PAPR 2.7, 13.7. Currently we implement no such error logic. Fix this by handling these error cases as PAPR defines. Cc: Bharata B Rao Signed-off-by: Michael Roth Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 21 +++++++++++++++++++++ include/hw/ppc/spapr.h | 1 + 2 files changed, 22 insertions(+) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 9ce844ab1e..faf8760d2e 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -66,6 +66,16 @@ static int set_isolation_state(sPAPRDRConnector *drc, DPRINTFN("drc: %x, set_isolation_state: %x", get_index(drc), state); + if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) { + /* cannot unisolate a non-existant resource, and, or resources + * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 13.5.3.5) + */ + if (!drc->dev || + drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) { + return RTAS_OUT_NO_SUCH_INDICATOR; + } + } + drc->isolation_state = state; if (drc->isolation_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) { @@ -107,6 +117,17 @@ static int set_allocation_state(sPAPRDRConnector *drc, DPRINTFN("drc: %x, set_allocation_state: %x", get_index(drc), state); + if (state == SPAPR_DR_ALLOCATION_STATE_USABLE) { + /* if there's no resource/device associated with the DRC, there's + * no way for us to put it in an allocation state consistent with + * being 'USABLE'. PAPR 2.7, 13.5.3.4 documents that this should + * result in an RTAS return code of -3 / "no such indicator" + */ + if (!drc->dev) { + return RTAS_OUT_NO_SUCH_INDICATOR; + } + } + if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI) { drc->allocation_state = state; if (drc->awaiting_release && diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index cbe3463e32..8a0a74d5d9 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -409,6 +409,7 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi); #define RTAS_OUT_BUSY -2 #define RTAS_OUT_PARAM_ERROR -3 #define RTAS_OUT_NOT_SUPPORTED -3 +#define RTAS_OUT_NO_SUCH_INDICATOR -3 #define RTAS_OUT_NOT_AUTHORIZED -9002 /* RTAS tokens */ From 4a1c9cf0073e733b421e7b82ad673e7cf6ed8454 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Mon, 29 Jun 2015 14:14:27 +0530 Subject: [PATCH 18/36] spapr: Initialize hotplug memory address space Initialize a hotplug memory region under which all the hotplugged memory is accommodated. Also enable memory hotplug by setting CONFIG_MEM_HOTPLUG. Modelled on i386 memory hotplug. Signed-off-by: Bharata B Rao Reviewed-by: David Gibson Signed-off-by: David Gibson --- default-configs/ppc64-softmmu.mak | 1 + hw/ppc/spapr.c | 18 ++++++++++++++++++ include/hw/ppc/spapr.h | 12 ++++++++++++ 3 files changed, 31 insertions(+) diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index ab62cc7ff0..e77cb1ac54 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -52,3 +52,4 @@ CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM)) # For PReP CONFIG_MC146818RTC=y CONFIG_ISA_TESTDEV=y +CONFIG_MEM_HOTPLUG=y diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d49f322fcc..2fb5e3643c 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1562,6 +1562,24 @@ static void ppc_spapr_init(MachineState *machine) memory_region_add_subregion(sysmem, 0, rma_region); } + /* initialize hotplug memory address space */ + if (machine->ram_size < machine->maxram_size) { + ram_addr_t hotplug_mem_size = machine->maxram_size - machine->ram_size; + + if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) { + error_report("unsupported amount of memory slots: %"PRIu64, + machine->ram_slots); + exit(EXIT_FAILURE); + } + + spapr->hotplug_memory.base = ROUND_UP(machine->ram_size, + SPAPR_HOTPLUG_MEM_ALIGN); + memory_region_init(&spapr->hotplug_memory.mr, OBJECT(spapr), + "hotplug-memory", hotplug_mem_size); + memory_region_add_subregion(sysmem, spapr->hotplug_memory.base, + &spapr->hotplug_memory.mr); + } + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin"); if (!filename) { error_report("Could not find LPAR rtas '%s'", "spapr-rtas.bin"); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 8a0a74d5d9..e882770db7 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -5,6 +5,7 @@ #include "hw/boards.h" #include "hw/ppc/xics.h" #include "hw/ppc/spapr_drc.h" +#include "hw/mem/pc-dimm.h" struct VIOsPAPRBus; struct sPAPRPHBState; @@ -76,6 +77,7 @@ struct sPAPRMachineState { /*< public >*/ char *kvm_type; + MemoryHotplugState hotplug_memory; }; #define H_SUCCESS 0 @@ -610,4 +612,14 @@ int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset); #define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */ +/* + * This defines the maximum number of DIMM slots we can have for sPAPR + * guest. This is not defined by sPAPR but we are defining it to 32 slots + * based on default number of slots provided by PowerPC kernel. + */ +#define SPAPR_MAX_RAM_SLOTS 32 + +/* 1GB alignment for hotplug memory region */ +#define SPAPR_HOTPLUG_MEM_ALIGN (1ULL << 30) + #endif /* !defined (__HW_SPAPR_H__) */ From 0cb688d22b3941af02fee78ba21dc3a39c367e0b Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Thu, 10 Sep 2015 16:11:02 -0500 Subject: [PATCH 19/36] spapr_drc: use RTAS return codes for methods called by RTAS Certain methods in sPAPRDRConnector objects are only ever called by RTAS and in many cases are responsible for the logic that determines the RTAS return codes. Rather than having a level of indirection requiring RTAS code to re-interpret return values from such methods to determine the appropriate return code, just pass them through directly. This requires changing method return types to uint32_t to match the type of values currently passed to RTAS helpers. In the case of read accesses like drc->entity_sense() where we weren't previously reporting any errors, just the read value, we modify the function to return RTAS return code, and pass the read value back via reference. Suggested-by: Bharata B Rao Suggested-by: David Gibson Cc: Bharata B Rao Signed-off-by: Michael Roth Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 37 ++++++++++++++++++----------------- hw/ppc/spapr_rtas.c | 40 +++++++++++++++++++++----------------- include/hw/ppc/spapr_drc.h | 14 ++++++------- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index faf8760d2e..b7b9891714 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -15,6 +15,7 @@ #include "hw/qdev.h" #include "qapi/visitor.h" #include "qemu/error-report.h" +#include "hw/ppc/spapr.h" /* for RTAS return codes */ /* #define DEBUG_SPAPR_DRC */ @@ -59,8 +60,8 @@ static uint32_t get_index(sPAPRDRConnector *drc) (drc->id & DRC_INDEX_ID_MASK); } -static int set_isolation_state(sPAPRDRConnector *drc, - sPAPRDRIsolationState state) +static uint32_t set_isolation_state(sPAPRDRConnector *drc, + sPAPRDRIsolationState state) { sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); @@ -99,19 +100,19 @@ static int set_isolation_state(sPAPRDRConnector *drc, drc->configured = false; } - return 0; + return RTAS_OUT_SUCCESS; } -static int set_indicator_state(sPAPRDRConnector *drc, - sPAPRDRIndicatorState state) +static uint32_t set_indicator_state(sPAPRDRConnector *drc, + sPAPRDRIndicatorState state) { DPRINTFN("drc: %x, set_indicator_state: %x", get_index(drc), state); drc->indicator_state = state; - return 0; + return RTAS_OUT_SUCCESS; } -static int set_allocation_state(sPAPRDRConnector *drc, - sPAPRDRAllocationState state) +static uint32_t set_allocation_state(sPAPRDRConnector *drc, + sPAPRDRAllocationState state) { sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); @@ -137,7 +138,7 @@ static int set_allocation_state(sPAPRDRConnector *drc, drc->detach_cb_opaque, NULL); } } - return 0; + return RTAS_OUT_SUCCESS; } static uint32_t get_type(sPAPRDRConnector *drc) @@ -178,10 +179,8 @@ static void set_configured(sPAPRDRConnector *drc) * based on the current allocation/indicator/power states * for the DR connector. */ -static sPAPRDREntitySense entity_sense(sPAPRDRConnector *drc) +static uint32_t entity_sense(sPAPRDRConnector *drc, sPAPRDREntitySense *state) { - sPAPRDREntitySense state; - if (drc->dev) { if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI && drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) { @@ -190,7 +189,7 @@ static sPAPRDREntitySense entity_sense(sPAPRDRConnector *drc) * Otherwise, report the state as USABLE/PRESENT, * as we would for PCI. */ - state = SPAPR_DR_ENTITY_SENSE_UNUSABLE; + *state = SPAPR_DR_ENTITY_SENSE_UNUSABLE; } else { /* this assumes all PCI devices are assigned to * a 'live insertion' power domain, where QEMU @@ -198,21 +197,21 @@ static sPAPRDREntitySense entity_sense(sPAPRDRConnector *drc) * to the guest. present, non-PCI resources are * unaffected by power state. */ - state = SPAPR_DR_ENTITY_SENSE_PRESENT; + *state = SPAPR_DR_ENTITY_SENSE_PRESENT; } } else { if (drc->type == SPAPR_DR_CONNECTOR_TYPE_PCI) { /* PCI devices, and only PCI devices, use EMPTY * in cases where we'd otherwise use UNUSABLE */ - state = SPAPR_DR_ENTITY_SENSE_EMPTY; + *state = SPAPR_DR_ENTITY_SENSE_EMPTY; } else { - state = SPAPR_DR_ENTITY_SENSE_UNUSABLE; + *state = SPAPR_DR_ENTITY_SENSE_UNUSABLE; } } DPRINTFN("drc: %x, entity_sense: %x", get_index(drc), state); - return state; + return RTAS_OUT_SUCCESS; } static void prop_get_index(Object *obj, Visitor *v, void *opaque, @@ -245,7 +244,9 @@ static void prop_get_entity_sense(Object *obj, Visitor *v, void *opaque, { sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj); sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); - uint32_t value = (uint32_t)drck->entity_sense(drc); + uint32_t value; + + drck->entity_sense(drc, &value); visit_type_uint32(v, &value, name, errp); } diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 2f8e25cfb2..34b12a3b99 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -372,12 +372,13 @@ static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t sensor_type; uint32_t sensor_index; uint32_t sensor_state; + uint32_t ret = RTAS_OUT_SUCCESS; sPAPRDRConnector *drc; sPAPRDRConnectorClass *drck; if (nargs != 3 || nret != 1) { - rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); - return; + ret = RTAS_OUT_PARAM_ERROR; + goto out; } sensor_type = rtas_ld(args, 0); @@ -393,8 +394,8 @@ static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr, if (!drc) { DPRINTF("rtas_set_indicator: invalid sensor/DRC index: %xh\n", sensor_index); - rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); - return; + ret = RTAS_OUT_PARAM_ERROR; + goto out; } drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); @@ -413,19 +414,20 @@ static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr, spapr_ccs_remove(spapr, ccs); } } - drck->set_isolation_state(drc, sensor_state); + ret = drck->set_isolation_state(drc, sensor_state); break; case RTAS_SENSOR_TYPE_DR: - drck->set_indicator_state(drc, sensor_state); + ret = drck->set_indicator_state(drc, sensor_state); break; case RTAS_SENSOR_TYPE_ALLOCATION_STATE: - drck->set_allocation_state(drc, sensor_state); + ret = drck->set_allocation_state(drc, sensor_state); break; default: goto out_unimplemented; } - rtas_st(rets, 0, RTAS_OUT_SUCCESS); +out: + rtas_st(rets, 0, ret); return; out_unimplemented: @@ -442,13 +444,14 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr, { uint32_t sensor_type; uint32_t sensor_index; + uint32_t sensor_state = 0; sPAPRDRConnector *drc; sPAPRDRConnectorClass *drck; - uint32_t entity_sense; + uint32_t ret = RTAS_OUT_SUCCESS; if (nargs != 2 || nret != 2) { - rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); - return; + ret = RTAS_OUT_PARAM_ERROR; + goto out; } sensor_type = rtas_ld(args, 0); @@ -458,22 +461,23 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr, /* currently only DR-related sensors are implemented */ DPRINTF("rtas_get_sensor_state: sensor/indicator not implemented: %d\n", sensor_type); - rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED); - return; + ret = RTAS_OUT_NOT_SUPPORTED; + goto out; } drc = spapr_dr_connector_by_index(sensor_index); if (!drc) { DPRINTF("rtas_get_sensor_state: invalid sensor/DRC index: %xh\n", sensor_index); - rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); - return; + ret = RTAS_OUT_PARAM_ERROR; + goto out; } drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); - entity_sense = drck->entity_sense(drc); + ret = drck->entity_sense(drc, &sensor_state); - rtas_st(rets, 0, RTAS_OUT_SUCCESS); - rtas_st(rets, 1, entity_sense); +out: + rtas_st(rets, 0, ret); + rtas_st(rets, 1, sensor_state); } /* configure-connector work area offsets, int32_t units for field diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h index 28ffeaeb1c..7e5634772c 100644 --- a/include/hw/ppc/spapr_drc.h +++ b/include/hw/ppc/spapr_drc.h @@ -165,17 +165,17 @@ typedef struct sPAPRDRConnectorClass { /*< public >*/ /* accessors for guest-visible (generally via RTAS) DR state */ - int (*set_isolation_state)(sPAPRDRConnector *drc, - sPAPRDRIsolationState state); - int (*set_indicator_state)(sPAPRDRConnector *drc, - sPAPRDRIndicatorState state); - int (*set_allocation_state)(sPAPRDRConnector *drc, - sPAPRDRAllocationState state); + uint32_t (*set_isolation_state)(sPAPRDRConnector *drc, + sPAPRDRIsolationState state); + uint32_t (*set_indicator_state)(sPAPRDRConnector *drc, + sPAPRDRIndicatorState state); + uint32_t (*set_allocation_state)(sPAPRDRConnector *drc, + sPAPRDRAllocationState state); uint32_t (*get_index)(sPAPRDRConnector *drc); uint32_t (*get_type)(sPAPRDRConnector *drc); const char *(*get_name)(sPAPRDRConnector *drc); - sPAPRDREntitySense (*entity_sense)(sPAPRDRConnector *drc); + uint32_t (*entity_sense)(sPAPRDRConnector *drc, sPAPRDREntitySense *state); /* QEMU interfaces for managing FDT/configure-connector */ const void *(*get_fdt)(sPAPRDRConnector *drc, int *fdt_start_offset); From 94649d423e4647fca3bc3e8b2b363d6d2adee9ce Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 16 Sep 2015 16:57:51 +1000 Subject: [PATCH 20/36] spapr: Don't use QOM [*] syntax for DR connectors. The dynamic reconfiguration (hotplug) code for the pseries machine type uses a "DR connector" QOM object for each resource it will be possible to hotplug. Each of these is added to its owner using object_property_add_child(owner, "dr-connector[*], ...); That works ok, mostly, but it means that the property indices are arbitrary, depending on the order in which the connectors are constructed. That might line up to something useful, but it doesn't have to. It will get worse once we add hotplug RAM support. That will add a DR connector object for every 256MB of potential memory. So if maxmem=2T, for example, there are 8192 objects under the same parent. The QOM interfaces aren't really designed for this. In particular object_property_add() with [*] has O(n^2) time complexity (in the number of existing children): first it has a linear search through array indices to find a free slot, each of which is attempted to a recursive call to object_property_add() with a specific [N]. Those calls are O(n) because there's a linear search through all properties to check for duplicates. By using a meaningful index value, which we already know is unique we can avoid the [*] special behaviour. That lets us reduce the total time for creating the DR objects from O(n^3) to O(n^2). O(n^2) is still kind of crappy, but it's enough to reduce the startup time of qemu (with in-progress memory hotplug support) with maxmem=2T from ~20 minutes to ~4 seconds. Signed-off-by: David Gibson Cc: Bharata B Rao Tested-by: Bharata B Rao Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr_drc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index b7b9891714..5d6ea7ce41 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -473,14 +473,17 @@ sPAPRDRConnector *spapr_dr_connector_new(Object *owner, { sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(object_new(TYPE_SPAPR_DR_CONNECTOR)); + char *prop_name; g_assert(type); drc->type = type; drc->id = id; drc->owner = owner; - object_property_add_child(owner, "dr-connector[*]", OBJECT(drc), NULL); + prop_name = g_strdup_printf("dr-connector[%"PRIu32"]", get_index(drc)); + object_property_add_child(owner, prop_name, OBJECT(drc), NULL); object_property_set_bool(OBJECT(drc), true, "realized", NULL); + g_free(prop_name); /* human-readable name for a DRC to encode into the DT * description. this is mainly only used within a guest in place From 38b02bd846672f33bc2eabcb9847c4b78069e097 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Thu, 6 Aug 2015 13:37:24 +1000 Subject: [PATCH 21/36] spapr: Use QEMU limit for maximum CPUs number sPAPR uses hard coded limit of maximum 255 supported CPUs which is exactly the same as QEMU-wide limit which is MAX_CPUMASK_BITS and also defined as 255. This makes use of a global CPU number limit for the "pseries" machine. In order to anticipate future increase of the MAX_CPUMASK_BITS (or to help debugging large systems), this also bumps the FDT_MAX_SIZE limit from 256K to 1M assuming that 1 CPU core needs roughly 512 bytes in the device tree so the new limit can cover up to 2048 CPU cores. Signed-off-by: Alexey Kardashevskiy Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 2fb5e3643c..33e22cea65 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -74,7 +74,7 @@ * * We load our kernel at 4M, leaving space for SLOF initial image */ -#define FDT_MAX_SIZE 0x40000 +#define FDT_MAX_SIZE 0x100000 #define RTAS_MAX_SIZE 0x10000 #define RTAS_MAX_ADDR 0x80000000 /* RTAS must stay below that */ #define FW_MAX_SIZE 0x400000 @@ -86,8 +86,6 @@ #define TIMEBASE_FREQ 512000000ULL -#define MAX_CPUS 255 - #define PHANDLE_XICP 0x00001111 #define HTAB_SIZE(spapr) (1ULL << ((spapr)->htab_shift)) @@ -1859,7 +1857,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->init = ppc_spapr_init; mc->reset = ppc_spapr_reset; mc->block_default_type = IF_SCSI; - mc->max_cpus = MAX_CPUS; + mc->max_cpus = MAX_CPUMASK_BITS; mc->no_parallel = 1; mc->default_boot_order = ""; mc->default_ram_size = 512 * M_BYTE; From 224245bf524189789d231f38434c9f8fd57a249c Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 12 Aug 2015 13:16:48 +1000 Subject: [PATCH 22/36] spapr: Add LMB DR connectors Enable memory hotplug for pseries 2.4 and add LMB DR connectors. With memory hotplug, enforce RAM size, NUMA node memory size and maxmem to be a multiple of SPAPR_MEMORY_BLOCK_SIZE (256M) since that's the granularity in which LMBs are represented and hot-added. LMB DR connectors will be used by the memory hotplug code. Signed-off-by: Bharata B Rao Signed-off-by: Michael Roth [spapr_drc_reset implementation] [since this missed the 2.4 cutoff, changing to only enable for 2.5] Signed-off-by: David Gibson --- hw/ppc/spapr.c | 87 ++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 1 + 2 files changed, 88 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 33e22cea65..940a82fc71 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -61,6 +61,7 @@ #include "hw/nmi.h" #include "hw/compat.h" +#include "qemu-common.h" #include @@ -1446,10 +1447,84 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu) qemu_register_reset(spapr_cpu_reset, cpu); } +/* + * Reset routine for LMB DR devices. + * + * Unlike PCI DR devices, LMB DR devices explicitly register this reset + * routine. Reset for PCI DR devices will be handled by PHB reset routine + * when it walks all its children devices. LMB devices reset occurs + * as part of spapr_ppc_reset(). + */ +static void spapr_drc_reset(void *opaque) +{ + sPAPRDRConnector *drc = opaque; + DeviceState *d = DEVICE(drc); + + if (d) { + device_reset(d); + } +} + +static void spapr_create_lmb_dr_connectors(sPAPRMachineState *spapr) +{ + MachineState *machine = MACHINE(spapr); + uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; + uint32_t nr_rma_lmbs = spapr->rma_size/lmb_size; + uint32_t nr_lmbs = machine->maxram_size/lmb_size - nr_rma_lmbs; + uint32_t nr_assigned_lmbs = machine->ram_size/lmb_size - nr_rma_lmbs; + int i; + + for (i = 0; i < nr_lmbs; i++) { + sPAPRDRConnector *drc; + uint64_t addr; + + if (i < nr_assigned_lmbs) { + addr = (i + nr_rma_lmbs) * lmb_size; + } else { + addr = (i - nr_assigned_lmbs) * lmb_size + + spapr->hotplug_memory.base; + } + drc = spapr_dr_connector_new(OBJECT(spapr), SPAPR_DR_CONNECTOR_TYPE_LMB, + addr/lmb_size); + qemu_register_reset(spapr_drc_reset, drc); + } +} + +/* + * If RAM size, maxmem size and individual node mem sizes aren't aligned + * to SPAPR_MEMORY_BLOCK_SIZE(256MB), then refuse to start the guest + * since we can't support such unaligned sizes with DRCONF_MEMORY. + */ +static void spapr_validate_node_memory(MachineState *machine) +{ + int i; + + if (machine->maxram_size % SPAPR_MEMORY_BLOCK_SIZE || + machine->ram_size % SPAPR_MEMORY_BLOCK_SIZE) { + error_report("Can't support memory configuration where RAM size " + "0x" RAM_ADDR_FMT " or maxmem size " + "0x" RAM_ADDR_FMT " isn't aligned to %llu MB", + machine->ram_size, machine->maxram_size, + SPAPR_MEMORY_BLOCK_SIZE/M_BYTE); + exit(EXIT_FAILURE); + } + + for (i = 0; i < nb_numa_nodes; i++) { + if (numa_info[i].node_mem % SPAPR_MEMORY_BLOCK_SIZE) { + error_report("Can't support memory configuration where memory size" + " %" PRIx64 " of node %d isn't aligned to %llu MB", + numa_info[i].node_mem, i, + SPAPR_MEMORY_BLOCK_SIZE/M_BYTE); + exit(EXIT_FAILURE); + } + } +} + /* pSeries LPAR / sPAPR hardware init */ static void ppc_spapr_init(MachineState *machine) { sPAPRMachineState *spapr = SPAPR_MACHINE(machine); + sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; @@ -1528,6 +1603,10 @@ static void ppc_spapr_init(MachineState *machine) smp_threads), XICS_IRQS); + if (smc->dr_lmb_enabled) { + spapr_validate_node_memory(machine); + } + /* init CPUs */ if (machine->cpu_model == NULL) { machine->cpu_model = kvm_enabled() ? "host" : "POWER7"; @@ -1578,6 +1657,10 @@ static void ppc_spapr_init(MachineState *machine) &spapr->hotplug_memory.mr); } + if (smc->dr_lmb_enabled) { + spapr_create_lmb_dr_connectors(spapr); + } + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin"); if (!filename) { error_report("Could not find LPAR rtas '%s'", "spapr-rtas.bin"); @@ -1851,6 +1934,7 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp) static void spapr_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc); FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); NMIClass *nc = NMI_CLASS(oc); @@ -1865,6 +1949,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->has_dynamic_sysbus = true; mc->pci_allow_0_address = true; + smc->dr_lmb_enabled = false; fwc->get_dev_path = spapr_get_fw_dev_path; nc->nmi_monitor_handler = spapr_nmi; } @@ -2014,11 +2099,13 @@ static const TypeInfo spapr_machine_2_4_info = { static void spapr_machine_2_5_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc); mc->name = "pseries-2.5"; mc->desc = "pSeries Logical Partition (PAPR compliant) v2.5"; mc->alias = "pseries"; mc->is_default = 1; + smc->dr_lmb_enabled = true; } static const TypeInfo spapr_machine_2_5_info = { diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index e882770db7..5de54d4a93 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -35,6 +35,7 @@ struct sPAPRMachineClass { MachineClass parent_class; /*< public >*/ + bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */ }; /** From 03d196b7c57f22f796197f221f9d95336debee9e Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Mon, 13 Jul 2015 10:34:00 +1000 Subject: [PATCH 23/36] spapr: Support ibm,dynamic-reconfiguration-memory Parse ibm,architecture.vec table obtained from the guest and enable memory node configuration via ibm,dynamic-reconfiguration-memory if guest supports it. This is in preparation to support memory hotplug for sPAPR guests. This changes the way memory node configuration is done. Currently all memory nodes are built upfront. But after this patch, only memory@0 node for RMA is built upfront. Guest kernel boots with just that and rest of the memory nodes (via memory@XXX or ibm,dynamic-reconfiguration-memory) are built when guest does ibm,client-architecture-support call. Note: This patch needs a SLOF enhancement which is already part of SLOF binary in QEMU. Signed-off-by: Bharata B Rao Reviewed-by: David Gibson Signed-off-by: David Gibson --- docs/specs/ppc-spapr-hotplug.txt | 48 +++++++ hw/ppc/spapr.c | 210 ++++++++++++++++++++++++------- hw/ppc/spapr_hcall.c | 51 +++++++- include/hw/ppc/spapr.h | 15 ++- 4 files changed, 274 insertions(+), 50 deletions(-) diff --git a/docs/specs/ppc-spapr-hotplug.txt b/docs/specs/ppc-spapr-hotplug.txt index 46e07196bb..631b0cadae 100644 --- a/docs/specs/ppc-spapr-hotplug.txt +++ b/docs/specs/ppc-spapr-hotplug.txt @@ -302,4 +302,52 @@ consisting of , and . pseries guests use this property to note the maximum allowed CPUs for the guest. +== ibm,dynamic-reconfiguration-memory == + +ibm,dynamic-reconfiguration-memory is a device tree node that represents +dynamically reconfigurable logical memory blocks (LMB). This node +is generated only when the guest advertises the support for it via +ibm,client-architecture-support call. Memory that is not dynamically +reconfigurable is represented by /memory nodes. The properties of this +node that are of interest to the sPAPR memory hotplug implementation +in QEMU are described here. + +ibm,lmb-size + +This 64bit integer defines the size of each dynamically reconfigurable LMB. + +ibm,associativity-lookup-arrays + +This property defines a lookup array in which the NUMA associativity +information for each LMB can be found. It is a property encoded array +that begins with an integer M, the number of associativity lists followed +by an integer N, the number of entries per associativity list and terminated +by M associativity lists each of length N integers. + +This property provides the same information as given by ibm,associativity +property in a /memory node. Each assigned LMB has an index value between +0 and M-1 which is used as an index into this table to select which +associativity list to use for the LMB. This index value for each LMB +is defined in ibm,dynamic-memory property. + +ibm,dynamic-memory + +This property describes the dynamically reconfigurable memory. It is a +property encoded array that has an integer N, the number of LMBs followed +by N LMB list entires. + +Each LMB list entry consists of the following elements: + +- Logical address of the start of the LMB encoded as a 64bit integer. This + corresponds to reg property in /memory node. +- DRC index of the LMB that corresponds to ibm,my-drc-index property + in a /memory node. +- Four bytes reserved for expansion. +- Associativity list index for the LMB that is used as an index into + ibm,associativity-lookup-arrays property described earlier. This + is used to retrieve the right associativity list to be used for this + LMB. +- A 32bit flags word. The bit at bit position 0x00000008 defines whether + the LMB is assigned to the the partition as of boot time. + [1] http://thread.gmane.org/gmane.linux.ports.ppc.embedded/75350/focus=106867 diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 940a82fc71..2f49f97924 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -504,44 +504,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, return fdt; } -int spapr_h_cas_compose_response(sPAPRMachineState *spapr, - target_ulong addr, target_ulong size) -{ - void *fdt, *fdt_skel; - sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 }; - - size -= sizeof(hdr); - - /* Create sceleton */ - fdt_skel = g_malloc0(size); - _FDT((fdt_create(fdt_skel, size))); - _FDT((fdt_begin_node(fdt_skel, ""))); - _FDT((fdt_end_node(fdt_skel))); - _FDT((fdt_finish(fdt_skel))); - fdt = g_malloc0(size); - _FDT((fdt_open_into(fdt_skel, fdt, size))); - g_free(fdt_skel); - - /* Fix skeleton up */ - _FDT((spapr_fixup_cpu_dt(fdt, spapr))); - - /* Pack resulting tree */ - _FDT((fdt_pack(fdt))); - - if (fdt_totalsize(fdt) + sizeof(hdr) > size) { - trace_spapr_cas_failed(size); - return -1; - } - - cpu_physical_memory_write(addr, &hdr, sizeof(hdr)); - cpu_physical_memory_write(addr + sizeof(hdr), fdt, fdt_totalsize(fdt)); - trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr)); - g_free(fdt); - - return 0; -} - -static void spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start, +static int spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start, hwaddr size) { uint32_t associativity[] = { @@ -564,6 +527,7 @@ static void spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start, sizeof(mem_reg_property)))); _FDT((fdt_setprop(fdt, off, "ibm,associativity", associativity, sizeof(associativity)))); + return off; } static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt) @@ -595,7 +559,6 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt) } if (!mem_start) { /* ppc_spapr_init() checks for rma_size <= node0_size already */ - spapr_populate_memory_node(fdt, i, 0, spapr->rma_size); mem_start += spapr->rma_size; node_size -= spapr->rma_size; } @@ -745,6 +708,154 @@ static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr) } +/* + * Adds ibm,dynamic-reconfiguration-memory node. + * Refer to docs/specs/ppc-spapr-hotplug.txt for the documentation + * of this device tree node. + */ +static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) +{ + MachineState *machine = MACHINE(spapr); + int ret, i, offset; + uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; + uint32_t prop_lmb_size[] = {0, cpu_to_be32(lmb_size)}; + uint32_t nr_rma_lmbs = spapr->rma_size/lmb_size; + uint32_t nr_lmbs = machine->maxram_size/lmb_size - nr_rma_lmbs; + uint32_t nr_assigned_lmbs = machine->ram_size/lmb_size - nr_rma_lmbs; + uint32_t *int_buf, *cur_index, buf_len; + + /* Allocate enough buffer size to fit in ibm,dynamic-memory */ + buf_len = nr_lmbs * SPAPR_DR_LMB_LIST_ENTRY_SIZE * sizeof(uint32_t) + + sizeof(uint32_t); + cur_index = int_buf = g_malloc0(buf_len); + + offset = fdt_add_subnode(fdt, 0, "ibm,dynamic-reconfiguration-memory"); + + ret = fdt_setprop(fdt, offset, "ibm,lmb-size", prop_lmb_size, + sizeof(prop_lmb_size)); + if (ret < 0) { + goto out; + } + + ret = fdt_setprop_cell(fdt, offset, "ibm,memory-flags-mask", 0xff); + if (ret < 0) { + goto out; + } + + ret = fdt_setprop_cell(fdt, offset, "ibm,memory-preservation-time", 0x0); + if (ret < 0) { + goto out; + } + + /* ibm,dynamic-memory */ + int_buf[0] = cpu_to_be32(nr_lmbs); + cur_index++; + for (i = 0; i < nr_lmbs; i++) { + sPAPRDRConnector *drc; + sPAPRDRConnectorClass *drck; + uint64_t addr; + uint32_t *dynamic_memory = cur_index; + + if (i < nr_assigned_lmbs) { + addr = (i + nr_rma_lmbs) * lmb_size; + } else { + addr = (i - nr_assigned_lmbs) * lmb_size + + spapr->hotplug_memory.base; + } + drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB, + addr/lmb_size); + g_assert(drc); + drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); + + dynamic_memory[0] = cpu_to_be32(addr >> 32); + dynamic_memory[1] = cpu_to_be32(addr & 0xffffffff); + dynamic_memory[2] = cpu_to_be32(drck->get_index(drc)); + dynamic_memory[3] = cpu_to_be32(0); /* reserved */ + dynamic_memory[4] = cpu_to_be32(numa_get_node(addr, NULL)); + if (addr < machine->ram_size || + memory_region_present(get_system_memory(), addr)) { + dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_ASSIGNED); + } else { + dynamic_memory[5] = cpu_to_be32(0); + } + + cur_index += SPAPR_DR_LMB_LIST_ENTRY_SIZE; + } + ret = fdt_setprop(fdt, offset, "ibm,dynamic-memory", int_buf, buf_len); + if (ret < 0) { + goto out; + } + + /* ibm,associativity-lookup-arrays */ + cur_index = int_buf; + int_buf[0] = cpu_to_be32(nb_numa_nodes); + int_buf[1] = cpu_to_be32(4); /* Number of entries per associativity list */ + cur_index += 2; + for (i = 0; i < nb_numa_nodes; i++) { + uint32_t associativity[] = { + cpu_to_be32(0x0), + cpu_to_be32(0x0), + cpu_to_be32(0x0), + cpu_to_be32(i) + }; + memcpy(cur_index, associativity, sizeof(associativity)); + cur_index += 4; + } + ret = fdt_setprop(fdt, offset, "ibm,associativity-lookup-arrays", int_buf, + (cur_index - int_buf) * sizeof(uint32_t)); +out: + g_free(int_buf); + return ret; +} + +int spapr_h_cas_compose_response(sPAPRMachineState *spapr, + target_ulong addr, target_ulong size, + bool cpu_update, bool memory_update) +{ + void *fdt, *fdt_skel; + sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 }; + sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(qdev_get_machine()); + + size -= sizeof(hdr); + + /* Create sceleton */ + fdt_skel = g_malloc0(size); + _FDT((fdt_create(fdt_skel, size))); + _FDT((fdt_begin_node(fdt_skel, ""))); + _FDT((fdt_end_node(fdt_skel))); + _FDT((fdt_finish(fdt_skel))); + fdt = g_malloc0(size); + _FDT((fdt_open_into(fdt_skel, fdt, size))); + g_free(fdt_skel); + + /* Fixup cpu nodes */ + if (cpu_update) { + _FDT((spapr_fixup_cpu_dt(fdt, spapr))); + } + + /* Generate memory nodes or ibm,dynamic-reconfiguration-memory node */ + if (memory_update && smc->dr_lmb_enabled) { + _FDT((spapr_populate_drconf_memory(spapr, fdt))); + } else { + _FDT((spapr_populate_memory(spapr, fdt))); + } + + /* Pack resulting tree */ + _FDT((fdt_pack(fdt))); + + if (fdt_totalsize(fdt) + sizeof(hdr) > size) { + trace_spapr_cas_failed(size); + return -1; + } + + cpu_physical_memory_write(addr, &hdr, sizeof(hdr)); + cpu_physical_memory_write(addr + sizeof(hdr), fdt, fdt_totalsize(fdt)); + trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr)); + g_free(fdt); + + return 0; +} + static void spapr_finalize_fdt(sPAPRMachineState *spapr, hwaddr fdt_addr, hwaddr rtas_addr, @@ -763,10 +874,23 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr, /* open out the base tree into a temp buffer for the final tweaks */ _FDT((fdt_open_into(spapr->fdt_skel, fdt, FDT_MAX_SIZE))); - ret = spapr_populate_memory(spapr, fdt); - if (ret < 0) { - fprintf(stderr, "couldn't setup memory nodes in fdt\n"); - exit(1); + /* + * Add memory@0 node to represent RMA. Rest of the memory is either + * represented by memory nodes or ibm,dynamic-reconfiguration-memory + * node later during ibm,client-architecture-support call. + * + * If NUMA is configured, ensure that memory@0 ends up in the + * first memory-less node. + */ + if (nb_numa_nodes) { + for (i = 0; i < nb_numa_nodes; ++i) { + if (numa_info[i].node_mem) { + spapr_populate_memory_node(fdt, i, 0, spapr->rma_size); + break; + } + } + } else { + spapr_populate_memory_node(fdt, 0, 0, spapr->rma_size); } ret = spapr_populate_vdevice(spapr->vio_bus, fdt); diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 71fc9f23a1..cebceea69b 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -808,6 +808,32 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr, return ret; } +/* + * Return the offset to the requested option vector @vector in the + * option vector table @table. + */ +static target_ulong cas_get_option_vector(int vector, target_ulong table) +{ + int i; + char nr_vectors, nr_entries; + + if (!table) { + return 0; + } + + nr_vectors = (ldl_phys(&address_space_memory, table) >> 24) + 1; + if (!vector || vector > nr_vectors) { + return 0; + } + table++; /* skip nr option vectors */ + + for (i = 0; i < vector - 1; i++) { + nr_entries = ldl_phys(&address_space_memory, table) >> 24; + table += nr_entries + 2; + } + return table; +} + typedef struct { PowerPCCPU *cpu; uint32_t cpu_version; @@ -828,19 +854,22 @@ static void do_set_compat(void *arg) ((cpuver) == CPU_POWERPC_LOGICAL_2_06_PLUS) ? 2061 : \ ((cpuver) == CPU_POWERPC_LOGICAL_2_07) ? 2070 : 0) +#define OV5_DRCONF_MEMORY 0x20 + static target_ulong h_client_architecture_support(PowerPCCPU *cpu_, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { - target_ulong list = args[0]; + target_ulong list = args[0], ov_table; PowerPCCPUClass *pcc_ = POWERPC_CPU_GET_CLASS(cpu_); CPUState *cs; - bool cpu_match = false; + bool cpu_match = false, cpu_update = true, memory_update = false; unsigned old_cpu_version = cpu_->cpu_version; unsigned compat_lvl = 0, cpu_version = 0; unsigned max_lvl = get_compat_level(cpu_->max_compat); int counter; + char ov5_byte2; /* Parse PVR list */ for (counter = 0; counter < 512; ++counter) { @@ -890,8 +919,6 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu_, } } - /* For the future use: here @list points to the first capability */ - /* Parsing finished */ trace_spapr_cas_pvr(cpu_->cpu_version, cpu_match, cpu_version, pcc_->pcr_mask); @@ -915,14 +942,26 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu_, } if (!cpu_version) { - return H_SUCCESS; + cpu_update = false; } + /* For the future use: here @ov_table points to the first option vector */ + ov_table = list; + + list = cas_get_option_vector(5, ov_table); if (!list) { return H_SUCCESS; } - if (spapr_h_cas_compose_response(spapr, args[1], args[2])) { + /* @list now points to OV 5 */ + list += 2; + ov5_byte2 = rtas_ld(list, 0) >> 24; + if (ov5_byte2 & OV5_DRCONF_MEMORY) { + memory_update = true; + } + + if (spapr_h_cas_compose_response(spapr, args[1], args[2], + cpu_update, memory_update)) { qemu_system_reset_request(); } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 5de54d4a93..7d20798276 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -581,7 +581,8 @@ struct sPAPREventLogEntry { void spapr_events_init(sPAPRMachineState *sm); void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq); int spapr_h_cas_compose_response(sPAPRMachineState *sm, - target_ulong addr, target_ulong size); + target_ulong addr, target_ulong size, + bool cpu_update, bool memory_update); sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, uint64_t bus_offset, uint32_t page_shift, @@ -623,4 +624,16 @@ int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset); /* 1GB alignment for hotplug memory region */ #define SPAPR_HOTPLUG_MEM_ALIGN (1ULL << 30) +/* + * Number of 32 bit words in each LMB list entry in ibm,dynamic-memory + * property under ibm,dynamic-reconfiguration-memory node. + */ +#define SPAPR_DR_LMB_LIST_ENTRY_SIZE 6 + +/* + * This flag value defines the LMB as assigned in ibm,dynamic-memory + * property under ibm,dynamic-reconfiguration-memory node. + */ +#define SPAPR_LMB_FLAGS_ASSIGNED 0x00000008 + #endif /* !defined (__HW_SPAPR_H__) */ From ce881f774d69d941eb999c25f0cb1f72cd228795 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Mon, 29 Jun 2015 14:14:30 +0530 Subject: [PATCH 24/36] spapr: Make hash table size a factor of maxram_size The hash table size is dependent on ram_size, but since with hotplug the memory can grow till maxram_size. Hence make hash table size dependent on maxram_size. This allows to hotplug huge amounts of memory to the guest. Signed-off-by: Bharata B Rao Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 2f49f97924..d21e95cf6b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1715,7 +1715,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)) >= machine->ram_size) { + if ((1ULL << (spapr->htab_shift + 7)) >= machine->maxram_size) { break; } spapr->htab_shift++; From c20d332a85c95245e3b720bfea1bd02e3a311463 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Tue, 1 Sep 2015 11:22:35 +1000 Subject: [PATCH 25/36] spapr: Memory hotplug support Make use of pc-dimm infrastructure to support memory hotplug for PowerPC. Signed-off-by: Bharata B Rao Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 118 ++++++++++++++++++++++++++++++++++++++++++ hw/ppc/spapr_events.c | 8 +-- 2 files changed, 123 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d21e95cf6b..5b462290a5 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -34,6 +34,7 @@ #include "sysemu/block-backend.h" #include "sysemu/cpus.h" #include "sysemu/kvm.h" +#include "sysemu/device_tree.h" #include "kvm_ppc.h" #include "migration/migration.h" #include "mmu-hash64.h" @@ -862,6 +863,7 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr, hwaddr rtas_size) { MachineState *machine = MACHINE(qdev_get_machine()); + sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); const char *boot_device = machine->boot_order; int ret, i; size_t cb = 0; @@ -945,6 +947,10 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr, spapr_populate_chosen_stdout(fdt, spapr->vio_bus); } + if (smc->dr_lmb_enabled) { + _FDT(spapr_drc_populate_dt(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_LMB)); + } + _FDT((fdt_pack(fdt))); if (fdt_totalsize(fdt) > FDT_MAX_SIZE) { @@ -2055,12 +2061,120 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp) } } +static void spapr_add_lmbs(DeviceState *dev, uint64_t addr, uint64_t size, + uint32_t node, Error **errp) +{ + sPAPRDRConnector *drc; + sPAPRDRConnectorClass *drck; + uint32_t nr_lmbs = size/SPAPR_MEMORY_BLOCK_SIZE; + int i, fdt_offset, fdt_size; + void *fdt; + + /* + * Check for DRC connectors and send hotplug notification to the + * guest only in case of hotplugged memory. This allows cold plugged + * memory to be specified at boot time. + */ + if (!dev->hotplugged) { + return; + } + + for (i = 0; i < nr_lmbs; i++) { + drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB, + addr/SPAPR_MEMORY_BLOCK_SIZE); + g_assert(drc); + + fdt = create_device_tree(&fdt_size); + fdt_offset = spapr_populate_memory_node(fdt, node, addr, + SPAPR_MEMORY_BLOCK_SIZE); + + drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); + drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, errp); + spapr_hotplug_req_add_event(drc); + addr += SPAPR_MEMORY_BLOCK_SIZE; + } +} + +static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, + uint32_t node, Error **errp) +{ + Error *local_err = NULL; + sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev); + PCDIMMDevice *dimm = PC_DIMM(dev); + PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); + MemoryRegion *mr = ddc->get_memory_region(dimm); + uint64_t align = memory_region_get_alignment(mr); + uint64_t size = memory_region_size(mr); + uint64_t addr; + + if (size % SPAPR_MEMORY_BLOCK_SIZE) { + error_setg(&local_err, "Hotplugged memory size must be a multiple of " + "%lld MB", SPAPR_MEMORY_BLOCK_SIZE/M_BYTE); + goto out; + } + + pc_dimm_memory_plug(dev, &ms->hotplug_memory, mr, align, &local_err); + if (local_err) { + goto out; + } + + addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err); + if (local_err) { + pc_dimm_memory_unplug(dev, &ms->hotplug_memory, mr); + goto out; + } + + spapr_add_lmbs(dev, addr, size, node, &error_abort); + +out: + error_propagate(errp, local_err); +} + +static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(qdev_get_machine()); + + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + uint32_t node; + + if (!smc->dr_lmb_enabled) { + error_setg(errp, "Memory hotplug not supported for this machine"); + return; + } + node = object_property_get_int(OBJECT(dev), PC_DIMM_NODE_PROP, errp); + if (*errp) { + return; + } + + spapr_memory_plug(hotplug_dev, dev, node, errp); + } +} + +static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + error_setg(errp, "Memory hot unplug not supported by sPAPR"); + } +} + +static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine, + DeviceState *dev) +{ + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + return HOTPLUG_HANDLER(machine); + } + return NULL; +} + static void spapr_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc); FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); NMIClass *nc = NMI_CLASS(oc); + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); mc->init = ppc_spapr_init; mc->reset = ppc_spapr_reset; @@ -2072,6 +2186,9 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->kvm_type = spapr_kvm_type; mc->has_dynamic_sysbus = true; mc->pci_allow_0_address = true; + mc->get_hotplug_handler = spapr_get_hotpug_handler; + hc->plug = spapr_machine_device_plug; + hc->unplug = spapr_machine_device_unplug; smc->dr_lmb_enabled = false; fwc->get_dev_path = spapr_get_fw_dev_path; @@ -2089,6 +2206,7 @@ static const TypeInfo spapr_machine_info = { .interfaces = (InterfaceInfo[]) { { TYPE_FW_PATH_PROVIDER }, { TYPE_NMI }, + { TYPE_HOTPLUG_HANDLER }, { } }, }; diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index f626eb7b34..98bf7aedfc 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -427,14 +427,16 @@ static void spapr_hotplug_req_event(sPAPRDRConnector *drc, uint8_t hp_action) hp->hdr.section_length = cpu_to_be16(sizeof(*hp)); hp->hdr.section_version = 1; /* includes extended modifier */ hp->hotplug_action = hp_action; - + hp->drc.index = cpu_to_be32(drck->get_index(drc)); + hp->hotplug_identifier = RTAS_LOG_V6_HP_ID_DRC_INDEX; switch (drc_type) { case SPAPR_DR_CONNECTOR_TYPE_PCI: - hp->drc.index = cpu_to_be32(drck->get_index(drc)); - hp->hotplug_identifier = RTAS_LOG_V6_HP_ID_DRC_INDEX; hp->hotplug_type = RTAS_LOG_V6_HP_TYPE_PCI; break; + case SPAPR_DR_CONNECTOR_TYPE_LMB: + hp->hotplug_type = RTAS_LOG_V6_HP_TYPE_MEMORY; + break; default: /* we shouldn't be signaling hotplug events for resources * that don't support them From b556854bd8524c26b8be98ab1bfdf0826831e793 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Mon, 29 Jun 2015 14:14:32 +0530 Subject: [PATCH 26/36] spapr: Don't allow memory hotplug to memory less nodes Currently PowerPC kernel doesn't allow hot-adding memory to memory-less node, but instead will silently add the memory to the first node that has some memory. This causes two unexpected behaviours for the user. - Memory gets hotplugged to a different node than what the user specified. - Since pc-dimm subsystem in QEMU still thinks that memory belongs to memory-less node, a reboot will set things accordingly and the previously hotplugged memory now ends in the right node. This appears as if some memory moved from one node to another. So until kernel starts supporting memory hotplug to memory-less nodes, just prevent such attempts upfront in QEMU. Signed-off-by: Bharata B Rao Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5b462290a5..1170028578 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2136,7 +2136,7 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(qdev_get_machine()); if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - uint32_t node; + int node; if (!smc->dr_lmb_enabled) { error_setg(errp, "Memory hotplug not supported for this machine"); @@ -2147,6 +2147,28 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, return; } + /* + * Currently PowerPC kernel doesn't allow hot-adding memory to + * memory-less node, but instead will silently add the memory + * to the first node that has some memory. This causes two + * unexpected behaviours for the user. + * + * - Memory gets hotplugged to a different node than what the user + * specified. + * - Since pc-dimm subsystem in QEMU still thinks that memory belongs + * to memory-less node, a reboot will set things accordingly + * and the previously hotplugged memory now ends in the right node. + * This appears as if some memory moved from one node to another. + * + * So until kernel starts supporting memory hotplug to memory-less + * nodes, just prevent such attempts upfront in QEMU. + */ + if (nb_numa_nodes && !numa_info[node].node_mem) { + error_setg(errp, "Can't hotplug memory to memory-less node %d", + node); + return; + } + spapr_memory_plug(hotplug_dev, dev, node, errp); } } From 19a35c9e1b964f420ee07141f049e6c96c63b740 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Mon, 3 Aug 2015 11:05:39 +0530 Subject: [PATCH 27/36] spapr: Provide better error message when slots exceed max allowed Currently when user specifies more slots than allowed max of SPAPR_MAX_RAM_SLOTS (32), we error out like this: qemu-system-ppc64: unsupported amount of memory slots: 64 Let the user know about the max allowed slots like this: qemu-system-ppc64: Specified number of memory slots 64 exceeds max supported 32 Signed-off-by: Bharata B Rao Reviewed-by: David Gibson Signed-off-by: David Gibson --- 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 1170028578..5c81e19ac7 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1774,8 +1774,8 @@ static void ppc_spapr_init(MachineState *machine) ram_addr_t hotplug_mem_size = machine->maxram_size - machine->ram_size; if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) { - error_report("unsupported amount of memory slots: %"PRIu64, - machine->ram_slots); + error_report("Specified number of memory slots %"PRIu64" exceeds max supported %d\n", + machine->ram_slots, SPAPR_MAX_RAM_SLOTS); exit(EXIT_FAILURE); } From 6663864e950d40c467ae4ab81c4dac64d7a8d9e6 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Mon, 3 Aug 2015 11:05:40 +0530 Subject: [PATCH 28/36] spapr: Populate ibm,associativity-lookup-arrays correctly for non-NUMA When NUMA isn't configured explicitly, assume node 0 is present for the purpose of creating ibm,associativity-lookup-arrays property under ibm,dynamic-reconfiguration-memory DT node. This ensures that the associativity index property is correctly updated in ibm,dynamic-memory for the LMB that is hotplugged. Signed-off-by: Bharata B Rao Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5c81e19ac7..64d07cd634 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -724,6 +724,7 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) uint32_t nr_lmbs = machine->maxram_size/lmb_size - nr_rma_lmbs; uint32_t nr_assigned_lmbs = machine->ram_size/lmb_size - nr_rma_lmbs; uint32_t *int_buf, *cur_index, buf_len; + int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1; /* Allocate enough buffer size to fit in ibm,dynamic-memory */ buf_len = nr_lmbs * SPAPR_DR_LMB_LIST_ENTRY_SIZE * sizeof(uint32_t) + @@ -789,10 +790,10 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) /* ibm,associativity-lookup-arrays */ cur_index = int_buf; - int_buf[0] = cpu_to_be32(nb_numa_nodes); + int_buf[0] = cpu_to_be32(nr_nodes); int_buf[1] = cpu_to_be32(4); /* Number of entries per associativity list */ cur_index += 2; - for (i = 0; i < nb_numa_nodes; i++) { + for (i = 0; i < nr_nodes; i++) { uint32_t associativity[] = { cpu_to_be32(0x0), cpu_to_be32(0x0), From e8f986fc57a664a74b9f685b466506366a15201b Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Mon, 3 Aug 2015 11:05:41 +0530 Subject: [PATCH 29/36] spapr: Revert to memory@XXXX representation for non-hotplugged memory Don't represent non-hotluggable memory under drconf node. With this we don't have to create DRC objects for them. The effect of this patch is that we revert back to memory@XXXX representation for all the memory specified with -m option and represent the cold plugged memory and hot-pluggable memory under ibm,dynamic-reconfiguration-memory. Signed-off-by: Bharata B Rao Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 47 +++++++++-------------------------------------- 1 file changed, 9 insertions(+), 38 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 64d07cd634..402c00d24e 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -560,6 +560,7 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt) } if (!mem_start) { /* ppc_spapr_init() checks for rma_size <= node0_size already */ + spapr_populate_memory_node(fdt, i, 0, spapr->rma_size); mem_start += spapr->rma_size; node_size -= spapr->rma_size; } @@ -720,9 +721,7 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) int ret, i, offset; uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; uint32_t prop_lmb_size[] = {0, cpu_to_be32(lmb_size)}; - uint32_t nr_rma_lmbs = spapr->rma_size/lmb_size; - uint32_t nr_lmbs = machine->maxram_size/lmb_size - nr_rma_lmbs; - uint32_t nr_assigned_lmbs = machine->ram_size/lmb_size - nr_rma_lmbs; + uint32_t nr_lmbs = (machine->maxram_size - machine->ram_size)/lmb_size; uint32_t *int_buf, *cur_index, buf_len; int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1; @@ -755,15 +754,9 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) for (i = 0; i < nr_lmbs; i++) { sPAPRDRConnector *drc; sPAPRDRConnectorClass *drck; - uint64_t addr; + uint64_t addr = i * lmb_size + spapr->hotplug_memory.base;; uint32_t *dynamic_memory = cur_index; - if (i < nr_assigned_lmbs) { - addr = (i + nr_rma_lmbs) * lmb_size; - } else { - addr = (i - nr_assigned_lmbs) * lmb_size + - spapr->hotplug_memory.base; - } drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB, addr/lmb_size); g_assert(drc); @@ -838,8 +831,6 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr, /* Generate memory nodes or ibm,dynamic-reconfiguration-memory node */ if (memory_update && smc->dr_lmb_enabled) { _FDT((spapr_populate_drconf_memory(spapr, fdt))); - } else { - _FDT((spapr_populate_memory(spapr, fdt))); } /* Pack resulting tree */ @@ -877,23 +868,10 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr, /* open out the base tree into a temp buffer for the final tweaks */ _FDT((fdt_open_into(spapr->fdt_skel, fdt, FDT_MAX_SIZE))); - /* - * Add memory@0 node to represent RMA. Rest of the memory is either - * represented by memory nodes or ibm,dynamic-reconfiguration-memory - * node later during ibm,client-architecture-support call. - * - * If NUMA is configured, ensure that memory@0 ends up in the - * first memory-less node. - */ - if (nb_numa_nodes) { - for (i = 0; i < nb_numa_nodes; ++i) { - if (numa_info[i].node_mem) { - spapr_populate_memory_node(fdt, i, 0, spapr->rma_size); - break; - } - } - } else { - spapr_populate_memory_node(fdt, 0, 0, spapr->rma_size); + ret = spapr_populate_memory(spapr, fdt); + if (ret < 0) { + fprintf(stderr, "couldn't setup memory nodes in fdt\n"); + exit(1); } ret = spapr_populate_vdevice(spapr->vio_bus, fdt); @@ -1600,21 +1578,14 @@ static void spapr_create_lmb_dr_connectors(sPAPRMachineState *spapr) { MachineState *machine = MACHINE(spapr); uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; - uint32_t nr_rma_lmbs = spapr->rma_size/lmb_size; - uint32_t nr_lmbs = machine->maxram_size/lmb_size - nr_rma_lmbs; - uint32_t nr_assigned_lmbs = machine->ram_size/lmb_size - nr_rma_lmbs; + uint32_t nr_lmbs = (machine->maxram_size - machine->ram_size)/lmb_size; int i; for (i = 0; i < nr_lmbs; i++) { sPAPRDRConnector *drc; uint64_t addr; - if (i < nr_assigned_lmbs) { - addr = (i + nr_rma_lmbs) * lmb_size; - } else { - addr = (i - nr_assigned_lmbs) * lmb_size + - spapr->hotplug_memory.base; - } + addr = i * lmb_size + spapr->hotplug_memory.base; drc = spapr_dr_connector_new(OBJECT(spapr), SPAPR_DR_CONNECTOR_TYPE_LMB, addr/lmb_size); qemu_register_reset(spapr_drc_reset, drc); From 7a36ae7a9f4f136d40fe1da4aab66b364d4aa56d Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Mon, 3 Aug 2015 11:05:42 +0530 Subject: [PATCH 30/36] spapr: Support hotplug by specifying DRC count Support hotplug identifier type RTAS_LOG_V6_HP_ID_DRC_COUNT that allows hotplugging of DRCs by specifying the DRC count. While we are here, rename spapr_hotplug_req_add_event() to spapr_hotplug_req_add_by_index() spapr_hotplug_req_remove_event() to spapr_hotplug_req_remove_by_index() so that they match with spapr_hotplug_req_add_by_count(). Signed-off-by: Bharata B Rao Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 2 +- hw/ppc/spapr_events.c | 47 ++++++++++++++++++++++++++++++++++-------- hw/ppc/spapr_pci.c | 4 ++-- include/hw/ppc/spapr.h | 8 +++++-- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 402c00d24e..d00513fc34 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2062,7 +2062,7 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr, uint64_t size, drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, errp); - spapr_hotplug_req_add_event(drc); + spapr_hotplug_req_add_by_index(drc); addr += SPAPR_MEMORY_BLOCK_SIZE; } } diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index 98bf7aedfc..744ea62ac0 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -386,7 +386,9 @@ static void spapr_powerdown_req(Notifier *n, void *opaque) qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq)); } -static void spapr_hotplug_req_event(sPAPRDRConnector *drc, uint8_t hp_action) +static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action, + sPAPRDRConnectorType drc_type, + uint32_t drc) { sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); struct hp_log_full *new_hp; @@ -395,8 +397,6 @@ static void spapr_hotplug_req_event(sPAPRDRConnector *drc, uint8_t hp_action) struct rtas_event_log_v6_maina *maina; struct rtas_event_log_v6_mainb *mainb; struct rtas_event_log_v6_hp *hp; - sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); - sPAPRDRConnectorType drc_type = drck->get_type(drc); new_hp = g_malloc0(sizeof(struct hp_log_full)); hdr = &new_hp->hdr; @@ -427,8 +427,7 @@ static void spapr_hotplug_req_event(sPAPRDRConnector *drc, uint8_t hp_action) hp->hdr.section_length = cpu_to_be16(sizeof(*hp)); hp->hdr.section_version = 1; /* includes extended modifier */ hp->hotplug_action = hp_action; - hp->drc.index = cpu_to_be32(drck->get_index(drc)); - hp->hotplug_identifier = RTAS_LOG_V6_HP_ID_DRC_INDEX; + hp->hotplug_identifier = hp_id; switch (drc_type) { case SPAPR_DR_CONNECTOR_TYPE_PCI: @@ -445,19 +444,49 @@ static void spapr_hotplug_req_event(sPAPRDRConnector *drc, uint8_t hp_action) return; } + if (hp_id == RTAS_LOG_V6_HP_ID_DRC_COUNT) { + hp->drc.count = cpu_to_be32(drc); + } else if (hp_id == RTAS_LOG_V6_HP_ID_DRC_INDEX) { + hp->drc.index = cpu_to_be32(drc); + } + rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp, true); qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq)); } -void spapr_hotplug_req_add_event(sPAPRDRConnector *drc) +void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc) { - spapr_hotplug_req_event(drc, RTAS_LOG_V6_HP_ACTION_ADD); + sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); + sPAPRDRConnectorType drc_type = drck->get_type(drc); + uint32 index = drck->get_index(drc); + + spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_INDEX, + RTAS_LOG_V6_HP_ACTION_ADD, drc_type, index); } -void spapr_hotplug_req_remove_event(sPAPRDRConnector *drc) +void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc) { - spapr_hotplug_req_event(drc, RTAS_LOG_V6_HP_ACTION_REMOVE); + sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); + sPAPRDRConnectorType drc_type = drck->get_type(drc); + uint32 index = drck->get_index(drc); + + spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_INDEX, + RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, index); +} + +void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type, + uint32_t count) +{ + spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT, + RTAS_LOG_V6_HP_ACTION_ADD, drc_type, count); +} + +void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type, + uint32_t count) +{ + spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT, + RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, count); } static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr, diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index d2188c854d..b088491c9e 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1187,7 +1187,7 @@ static void spapr_phb_hot_plug_child(HotplugHandler *plug_handler, return; } if (plugged_dev->hotplugged) { - spapr_hotplug_req_add_event(drc); + spapr_hotplug_req_add_by_index(drc); } } @@ -1215,7 +1215,7 @@ static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler, error_propagate(errp, local_err); return; } - spapr_hotplug_req_remove_event(drc); + spapr_hotplug_req_remove_by_index(drc); } } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 7d20798276..ffb108d64c 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -594,8 +594,12 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname, int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, sPAPRTCETable *tcet); void spapr_pci_switch_vga(bool big_endian); -void spapr_hotplug_req_add_event(sPAPRDRConnector *drc); -void spapr_hotplug_req_remove_event(sPAPRDRConnector *drc); +void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc); +void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc); +void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type, + uint32_t count); +void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type, + uint32_t count); /* rtas-configure-connector state */ struct sPAPRConfigureConnectorState { From 0a4178692c2375a4516da7b71629bd08ee8697ee Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Mon, 3 Aug 2015 11:05:43 +0530 Subject: [PATCH 31/36] spapr: Move memory hotplug to RTAS_LOG_V6_HP_ID_DRC_COUNT type Till now memory hotplug used RTAS_LOG_V6_HP_ID_DRC_INDEX hotplug type which meant that we generated one hotplug type of EPOW event for every 256MB (SPAPR_MEMORY_BLOCK_SIZE). This quickly overruns the kernel rtas log buffer thus resulting in loss of memory hotplug events. Switch to RTAS_LOG_V6_HP_ID_DRC_COUNT hotplug type for memory so that we generate only one event per hotplug request. Signed-off-by: Bharata B Rao Reviewed-by: Michael Roth Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d00513fc34..533c7adae1 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2062,9 +2062,9 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr, uint64_t size, drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, errp); - spapr_hotplug_req_add_by_index(drc); addr += SPAPR_MEMORY_BLOCK_SIZE; } + spapr_hotplug_req_add_by_count(SPAPR_DR_CONNECTOR_TYPE_LMB, nr_lmbs); } static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, From 20bb648dca6d7fe8cdd1941194e7851950b25dc5 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 8 Sep 2015 11:21:52 +1000 Subject: [PATCH 32/36] spapr: Fix default NUMA node allocation for threads At present, if guest numa nodes are requested, but the cpus in each node are not specified, spapr just uses the default behaviour or assigning each vcpu round-robin to nodes. If smp_threads != 1, that will assign adjacent threads in a core to different NUMA nodes. As well as being just weird, that's a configuration that can't be represented in the device tree we give to the guest, which means the guest and qemu end up with different ideas of the NUMA topology. This patch implements mc->cpu_index_to_socket_id in the spapr code to make sure vcpus get assigned to nodes only at the socket granularity. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 533c7adae1..59fc814640 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2162,6 +2162,13 @@ static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine, return NULL; } +static unsigned spapr_cpu_index_to_socket_id(unsigned cpu_index) +{ + /* Allocate to NUMA nodes on a "socket" basis (not that concept of + * socket means much for the paravirtualized PAPR platform) */ + return cpu_index / smp_threads / smp_cores; +} + static void spapr_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -2183,6 +2190,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->get_hotplug_handler = spapr_get_hotpug_handler; hc->plug = spapr_machine_device_plug; hc->unplug = spapr_machine_device_unplug; + mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id; smc->dr_lmb_enabled = false; fwc->get_dev_path = spapr_get_fw_dev_path; From ef001f069e0f175a036929782c5c63053df9569a Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 15 Sep 2015 21:34:20 +0200 Subject: [PATCH 33/36] ppc/spapr: Fix buffer overflow in spapr_populate_drconf_memory() The buffer that is allocated in spapr_populate_drconf_memory() is used for setting both, the "ibm,dynamic-memory" and the "ibm,associativity-lookup-arrays" property. However, only the size of the first one is taken into account when allocating the memory. So if the length of the second property is larger than the length of the first one, we run into a buffer overflow here! Fix it by taking the length of the second property into account, too. Fixes: "spapr: Support ibm,dynamic-reconfiguration-memory" patch Signed-off-by: Thomas Huth Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 59fc814640..1333375846 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -725,9 +725,12 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) uint32_t *int_buf, *cur_index, buf_len; int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1; - /* Allocate enough buffer size to fit in ibm,dynamic-memory */ - buf_len = nr_lmbs * SPAPR_DR_LMB_LIST_ENTRY_SIZE * sizeof(uint32_t) + - sizeof(uint32_t); + /* + * Allocate enough buffer size to fit in ibm,dynamic-memory + * or ibm,associativity-lookup-arrays + */ + buf_len = MAX(nr_lmbs * SPAPR_DR_LMB_LIST_ENTRY_SIZE + 1, nr_nodes * 4 + 2) + * sizeof(uint32_t); cur_index = int_buf = g_malloc0(buf_len); offset = fdt_add_subnode(fdt, 0, "ibm,dynamic-reconfiguration-memory"); From 4d9392be6c1aada69ce86c0f6584128976985394 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 17 Sep 2015 10:49:41 +0200 Subject: [PATCH 34/36] ppc/spapr: Implement H_RANDOM hypercall in QEMU The PAPR interface defines a hypercall to pass high-quality hardware generated random numbers to guests. Recent kernels can already provide this hypercall to the guest if the right hardware random number generator is available. But in case the user wants to use another source like EGD, or QEMU is running with an older kernel, we should also have this call in QEMU, so that guests that do not support virtio-rng yet can get good random numbers, too. This patch now adds a new pseudo-device to QEMU that either directly provides this hypercall to the guest or is able to enable the in-kernel hypercall if available. The in-kernel hypercall can be enabled with the use-kvm property, e.g.: qemu-system-ppc64 -device spapr-rng,use-kvm=true For handling the hypercall in QEMU instead, a "RngBackend" is required since the hypercall should provide "good" random data instead of pseudo-random (like from a "simple" library function like rand() or g_random_int()). Since there are multiple RngBackends available, the user must select an appropriate back-end via the "rng" property of the device, e.g.: qemu-system-ppc64 -object rng-random,filename=/dev/hwrng,id=gid0 \ -device spapr-rng,rng=gid0 ... See http://wiki.qemu-project.org/Features-Done/VirtIORNG for other example of specifying RngBackends. Signed-off-by: Thomas Huth Signed-off-by: David Gibson --- hw/ppc/Makefile.objs | 2 +- hw/ppc/spapr.c | 8 ++ hw/ppc/spapr_rng.c | 186 +++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 4 + target-ppc/kvm.c | 9 ++ target-ppc/kvm_ppc.h | 5 ++ 6 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 hw/ppc/spapr_rng.c diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs index c8ab06e7f3..c1ffc7771b 100644 --- a/hw/ppc/Makefile.objs +++ b/hw/ppc/Makefile.objs @@ -3,7 +3,7 @@ obj-y += ppc.o ppc_booke.o # IBM pSeries (sPAPR) obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o -obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o +obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy) obj-y += spapr_pci_vfio.o endif diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 1333375846..7f4f196e53 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -883,6 +883,14 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr, exit(1); } + if (object_resolve_path_type("", TYPE_SPAPR_RNG, NULL)) { + ret = spapr_rng_populate_dt(fdt); + if (ret < 0) { + fprintf(stderr, "could not set up rng device in the fdt\n"); + exit(1); + } + } + QLIST_FOREACH(phb, &spapr->phbs, list) { ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt); } diff --git a/hw/ppc/spapr_rng.c b/hw/ppc/spapr_rng.c new file mode 100644 index 0000000000..ed43d5e042 --- /dev/null +++ b/hw/ppc/spapr_rng.c @@ -0,0 +1,186 @@ +/* + * QEMU sPAPR random number generator "device" for H_RANDOM hypercall + * + * Copyright 2015 Thomas Huth, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/error-report.h" +#include "sysemu/sysemu.h" +#include "sysemu/device_tree.h" +#include "sysemu/rng.h" +#include "hw/ppc/spapr.h" +#include "kvm_ppc.h" + +#define SPAPR_RNG(obj) \ + OBJECT_CHECK(sPAPRRngState, (obj), TYPE_SPAPR_RNG) + +struct sPAPRRngState { + /*< private >*/ + DeviceState ds; + RngBackend *backend; + bool use_kvm; +}; +typedef struct sPAPRRngState sPAPRRngState; + +struct HRandomData { + QemuSemaphore sem; + union { + uint64_t v64; + uint8_t v8[8]; + } val; + int received; +}; +typedef struct HRandomData HRandomData; + +/* Callback function for the RngBackend */ +static void random_recv(void *dest, const void *src, size_t size) +{ + HRandomData *hrdp = dest; + + if (src && size > 0) { + assert(size + hrdp->received <= sizeof(hrdp->val.v8)); + memcpy(&hrdp->val.v8[hrdp->received], src, size); + hrdp->received += size; + } + + qemu_sem_post(&hrdp->sem); +} + +/* Handler for the H_RANDOM hypercall */ +static target_ulong h_random(PowerPCCPU *cpu, sPAPRMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + sPAPRRngState *rngstate; + HRandomData hrdata; + + rngstate = SPAPR_RNG(object_resolve_path_type("", TYPE_SPAPR_RNG, NULL)); + + if (!rngstate || !rngstate->backend) { + return H_HARDWARE; + } + + qemu_sem_init(&hrdata.sem, 0); + hrdata.val.v64 = 0; + hrdata.received = 0; + + qemu_mutex_unlock_iothread(); + while (hrdata.received < 8) { + rng_backend_request_entropy(rngstate->backend, 8 - hrdata.received, + random_recv, &hrdata); + qemu_sem_wait(&hrdata.sem); + } + qemu_mutex_lock_iothread(); + + qemu_sem_destroy(&hrdata.sem); + args[0] = hrdata.val.v64; + + return H_SUCCESS; +} + +static void spapr_rng_instance_init(Object *obj) +{ + sPAPRRngState *rngstate = SPAPR_RNG(obj); + + if (object_resolve_path_type("", TYPE_SPAPR_RNG, NULL) != NULL) { + error_report("spapr-rng can not be instantiated twice!"); + return; + } + + object_property_add_link(obj, "rng", TYPE_RNG_BACKEND, + (Object **)&rngstate->backend, + object_property_allow_set_link, + OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL); + object_property_set_description(obj, "rng", + "ID of the random number generator backend", + NULL); +} + +static void spapr_rng_realize(DeviceState *dev, Error **errp) +{ + + sPAPRRngState *rngstate = SPAPR_RNG(dev); + + if (rngstate->use_kvm) { + if (kvmppc_enable_hwrng() == 0) { + return; + } + /* + * If user specified both, use-kvm and a backend, we fall back to + * the backend now. If not, provide an appropriate error message. + */ + if (!rngstate->backend) { + error_setg(errp, "Could not initialize in-kernel H_RANDOM call!"); + return; + } + } + + if (rngstate->backend) { + spapr_register_hypercall(H_RANDOM, h_random); + } else { + error_setg(errp, "spapr-rng needs an RNG backend!"); + } +} + +int spapr_rng_populate_dt(void *fdt) +{ + int node; + int ret; + + node = qemu_fdt_add_subnode(fdt, "/ibm,platform-facilities"); + if (node <= 0) { + return -1; + } + ret = fdt_setprop_string(fdt, node, "device_type", + "ibm,platform-facilities"); + ret |= fdt_setprop_cell(fdt, node, "#address-cells", 0x1); + ret |= fdt_setprop_cell(fdt, node, "#size-cells", 0x0); + + node = fdt_add_subnode(fdt, node, "ibm,random-v1"); + if (node <= 0) { + return -1; + } + ret |= fdt_setprop_string(fdt, node, "compatible", "ibm,random"); + + return ret ? -1 : 0; +} + +static Property spapr_rng_properties[] = { + DEFINE_PROP_BOOL("use-kvm", sPAPRRngState, use_kvm, false), + DEFINE_PROP_END_OF_LIST(), +}; + +static void spapr_rng_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = spapr_rng_realize; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + dc->props = spapr_rng_properties; +} + +static const TypeInfo spapr_rng_info = { + .name = TYPE_SPAPR_RNG, + .parent = TYPE_DEVICE, + .instance_size = sizeof(sPAPRRngState), + .instance_init = spapr_rng_instance_init, + .class_init = spapr_rng_class_init, +}; + +static void spapr_rng_register_type(void) +{ + type_register_static(&spapr_rng_info); +} +type_init(spapr_rng_register_type) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index ffb108d64c..56c5b0b2b8 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -334,6 +334,7 @@ struct sPAPRMachineState { #define H_SET_MPP 0x2D0 #define H_GET_MPP 0x2D4 #define H_XIRR_X 0x2FC +#define H_RANDOM 0x300 #define H_SET_MODE 0x31C #define MAX_HCALL_OPCODE H_SET_MODE @@ -612,10 +613,13 @@ struct sPAPRConfigureConnectorState { void spapr_ccs_reset_hook(void *opaque); #define TYPE_SPAPR_RTC "spapr-rtc" +#define TYPE_SPAPR_RNG "spapr-rng" void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns); int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset); +int spapr_rng_populate_dt(void *fdt); + #define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */ /* diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 9cf5308ac3..e641680fb1 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -2489,3 +2489,12 @@ int kvm_arch_msi_data_to_gsi(uint32_t data) { return data & 0xffff; } + +int kvmppc_enable_hwrng(void) +{ + if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_PPC_HWRNG)) { + return -1; + } + + return kvmppc_enable_hcall(kvm_state, H_RANDOM); +} diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index f790d50e51..470f6d62f7 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -54,6 +54,7 @@ void kvmppc_hash64_free_pteg(uint64_t token); void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, target_ulong pte0, target_ulong pte1); bool kvmppc_has_cap_fixup_hcalls(void); +int kvmppc_enable_hwrng(void); #else @@ -251,6 +252,10 @@ static inline bool kvmppc_has_cap_fixup_hcalls(void) abort(); } +static inline int kvmppc_enable_hwrng(void) +{ + return -1; +} #endif #ifndef CONFIG_KVM From 47445c80fb57035331574ac1ac0bcee67fb84aeb Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Fri, 18 Sep 2015 17:30:43 +1000 Subject: [PATCH 35/36] sPAPR: Revert don't enable EEH on emulated PCI devices This reverts commit 7cb18007 ("sPAPR: Don't enable EEH on emulated PCI devices") as rtas_ibm_set_eeh_option() isn't the right place to check if there has the corresponding PCI device for the input address, which can be PE address, not PCI device address. Signed-off-by: Gavin Shan Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index b088491c9e..617b7f3fdd 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -431,7 +431,6 @@ static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu, { sPAPRPHBState *sphb; sPAPRPHBClass *spc; - PCIDevice *pdev; uint32_t addr, option; uint64_t buid; int ret; @@ -449,12 +448,6 @@ 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; From d76548a98f4e18d3c65a3d921bbb70caf9be6138 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Fri, 18 Sep 2015 17:30:44 +1000 Subject: [PATCH 36/36] sPAPR: Enable EEH on VFIO PCI device only This checks if the PCI device retrieved from the PCI device address is VFIO PCI device when enabling EEH functionality. If it's not VFIO PCI device, the EEH functonality isn't enabled. Signed-off-by: Gavin Shan Signed-off-by: David Gibson --- hw/ppc/spapr_pci_vfio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c index cca45ed312..a61b418131 100644 --- a/hw/ppc/spapr_pci_vfio.c +++ b/hw/ppc/spapr_pci_vfio.c @@ -117,7 +117,7 @@ static int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb, phb = PCI_HOST_BRIDGE(sphb); pdev = pci_find_device(phb->bus, (addr >> 16) & 0xFF, (addr >> 8) & 0xFF); - if (!pdev) { + if (!pdev || !object_dynamic_cast(OBJECT(pdev), "vfio-pci")) { return RTAS_OUT_PARAM_ERROR; }