diff options
| author | Greg Kurz | 2019-06-13 18:45:05 +0200 |
|---|---|---|
| committer | David Gibson | 2019-07-02 01:43:58 +0200 |
| commit | 7abc0c6d35306a41a48eda7ab2b7b2d51f32f86b (patch) | |
| tree | 439604b99e2dbb8b21870775b35a79af91fd7fa3 /hw | |
| parent | xics/spapr: Register RTAS/hypercalls once at machine init (diff) | |
| download | qemu-7abc0c6d35306a41a48eda7ab2b7b2d51f32f86b.tar.gz qemu-7abc0c6d35306a41a48eda7ab2b7b2d51f32f86b.tar.xz qemu-7abc0c6d35306a41a48eda7ab2b7b2d51f32f86b.zip | |
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>
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/intc/xics_kvm.c | 30 | ||||
| -rw-r--r-- | hw/ppc/spapr_irq.c | 13 |
2 files changed, 43 insertions, 0 deletions
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 5c4208f430..c7f8f5edd2 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -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; +} diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index dfb99f35ea..75654fc67a 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -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; + } } /* |
