[libvirt PATCH 09/17] qemu: Correct CPU capabilities probing for hvf

Andrea Bolognani posted 17 patches 4 years, 1 month ago
There is a newer version of this series
[libvirt PATCH 09/17] qemu: Correct CPU capabilities probing for hvf
Posted by Andrea Bolognani 4 years, 1 month ago
From: Roman Bolshakov <r.bolshakov@yadro.com>

With this change virsh domcapabilites shows:
  <mode name='host-passthrough' supported='yes'/>

https://gitlab.com/libvirt/libvirt/-/issues/147

Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
 src/qemu/qemu_capabilities.c | 25 ++++++++++++++++++++++---
 src/qemu/qemu_process.c      |  2 +-
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 893af0b635..c2ae87d747 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -741,6 +741,7 @@ struct _virQEMUCaps {
 
     /* Capabilities which may differ depending on the accelerator. */
     virQEMUCapsAccel kvm;
+    virQEMUCapsAccel hvf;
     virQEMUCapsAccel tcg;
 };
 
@@ -791,13 +792,15 @@ const char *virQEMUCapsArchToString(virArch arch)
 static bool
 virQEMUCapsTypeIsAccelerated(virDomainVirtType type)
 {
-    return type == VIR_DOMAIN_VIRT_KVM;
+    return type == VIR_DOMAIN_VIRT_KVM ||
+           type == VIR_DOMAIN_VIRT_HVF;
 }
 
 static bool
 virQEMUCapsHaveAccel(virQEMUCaps *qemuCaps)
 {
-    return virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM);
+    return virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) ||
+           virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF);
 }
 
 static const char *
@@ -805,6 +808,8 @@ virQEMUCapsAccelStr(virDomainVirtType type)
 {
     if (type == VIR_DOMAIN_VIRT_KVM) {
         return "kvm";
+    } else if (type == VIR_DOMAIN_VIRT_HVF) {
+        return "hvf";
     } else {
         return "tcg";
     }
@@ -862,6 +867,8 @@ virQEMUCapsGetAccel(virQEMUCaps *qemuCaps,
 {
     if (type == VIR_DOMAIN_VIRT_KVM)
         return &qemuCaps->kvm;
+    else if (type == VIR_DOMAIN_VIRT_HVF)
+        return &qemuCaps->hvf;
 
     return &qemuCaps->tcg;
 }
@@ -992,6 +999,8 @@ virQEMUCapsGetMachineTypesCaps(virQEMUCaps *qemuCaps,
      * take the set of machine types we probed first. */
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
         accel = &qemuCaps->kvm;
+    else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
+        accel = &qemuCaps->hvf;
     else
         accel = &qemuCaps->tcg;
 
@@ -2009,6 +2018,7 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps)
     ret->cpuData = virCPUDataNewCopy(qemuCaps->cpuData);
 
     if (virQEMUCapsAccelCopy(&ret->kvm, &qemuCaps->kvm) < 0 ||
+        virQEMUCapsAccelCopy(&ret->hvf, &qemuCaps->hvf) < 0 ||
         virQEMUCapsAccelCopy(&ret->tcg, &qemuCaps->tcg) < 0)
         return NULL;
 
@@ -2062,6 +2072,7 @@ void virQEMUCapsDispose(void *obj)
     virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
 
     virQEMUCapsAccelClear(&qemuCaps->kvm);
+    virQEMUCapsAccelClear(&qemuCaps->hvf);
     virQEMUCapsAccelClear(&qemuCaps->tcg);
 }
 
@@ -2313,6 +2324,10 @@ virQEMUCapsIsVirtTypeSupported(virQEMUCaps *qemuCaps,
         virQEMUCapsGet(qemuCaps, QEMU_CAPS_TCG))
         return true;
 
+    if (virtType == VIR_DOMAIN_VIRT_HVF &&
+        virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
+        return true;
+
     if (virtType == VIR_DOMAIN_VIRT_KVM &&
         virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
         return true;
@@ -2790,7 +2805,9 @@ bool
 virQEMUCapsHasMachines(virQEMUCaps *qemuCaps)
 {
 
-    return !!qemuCaps->kvm.nmachineTypes || !!qemuCaps->tcg.nmachineTypes;
+    return !!qemuCaps->kvm.nmachineTypes ||
+           !!qemuCaps->hvf.nmachineTypes ||
+           !!qemuCaps->tcg.nmachineTypes;
 }
 
 
@@ -4718,6 +4735,7 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
                       virArchToString(qemuCaps->arch));
 
     virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_KVM);
+    virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_HVF);
     virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_QEMU);
 
     for (i = 0; i < qemuCaps->ngicCapabilities; i++) {
@@ -5577,6 +5595,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
     qemuCaps->libvirtVersion = LIBVIR_VERSION_NUMBER;
 
     virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
+    virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_HVF);
     virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
 
     if (virQEMUCapsHaveAccel(qemuCaps)) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index de1146251d..c80c9bae2d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -9288,7 +9288,7 @@ qemuProcessQMPLaunch(qemuProcessQMP *proc)
     if (proc->forceTCG)
         machine = "none,accel=tcg";
     else
-        machine = "none,accel=kvm:tcg";
+        machine = "none,accel=kvm:hvf:tcg";
 
     VIR_DEBUG("Try to probe capabilities of '%s' via QMP, machine %s",
               proc->binary, machine);
-- 
2.31.1

