diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-07-11 16:34:09 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-07-11 16:34:09 +0100 |
commit | aa916e409c04cb614ec2fee8b6b33836bf5998bb (patch) | |
tree | 819d42aa423f46bb6ec55582d14d6dbe914821b9 /hw/ppc/spapr.c | |
parent | 29741be341d50e4311e42ca3199f9b0bcfd4f5d2 (diff) | |
parent | b87680427e8a3ff682f66514e99a8344e7437247 (diff) | |
download | qemu-aa916e409c04cb614ec2fee8b6b33836bf5998bb.zip qemu-aa916e409c04cb614ec2fee8b6b33836bf5998bb.tar.gz qemu-aa916e409c04cb614ec2fee8b6b33836bf5998bb.tar.bz2 |
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.10-20170711' into staging
ppc patch queue 2017-07-11
* Several minor cleanups from Greg Kurz
* Fix for migration of pseries-2.7 and earlier machine types
* More reworking of the DRC hotplug code, fixing several problems
though there are still more to go
* Fixes for CPU family / alias handling on POWER9
* Preliminary patches for POWER9 XIVE (new interrupt controller)
support
* Assorted other fixes
# gpg: Signature made Tue 11 Jul 2017 05:35:16 BST
# gpg: using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392
* remotes/dgibson/tags/ppc-for-2.10-20170711:
spapr: populate device tree depending on XIVE_EXPLOIT option
spapr: introduce the XIVE_EXPLOIT option in CAS
ppc/kvm: have the "family" CPU alias to point to TYPE_HOST_POWERPC_CPU
spapr: Only report host/guest IOMMU page size mismatches on KVM
spapr: fix memory hotplug error path
target/ppc: Add debug function for radix mmu translation
target/ppc: Refactor tcg radix mmu code
spapr: Use unplug_request for PCI hot unplug
spapr: Remove unnecessary differences between hotplug and coldplug paths
spapr: Add DRC release method
spapr: Uniform DRC reset paths
spapr: Leave DR-indicator management to the guest
target-ppc: SPR_BOOKE_ESR not set on FP exceptions
spapr: fix migration to pseries machine < 2.8
spapr: fix bogus function name in comment
spapr: refresh "platform-specific" hcalls comment
spapr: make spapr_populate_hotplug_cpu_dt() static
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ppc/spapr.c')
-rw-r--r-- | hw/ppc/spapr.c | 95 |
1 files changed, 43 insertions, 52 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 990772b..d38563d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -778,6 +778,11 @@ static int spapr_dt_cas_updates(sPAPRMachineState *spapr, void *fdt, } } + /* /interrupt controller */ + if (!spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)) { + spapr_dt_xics(xics_max_server_number(), fdt, PHANDLE_XICP); + } + offset = fdt_path_offset(fdt, "/chosen"); if (offset < 0) { offset = fdt_add_subnode(fdt, 0, "chosen"); @@ -801,7 +806,7 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr, size -= sizeof(hdr); - /* Create sceleton */ + /* Create skeleton */ fdt_skel = g_malloc0(size); _FDT((fdt_create(fdt_skel, size))); _FDT((fdt_begin_node(fdt_skel, ""))); @@ -910,7 +915,8 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen) { PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu); - char val[2 * 3] = { + char val[2 * 4] = { + 23, 0x00, /* Xive mode: 0 = legacy (as in ISA 2.7), 1 = Exploitation */ 24, 0x00, /* Hash/Radix, filled in below. */ 25, 0x00, /* Hash options: Segment Tables == no, GTSE == no. */ 26, 0x40, /* Radix options: GTSE == yes. */ @@ -918,19 +924,19 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen) if (kvm_enabled()) { if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) { - val[1] = 0x80; /* OV5_MMU_BOTH */ + val[3] = 0x80; /* OV5_MMU_BOTH */ } else if (kvmppc_has_cap_mmu_radix()) { - val[1] = 0x40; /* OV5_MMU_RADIX_300 */ + val[3] = 0x40; /* OV5_MMU_RADIX_300 */ } else { - val[1] = 0x00; /* Hash */ + val[3] = 0x00; /* Hash */ } } else { if (first_ppc_cpu->env.mmu_model & POWERPC_MMU_V3) { /* V3 MMU supports both hash and radix (with dynamic switching) */ - val[1] = 0xC0; + val[3] = 0xC0; } else { /* Otherwise we can only do hash */ - val[1] = 0x00; + val[3] = 0x00; } } _FDT(fdt_setprop(fdt, chosen, "ibm,arch-vec-5-platform-support", @@ -1068,9 +1074,6 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr, _FDT(fdt_setprop_cell(fdt, 0, "#address-cells", 2)); _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2)); - /* /interrupt controller */ - spapr_dt_xics(xics_max_server_number(), fdt, PHANDLE_XICP); - ret = spapr_populate_memory(spapr, fdt); if (ret < 0) { error_report("couldn't setup memory nodes in fdt"); @@ -1967,24 +1970,6 @@ static void spapr_boot_set(void *opaque, const char *boot_device, machine->boot_order = g_strdup(boot_device); } -/* - * 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); @@ -1993,13 +1978,11 @@ static void spapr_create_lmb_dr_connectors(sPAPRMachineState *spapr) int i; for (i = 0; i < nr_lmbs; i++) { - sPAPRDRConnector *drc; uint64_t addr; addr = i * lmb_size + spapr->hotplug_memory.base; - drc = spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_LMB, - addr/lmb_size); - qemu_register_reset(spapr_drc_reset, drc); + spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_LMB, + addr / lmb_size); } } @@ -2093,11 +2076,8 @@ static void spapr_init_cpus(sPAPRMachineState *spapr) int core_id = i * smp_threads; if (mc->has_hotpluggable_cpus) { - sPAPRDRConnector *drc = - spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_CPU, - (core_id / smp_threads) * smt); - - qemu_register_reset(spapr_drc_reset, drc); + spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_CPU, + (core_id / smp_threads) * smt); } if (i < boot_cores_nr) { @@ -2624,6 +2604,7 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size, int i, fdt_offset, fdt_size; void *fdt; uint64_t addr = addr_start; + Error *local_err = NULL; for (i = 0; i < nr_lmbs; i++) { drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, @@ -2634,7 +2615,18 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size, fdt_offset = spapr_populate_memory_node(fdt, node, addr, SPAPR_MEMORY_BLOCK_SIZE); - spapr_drc_attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, errp); + spapr_drc_attach(drc, dev, fdt, fdt_offset, &local_err); + if (local_err) { + while (addr > addr_start) { + addr -= SPAPR_MEMORY_BLOCK_SIZE; + drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, + addr / SPAPR_MEMORY_BLOCK_SIZE); + spapr_drc_detach(drc, dev, NULL); + } + g_free(fdt); + error_propagate(errp, local_err); + return; + } addr += SPAPR_MEMORY_BLOCK_SIZE; } /* send hotplug notification to the @@ -2674,14 +2666,20 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, addr = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err); if (local_err) { - pc_dimm_memory_unplug(dev, &ms->hotplug_memory, mr); - goto out; + goto out_unplug; } spapr_add_lmbs(dev, addr, size, node, spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT), - &error_abort); + &local_err); + if (local_err) { + goto out_unplug; + } + + return; +out_unplug: + pc_dimm_memory_unplug(dev, &ms->hotplug_memory, mr); out: error_propagate(errp, local_err); } @@ -2863,8 +2861,8 @@ out: error_propagate(errp, local_err); } -void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset, - sPAPRMachineState *spapr) +static void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset, + sPAPRMachineState *spapr) { PowerPCCPU *cpu = POWERPC_CPU(cs); DeviceClass *dc = DEVICE_GET_CLASS(cs); @@ -2979,17 +2977,10 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, g_assert(drc || !mc->has_hotpluggable_cpus); - /* - * Setup CPU DT entries only for hotplugged CPUs. For boot time or - * coldplugged CPUs DT entries are setup in spapr_build_fdt(). - */ - if (dev->hotplugged) { - fdt = spapr_populate_hotplug_cpu_dt(cs, &fdt_offset, spapr); - } + fdt = spapr_populate_hotplug_cpu_dt(cs, &fdt_offset, spapr); if (drc) { - spapr_drc_attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, - &local_err); + spapr_drc_attach(drc, dev, fdt, fdt_offset, &local_err); if (local_err) { g_free(fdt); error_propagate(errp, local_err); |