aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/intc/spapr_xive_kvm.c19
-rw-r--r--hw/intc/xive.c21
-rw-r--r--hw/ppc/spapr.c24
-rw-r--r--include/hw/ppc/xive.h1
4 files changed, 50 insertions, 15 deletions
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 3bf8e7a20e..8898615c69 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -72,11 +72,17 @@ static void kvm_cpu_disable_all(void)
* XIVE Thread Interrupt Management context (KVM)
*/
-static void kvmppc_xive_cpu_set_state(XiveTCTX *tctx, Error **errp)
+void kvmppc_xive_cpu_set_state(XiveTCTX *tctx, Error **errp)
{
+ SpaprXive *xive = SPAPR_MACHINE(qdev_get_machine())->xive;
uint64_t state[2];
int ret;
+ /* The KVM XIVE device is not in use yet */
+ if (xive->fd == -1) {
+ return;
+ }
+
/* word0 and word1 of the OS ring. */
state[0] = *((uint64_t *) &tctx->regs[TM_QW1_OS]);
@@ -655,7 +661,16 @@ int kvmppc_xive_post_load(SpaprXive *xive, int version_id)
}
}
- /* Restore the thread interrupt contexts */
+ /*
+ * Restore the thread interrupt contexts of initial CPUs.
+ *
+ * The context of hotplugged CPUs is restored later, by the
+ * 'post_load' handler of the XiveTCTX model because they are not
+ * available at the time the SpaprXive 'post_load' method is
+ * called. We can not restore the context of all CPUs in the
+ * 'post_load' handler of XiveTCTX because the machine is not
+ * necessarily connected to the KVM device at that time.
+ */
CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index cf77bdb7d3..da148e9f6f 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -615,12 +615,31 @@ static int vmstate_xive_tctx_pre_save(void *opaque)
return 0;
}
+static int vmstate_xive_tctx_post_load(void *opaque, int version_id)
+{
+ Error *local_err = NULL;
+
+ if (kvm_irqchip_in_kernel()) {
+ /*
+ * Required for hotplugged CPU, for which the state comes
+ * after all states of the machine.
+ */
+ kvmppc_xive_cpu_set_state(XIVE_TCTX(opaque), &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static const VMStateDescription vmstate_xive_tctx = {
.name = TYPE_XIVE_TCTX,
.version_id = 1,
.minimum_version_id = 1,
.pre_save = vmstate_xive_tctx_pre_save,
- .post_load = NULL, /* handled by the sPAPRxive model */
+ .post_load = vmstate_xive_tctx_post_load,
.fields = (VMStateField[]) {
VMSTATE_BUFFER(regs, XiveTCTX),
VMSTATE_END_OF_LIST()
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 821f0d4a49..12ed4b065c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1727,6 +1727,18 @@ static void spapr_machine_reset(MachineState *machine)
}
/*
+ * NVLink2-connected GPU RAM needs to be placed on a separate NUMA node.
+ * We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is
+ * called from vPHB reset handler so we initialize the counter here.
+ * If no NUMA is configured from the QEMU side, we start from 1 as GPU RAM
+ * must be equally distant from any other node.
+ * The final value of spapr->gpu_numa_id is going to be written to
+ * max-associativity-domains in spapr_build_fdt().
+ */
+ spapr->gpu_numa_id = MAX(1, nb_numa_nodes);
+ qemu_devices_reset();
+
+ /*
* If this reset wasn't generated by CAS, we should reset our
* negotiated options and start from scratch
*/
@@ -1742,18 +1754,6 @@ static void spapr_machine_reset(MachineState *machine)
}
/*
- * NVLink2-connected GPU RAM needs to be placed on a separate NUMA node.
- * We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is
- * called from vPHB reset handler so we initialize the counter here.
- * If no NUMA is configured from the QEMU side, we start from 1 as GPU RAM
- * must be equally distant from any other node.
- * The final value of spapr->gpu_numa_id is going to be written to
- * max-associativity-domains in spapr_build_fdt().
- */
- spapr->gpu_numa_id = MAX(1, nb_numa_nodes);
- qemu_devices_reset();
-
- /*
* This is fixing some of the default configuration of the XIVE
* devices. To be called after the reset of the machine devices.
*/
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 55c53c7417..736335174a 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -438,5 +438,6 @@ void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val);
void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp);
void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp);
void kvmppc_xive_cpu_get_state(XiveTCTX *tctx, Error **errp);
+void kvmppc_xive_cpu_set_state(XiveTCTX *tctx, Error **errp);
#endif /* PPC_XIVE_H */