diff options
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/spapr_xive_kvm.c | 19 | ||||
-rw-r--r-- | hw/intc/xive.c | 21 |
2 files changed, 37 insertions, 3 deletions
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c index 3bf8e7a..8898615 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 cf77bdb..da148e9 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() |