summary refs log tree commit diff stats
path: root/hw/intc/xics_kvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/intc/xics_kvm.c')
-rw-r--r--hw/intc/xics_kvm.c30
1 files changed, 30 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;
+}