xics/spapr: Detect old KVM XICS on POWER9 hosts
Older KVMs on POWER9 don't support destroying/recreating a KVM XICS device, which is required by 'dual' interrupt controller mode. This causes QEMU to emit a warning when the guest is rebooted and to fall back on XICS emulation: qemu-system-ppc64: warning: kernel_irqchip allowed but unavailable: Error on KVM_CREATE_DEVICE for XICS: File exists If kernel irqchip is required, QEMU will thus exit when the guest is first rebooted. Failing QEMU this late may be a painful experience for the user. Detect that and exit at machine init instead. Signed-off-by: Greg Kurz <groug@kaod.org> Message-Id: <156044430517.125694.6207865998817342638.stgit@bahia.lab.toulouse-stg.fr.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
d9293c4843
commit
7abc0c6d35
@ -142,8 +142,8 @@ xics XICS KVM XICS emul. XICS KVM
|
||||
(3) QEMU fails at CAS with ``Guest requested unavailable interrupt
|
||||
mode (XICS), either don't set the ic-mode machine property or try
|
||||
ic-mode=xics or ic-mode=dual``
|
||||
(4) QEMU/KVM incompatibility due to device destruction in reset. This
|
||||
needs to be addressed more cleanly with an error.
|
||||
(4) QEMU/KVM incompatibility due to device destruction in reset. QEMU fails
|
||||
with ``KVM is too old to support ic-mode=dual,kernel-irqchip=on``
|
||||
|
||||
|
||||
XIVE Device tree properties
|
||||
|
@ -452,3 +452,33 @@ void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp)
|
||||
/* Clear the presenter from the VCPUs */
|
||||
kvm_disable_icps();
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a heuristic to detect older KVMs on POWER9 hosts that don't
|
||||
* support destruction of a KVM XICS device while the VM is running.
|
||||
* Required to start a spapr machine with ic-mode=dual,kernel-irqchip=on.
|
||||
*/
|
||||
bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
|
||||
if (rc < 0) {
|
||||
/*
|
||||
* The error is ignored on purpose. The KVM XICS setup code
|
||||
* will catch it again anyway. The goal here is to see if
|
||||
* close() actually destroys the device or not.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
close(rc);
|
||||
|
||||
rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
|
||||
if (rc >= 0) {
|
||||
close(rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
return errno == EEXIST;
|
||||
}
|
||||
|
@ -669,6 +669,19 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* On a POWER9 host, some older KVM XICS devices cannot be destroyed and
|
||||
* re-created. Detect that early to avoid QEMU to exit later when the
|
||||
* guest reboots.
|
||||
*/
|
||||
if (kvm_enabled() &&
|
||||
spapr->irq == &spapr_irq_dual &&
|
||||
machine_kernel_irqchip_required(machine) &&
|
||||
xics_kvm_has_broken_disconnect(spapr)) {
|
||||
error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -35,6 +35,7 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
|
||||
uint32_t phandle);
|
||||
int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
|
||||
void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
|
||||
bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
|
||||
void xics_spapr_init(SpaprMachineState *spapr);
|
||||
void xics_spapr_connect(SpaprMachineState *spapr);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user