]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Query and use mshv capabilities
authorPraveen K Paladugu <prapal@linux.microsoft.com>
Fri, 7 Nov 2025 20:13:53 +0000 (14:13 -0600)
committerMartin Kletzander <mkletzan@redhat.com>
Sat, 22 Nov 2025 07:23:05 +0000 (08:23 +0100)
Qemu with mshv capabilities can launch VIR_DOMAIN_VIRT_HYPERV domains.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
src/qemu/qemu_capabilities.c

index cd788be28c329b90d8d40e9df25d05df2de54253..4050d5ccc692b204e6ff716e6b544a3149bc244c 100644 (file)
@@ -840,6 +840,7 @@ struct _virQEMUCaps {
     virQEMUCapsAccel kvm;
     virQEMUCapsAccel hvf;
     virQEMUCapsAccel tcg;
+    virQEMUCapsAccel mshv;
 };
 
 static virClass *virQEMUCapsClass;
@@ -938,7 +939,8 @@ bool
 virQEMUCapsHaveAccel(virQEMUCaps *qemuCaps)
 {
     return virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) ||
-           virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF);
+           virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF) ||
+           virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSHV);
 }
 
 
@@ -949,6 +951,8 @@ virQEMUCapsAccelStr(virDomainVirtType type)
         return "kvm";
     else if (type == VIR_DOMAIN_VIRT_HVF)
         return "hvf";
+    else if (type == VIR_DOMAIN_VIRT_HYPERV)
+        return "mshv";
 
     return "tcg";
 }
@@ -962,6 +966,8 @@ virQEMUCapsGetAccel(virQEMUCaps *qemuCaps,
         return &qemuCaps->kvm;
     else if (type == VIR_DOMAIN_VIRT_HVF)
         return &qemuCaps->hvf;
+    else if (type == VIR_DOMAIN_VIRT_HYPERV)
+        return &qemuCaps->mshv;
 
     return &qemuCaps->tcg;
 }
@@ -1069,6 +1075,8 @@ virQEMUCapsGetMachineTypesCaps(virQEMUCaps *qemuCaps,
         accel = &qemuCaps->kvm;
     else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
         accel = &qemuCaps->hvf;
+    else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSHV))
+        accel = &qemuCaps->mshv;
     else
         accel = &qemuCaps->tcg;
 
@@ -1177,6 +1185,10 @@ virQEMUCapsInitGuestFromBinary(virCaps *caps,
         virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HVF,
                                       NULL, NULL, 0, NULL);
     }
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSHV)) {
+        virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HYPERV,
+                                      NULL, NULL, 0, NULL);
+    }
 
     if (ARCH_IS_X86(guestarch) || guestarch == VIR_ARCH_AARCH64 ||
         ARCH_IS_LOONGARCH(guestarch))
@@ -2065,6 +2077,7 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps)
     virQEMUCapsAccelCopy(&ret->kvm, &qemuCaps->kvm);
     virQEMUCapsAccelCopy(&ret->hvf, &qemuCaps->hvf);
     virQEMUCapsAccelCopy(&ret->tcg, &qemuCaps->tcg);
+    virQEMUCapsAccelCopy(&ret->mshv, &qemuCaps->mshv);
 
     ret->gicCapabilities = g_new0(virGICCapability, qemuCaps->ngicCapabilities);
     ret->ngicCapabilities = qemuCaps->ngicCapabilities;
@@ -2124,6 +2137,7 @@ void virQEMUCapsDispose(void *obj)
     virQEMUCapsAccelClear(&qemuCaps->kvm);
     virQEMUCapsAccelClear(&qemuCaps->hvf);
     virQEMUCapsAccelClear(&qemuCaps->tcg);
+    virQEMUCapsAccelClear(&qemuCaps->mshv);
 }
 
 void
@@ -2346,6 +2360,10 @@ virQEMUCapsIsVirtTypeSupported(virQEMUCaps *qemuCaps,
         virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
         return true;
 
+    if (virtType == VIR_DOMAIN_VIRT_HYPERV &&
+        virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSHV))
+        return true;
+
     return false;
 }
 
@@ -2918,6 +2936,7 @@ virQEMUCapsHasMachines(virQEMUCaps *qemuCaps)
 
     return !!qemuCaps->kvm.nmachineTypes ||
            !!qemuCaps->hvf.nmachineTypes ||
+           !!qemuCaps->mshv.nmachineTypes ||
            !!qemuCaps->tcg.nmachineTypes;
 }
 
@@ -3492,6 +3511,8 @@ virQEMUCapsProbeAccels(virQEMUCaps *qemuCaps,
         virQEMUCapsSet(qemuCaps, QEMU_CAPS_HVF);
     else if (STREQ(enabled, "kvm"))
         virQEMUCapsSet(qemuCaps, QEMU_CAPS_KVM);
+    else if (STREQ(enabled, "mshv"))
+        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MSHV);
 
     return 0;
 }
@@ -4923,6 +4944,10 @@ virQEMUCapsLoadCache(virArch hostArch,
         virQEMUCapsLoadAccel(qemuCaps, ctxt, VIR_DOMAIN_VIRT_HVF) < 0) {
         return -1;
     }
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSHV) &&
+        virQEMUCapsLoadAccel(qemuCaps, ctxt, VIR_DOMAIN_VIRT_HYPERV) < 0) {
+        return -1;
+    }
     if (virQEMUCapsLoadAccel(qemuCaps, ctxt, VIR_DOMAIN_VIRT_QEMU) < 0)
         return -1;
 
@@ -4942,6 +4967,8 @@ virQEMUCapsLoadCache(virArch hostArch,
         virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
         virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_HVF);
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSHV))
+        virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_HYPERV);
     virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
 
     if (virXPathBoolean("boolean(./kvmSupportsNesting)", ctxt) > 0)
@@ -5292,6 +5319,8 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
         virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_KVM);
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
         virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_HVF);
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSHV))
+        virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_HYPERV);
     virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_QEMU);
 
     for (i = 0; i < qemuCaps->ngicCapabilities; i++) {
@@ -5799,6 +5828,9 @@ virQEMUCapsGetVirtType(virQEMUCaps *qemuCaps)
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
         return VIR_DOMAIN_VIRT_HVF;
 
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSHV))
+        return VIR_DOMAIN_VIRT_HYPERV;
+
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_TCG))
         return VIR_DOMAIN_VIRT_QEMU;
 
@@ -6035,6 +6067,9 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
         virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
         virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_HVF);
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSHV))
+        virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_HYPERV);
+
     virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
 
     if (virQEMUCapsHaveAccel(qemuCaps)) {
@@ -7243,4 +7278,5 @@ virQEMUCapsStripMachineAliases(virQEMUCaps *qemuCaps)
     virQEMUCapsStripMachineAliasesForVirtType(qemuCaps, VIR_DOMAIN_VIRT_KVM);
     virQEMUCapsStripMachineAliasesForVirtType(qemuCaps, VIR_DOMAIN_VIRT_HVF);
     virQEMUCapsStripMachineAliasesForVirtType(qemuCaps, VIR_DOMAIN_VIRT_QEMU);
+    virQEMUCapsStripMachineAliasesForVirtType(qemuCaps, VIR_DOMAIN_VIRT_HYPERV);
 }