Re: [libvirt PATCH 09/17] qemu: Correct CPU capabilities probing for hvf
Posted by Daniel P. Berrangé 4 years, 1 month ago
On Tue, Jan 04, 2022 at 07:52:48PM +0100, Andrea Bolognani wrote:
> From: Roman Bolshakov <r.bolshakov@yadro.com>
> 
> With this change virsh domcapabilites shows:
>   <mode name='host-passthrough' supported='yes'/>
> 
> https://gitlab.com/libvirt/libvirt/-/issues/147
> 
> Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
> Signed-off-by: Andrea Bolognani <abologna@redhat.com>
> ---
>  src/qemu/qemu_capabilities.c | 25 ++++++++++++++++++++++---
>  src/qemu/qemu_process.c      |  2 +-
>  2 files changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 893af0b635..c2ae87d747 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -741,6 +741,7 @@ struct _virQEMUCaps {
>  
>      /* Capabilities which may differ depending on the accelerator. */
>      virQEMUCapsAccel kvm;
> +    virQEMUCapsAccel hvf;
>      virQEMUCapsAccel tcg;
>  };
>  
> @@ -791,13 +792,15 @@ const char *virQEMUCapsArchToString(virArch arch)
>  static bool
>  virQEMUCapsTypeIsAccelerated(virDomainVirtType type)
>  {
> -    return type == VIR_DOMAIN_VIRT_KVM;
> +    return type == VIR_DOMAIN_VIRT_KVM ||
> +           type == VIR_DOMAIN_VIRT_HVF;
>  }
>  
>  static bool
>  virQEMUCapsHaveAccel(virQEMUCaps *qemuCaps)
>  {
> -    return virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM);
> +    return virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) ||
> +           virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF);
>  }
>  
>  static const char *
> @@ -805,6 +808,8 @@ virQEMUCapsAccelStr(virDomainVirtType type)
>  {
>      if (type == VIR_DOMAIN_VIRT_KVM) {
>          return "kvm";
> +    } else if (type == VIR_DOMAIN_VIRT_HVF) {
> +        return "hvf";
>      } else {
>          return "tcg";
>      }
> @@ -862,6 +867,8 @@ virQEMUCapsGetAccel(virQEMUCaps *qemuCaps,
>  {
>      if (type == VIR_DOMAIN_VIRT_KVM)
>          return &qemuCaps->kvm;
> +    else if (type == VIR_DOMAIN_VIRT_HVF)
> +        return &qemuCaps->hvf;
>  
>      return &qemuCaps->tcg;
>  }
> @@ -992,6 +999,8 @@ virQEMUCapsGetMachineTypesCaps(virQEMUCaps *qemuCaps,
>       * take the set of machine types we probed first. */
>      if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
>          accel = &qemuCaps->kvm;
> +    else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
> +        accel = &qemuCaps->hvf;
>      else
>          accel = &qemuCaps->tcg;
>  
> @@ -2009,6 +2018,7 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps)
>      ret->cpuData = virCPUDataNewCopy(qemuCaps->cpuData);
>  
>      if (virQEMUCapsAccelCopy(&ret->kvm, &qemuCaps->kvm) < 0 ||
> +        virQEMUCapsAccelCopy(&ret->hvf, &qemuCaps->hvf) < 0 ||
>          virQEMUCapsAccelCopy(&ret->tcg, &qemuCaps->tcg) < 0)
>          return NULL;
>  
> @@ -2062,6 +2072,7 @@ void virQEMUCapsDispose(void *obj)
>      virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
>  
>      virQEMUCapsAccelClear(&qemuCaps->kvm);
> +    virQEMUCapsAccelClear(&qemuCaps->hvf);
>      virQEMUCapsAccelClear(&qemuCaps->tcg);
>  }
>  
> @@ -2313,6 +2324,10 @@ virQEMUCapsIsVirtTypeSupported(virQEMUCaps *qemuCaps,
>          virQEMUCapsGet(qemuCaps, QEMU_CAPS_TCG))
>          return true;
>  
> +    if (virtType == VIR_DOMAIN_VIRT_HVF &&
> +        virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
> +        return true;
> +
>      if (virtType == VIR_DOMAIN_VIRT_KVM &&
>          virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
>          return true;
> @@ -2790,7 +2805,9 @@ bool
>  virQEMUCapsHasMachines(virQEMUCaps *qemuCaps)
>  {
>  
> -    return !!qemuCaps->kvm.nmachineTypes || !!qemuCaps->tcg.nmachineTypes;
> +    return !!qemuCaps->kvm.nmachineTypes ||
> +           !!qemuCaps->hvf.nmachineTypes ||
> +           !!qemuCaps->tcg.nmachineTypes;
>  }
>  
>  
> @@ -4718,6 +4735,7 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
>                        virArchToString(qemuCaps->arch));
>  
>      virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_KVM);
> +    virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_HVF);
>      virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_QEMU);
>  
>      for (i = 0; i < qemuCaps->ngicCapabilities; i++) {
> @@ -5577,6 +5595,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
>      qemuCaps->libvirtVersion = LIBVIR_VERSION_NUMBER;
>  
>      virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
> +    virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_HVF);
>      virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
>  
>      if (virQEMUCapsHaveAccel(qemuCaps)) {
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index de1146251d..c80c9bae2d 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -9288,7 +9288,7 @@ qemuProcessQMPLaunch(qemuProcessQMP *proc)
>      if (proc->forceTCG)
>          machine = "none,accel=tcg";
>      else
> -        machine = "none,accel=kvm:tcg";
> +        machine = "none,accel=kvm:hvf:tcg";

Probing kvm on macos or hvf on linux doesn't make much sense. For
that matter the existing code was already mistakenlyprobing kvm
on all platforms. IMHO this should be OS conditionalized

     #ifdef __linux__
     # define tryhwaccel kvm:tcg
     #elif __APPLE__
     # define tryhwaccel hvf:tcg
     #else
     # define tryhwaccel tcg
     #endif

     if (proc->forceTCG)
         machine = "none,accel=tcg";
     else
         machine = "none,accel=" # tryhwaccel

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|