aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/spapr.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-07-11 16:34:09 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-07-11 16:34:09 +0100
commitaa916e409c04cb614ec2fee8b6b33836bf5998bb (patch)
tree819d42aa423f46bb6ec55582d14d6dbe914821b9 /hw/ppc/spapr.c
parent29741be341d50e4311e42ca3199f9b0bcfd4f5d2 (diff)
parentb87680427e8a3ff682f66514e99a8344e7437247 (diff)
downloadqemu-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.c95
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);