[libvirt PATCH 00/17] qemu: Introduce hvf domain type for Hypervisor.framework

In order to hopefully address [libvirt#147] at long last, I've picked up Roman's patches from 2018 and attempted to forward-port them. More specifically, I've used the [roolebo/hvf-domain] branch as a starting point, since it seems to contain a few improvements over [v2] and was just easier to pick up. The code is mostly his own, so I've retained the existing authorship information, but I've dropped Reviewed-by tags for commits that have been modified in non-trivial ways. I've applied very minimal style tweaks along the way, but overall I've tried to modify the existing patches as little as possible. I've added a few changes of my own, which I've marked as "fixup!" when I felt that they should be squashed into the previous patch rather than existing as separate commits. The new test cases, such as they are, pass, and no regressions to KVM support appear to have been introduced in the process. I don't currently have access to a machine running macOS, so I can't verify that it's actually possible to start a hardware-accelerated VM. Changes from [v2]: * rebased on top of master; * added a couple of simple test cases. Notes / to do items: * I've skipped [kvmonly] because it was not obvious how to forward-port it, and things generally seemed to work fine even without it. I have some ideas on how to integrate the logic in the current version of the code if it turns out to be necessary after all; * I've also skipped most of the changes to docs/formatdomain.rst, namely the ones that replaced "QEMU" or "QEMU/KVM" in :since: blocks. I'm not yet sure how to best deal with the situation, but adding "and HVF" everywhere is almost certainly not it; * docs/macos.html.in needs to be converted to ReStructuredText before merging. Useful links: * GitLab: [abologna/hvf] * CI: [pipeline] [libvirt#147] https://gitlab.com/libvirt/libvirt/-/issues/147 [roolebo/hvf-domain] https://github.com/roolebo/libvirt/tree/hvf-domain [abologna/hvf] https://gitlab.com/abologna/libvirt/-/commits/hvf [pipeline] https://gitlab.com/abologna/libvirt/-/pipelines/441350810 [kvmonly] https://github.com/roolebo/libvirt/commit/1752ccbfe53bf4f89f3f45e4ef96b7da7a... [v2] https://listman.redhat.com/archives/libvir-list/2018-November/msg00802.html Andrea Bolognani (4): fixup! qemu: Fix HVF architecture check tests: Add HVF support to testutilsqemu tests: Add HVF test cases fixup! NEWS: Mention Apple Silicon support for HVF Roman Bolshakov (13): conf: Add hvf domain type qemu: Define hvf capability qemu: Query hvf capability on macOS qemu: Expose hvf domain type if hvf is supported qemu: Introduce virQEMUCapsTypeIsAccelerated qemu: Introduce virQEMUCapsHaveAccel qemu: Introduce virQEMUCapsAccelStr qemu: Make error message accel-agnostic qemu: Correct CPU capabilities probing for hvf docs: Add hvf on QEMU driver page docs: Note hvf support for domain elements docs: Add support page for libvirt on macOS news: Mention hvf domain type NEWS.rst | 9 + docs/docs.html.in | 3 + docs/drvqemu.rst | 48 +++- docs/formatdomain.rst | 22 +- docs/index.html.in | 4 +- docs/macos.html.in | 229 ++++++++++++++++++ docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_capabilities.c | 107 +++++++- src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 4 + src/qemu/qemu_process.c | 2 +- .../hvf-aarch64-virt-headless.args | 48 ++++ .../hvf-aarch64-virt-headless.xml | 45 ++++ .../hvf-x86_64-q35-headless.args | 47 ++++ .../hvf-x86_64-q35-headless.xml | 44 ++++ tests/qemuxml2argvtest.c | 18 ++ .../hvf-aarch64-virt-headless.xml | 94 +++++++ .../hvf-x86_64-q35-headless.xml | 97 ++++++++ tests/qemuxml2xmltest.c | 18 ++ tests/testutilsqemu.c | 40 +++ 22 files changed, 857 insertions(+), 26 deletions(-) create mode 100644 docs/macos.html.in create mode 100644 tests/qemuxml2argvdata/hvf-aarch64-virt-headless.args create mode 100644 tests/qemuxml2argvdata/hvf-aarch64-virt-headless.xml create mode 100644 tests/qemuxml2argvdata/hvf-x86_64-q35-headless.args create mode 100644 tests/qemuxml2argvdata/hvf-x86_64-q35-headless.xml create mode 100644 tests/qemuxml2xmloutdata/hvf-aarch64-virt-headless.xml create mode 100644 tests/qemuxml2xmloutdata/hvf-x86_64-q35-headless.xml -- 2.31.1

From: Roman Bolshakov <r.bolshakov@yadro.com> QEMU supports Hypervisor.framework since 2.12 as hvf accel. Hypervisor.framework provides a lightweight interface to run a virtual cpu on macOS without the need to install third-party kernel extensions (KEXTs). It's supported since macOS 10.10 on machines with Intel VT-x feature set that includes Extended Page Tables (EPT) and Unrestricted Mode. Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/formatdomain.rst | 3 ++- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 4 ++++ 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index d4f30bb8af..3e9de05249 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -20,7 +20,8 @@ Element and attribute overview The root element required for all virtual machines is named ``domain``. It has two attributes, the ``type`` specifies the hypervisor used for running the -domain. The allowed values are driver specific, but include "xen", "kvm", "qemu" +domain. The allowed values are driver specific, but include "xen", "kvm", +"hvf" (:since:`since 8.0.0 and QEMU 2.12`), "qemu" and "lxc". The second attribute is ``id`` which is a unique integer identifier for the running guest machine. Inactive machines have no id value. diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 7fa5c2b8b5..bf9c12397f 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -230,6 +230,7 @@ <value>phyp</value> <!-- NOT USED ANYMORE --> <value>vz</value> <value>bhyve</value> + <value>hvf</value> </choice> </attribute> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5691b8d2d5..0faecf2bb4 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -125,6 +125,7 @@ VIR_ENUM_IMPL(virDomainVirt, "parallels", "bhyve", "vz", + "hvf", ); VIR_ENUM_IMPL(virDomainOS, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 144ba4dd12..d4d8aa7e23 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -139,6 +139,7 @@ typedef enum { VIR_DOMAIN_VIRT_PARALLELS, VIR_DOMAIN_VIRT_BHYVE, VIR_DOMAIN_VIRT_VZ, + VIR_DOMAIN_VIRT_HVF, VIR_DOMAIN_VIRT_LAST } virDomainVirtType; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d822533ccb..3bacf3edf2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7229,6 +7229,10 @@ qemuBuildAccelCommandLine(virCommand *cmd, } break; + case VIR_DOMAIN_VIRT_HVF: + virBufferAddLit(&buf, "hvf"); + break; + case VIR_DOMAIN_VIRT_KQEMU: case VIR_DOMAIN_VIRT_XEN: case VIR_DOMAIN_VIRT_LXC: -- 2.31.1

On Tue, Jan 04, 2022 at 07:52:40PM +0100, Andrea Bolognani wrote:
From: Roman Bolshakov <r.bolshakov@yadro.com>
QEMU supports Hypervisor.framework since 2.12 as hvf accel. Hypervisor.framework provides a lightweight interface to run a virtual cpu on macOS without the need to install third-party kernel extensions (KEXTs).
It's supported since macOS 10.10 on machines with Intel VT-x feature set that includes Extended Page Tables (EPT) and Unrestricted Mode.
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/formatdomain.rst | 3 ++- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 4 ++++ 5 files changed, 9 insertions(+), 1 deletion(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> 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 :|

From: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 1 + src/qemu/qemu_capabilities.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 4f63322a9e..7823cb3d48 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -653,6 +653,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "query-dirty-rate", /* QEMU_CAPS_QUERY_DIRTY_RATE */ "rbd-encryption", /* QEMU_CAPS_RBD_ENCRYPTION */ "sev-guest-kernel-hashes", /* QEMU_CAPS_SEV_GUEST_KERNEL_HASHES */ + "hvf", /* QEMU_CAPS_HVF */ ); diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index aaac20a834..4ffec44f6d 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -632,6 +632,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_QUERY_DIRTY_RATE, /* accepts query-dirty-rate */ QEMU_CAPS_RBD_ENCRYPTION, /* Ceph RBD encryption support */ QEMU_CAPS_SEV_GUEST_KERNEL_HASHES, /* sev-guest.kernel-hashes= */ + QEMU_CAPS_HVF, /* Whether Hypervisor.framework is available */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; -- 2.31.1

On Tue, Jan 04, 2022 at 07:52:41PM +0100, Andrea Bolognani wrote:
From: Roman Bolshakov <r.bolshakov@yadro.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 1 + src/qemu/qemu_capabilities.h | 1 + 2 files changed, 2 insertions(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> 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 :|

From: Roman Bolshakov <r.bolshakov@yadro.com> There's no QMP command for querying if hvf is supported, therefore we use sysctl interface that tells if Hypervisor.framework works/available on the host. Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 7823cb3d48..9b4f695770 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -56,6 +56,10 @@ #include <unistd.h> #include <stdarg.h> #include <sys/utsname.h> +#ifdef __APPLE__ +# include <sys/types.h> +# include <sys/sysctl.h> +#endif #define VIR_FROM_THIS VIR_FROM_QEMU @@ -3191,6 +3195,32 @@ virQEMUCapsProbeQMPKVMState(virQEMUCaps *qemuCaps, return 0; } +#ifdef __APPLE__ +static int +virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps) +{ + int hv_support; + size_t len = sizeof(hv_support); + + if (sysctlbyname("kern.hv_support", &hv_support, &len, NULL, 0) < 0) + hv_support = 0; + + if (qemuCaps->version >= 2012000 && + ARCH_IS_X86(qemuCaps->arch) && + hv_support) { + virQEMUCapsSet(qemuCaps, QEMU_CAPS_HVF); + } + + return 0; +} +#else +static int +virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps G_GNUC_UNUSED) +{ + return 0; +} +#endif + struct virQEMUCapsCommandLineProps { const char *option; const char *param; @@ -5335,6 +5365,9 @@ virQEMUCapsInitQMPMonitor(virQEMUCaps *qemuCaps, if (virQEMUCapsProbeQMPKVMState(qemuCaps, mon) < 0) return -1; + if (virQEMUCapsProbeHVF(qemuCaps) < 0) + return -1; + type = virQEMUCapsGetVirtType(qemuCaps); accel = virQEMUCapsGetAccel(qemuCaps, type); -- 2.31.1

On Tue, Jan 04, 2022 at 07:52:42PM +0100, Andrea Bolognani wrote:
From: Roman Bolshakov <r.bolshakov@yadro.com>
There's no QMP command for querying if hvf is supported, therefore we use sysctl interface that tells if Hypervisor.framework works/available on the host.
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> 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 :|

From: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 9b4f695770..ca060485fa 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1081,6 +1081,10 @@ virQEMUCapsInitGuestFromBinary(virCaps *caps, virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM, NULL, NULL, 0, NULL); } + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF)) { + virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HVF, + NULL, NULL, 0, NULL); + } if ((ARCH_IS_X86(guestarch) || guestarch == VIR_ARCH_AARCH64)) virCapabilitiesAddGuestFeatureWithToggle(guest, VIR_CAPS_GUEST_FEATURE_TYPE_ACPI, -- 2.31.1

From: Roman Bolshakov <r.bolshakov@yadro.com> It replaces hardcoded checks that select accelCPU/accelCPUModels (formerly known as kvmCPU/kvmCPUModels) for KVM. It'll be cleaner to use the function when multiple accelerators are supported in qemu driver. Explicit KVM domain checks should be done only when a feature is available only for KVM. Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index ca060485fa..e2ce2a5d07 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -788,6 +788,11 @@ const char *virQEMUCapsArchToString(virArch arch) return virArchToString(arch); } +static bool +virQEMUCapsTypeIsAccelerated(virDomainVirtType type) +{ + return type == VIR_DOMAIN_VIRT_KVM; +} /* Checks whether a domain with @guest arch can run natively on @host. */ @@ -2328,7 +2333,7 @@ virQEMUCapsIsCPUModeSupported(virQEMUCaps *qemuCaps, switch (mode) { case VIR_CPU_MODE_HOST_PASSTHROUGH: - return type == VIR_DOMAIN_VIRT_KVM && + return virQEMUCapsTypeIsAccelerated(type) && virQEMUCapsGuestIsNative(hostarch, qemuCaps->arch); case VIR_CPU_MODE_HOST_MODEL: @@ -2990,7 +2995,7 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCaps *qemuCaps, qemuMonitor *mon, virDomainVirtType virtType) { - const char *model = virtType == VIR_DOMAIN_VIRT_KVM ? "host" : "max"; + const char *model = virQEMUCapsTypeIsAccelerated(virtType) ? "host" : "max"; g_autoptr(qemuMonitorCPUModelInfo) modelInfo = NULL; g_autoptr(qemuMonitorCPUModelInfo) nonMigratable = NULL; g_autoptr(GHashTable) hash = NULL; @@ -3700,7 +3705,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps, virArchToString(qemuCaps->arch), virDomainVirtTypeToString(type)); goto error; - } else if (type == VIR_DOMAIN_VIRT_KVM && + } else if (virQEMUCapsTypeIsAccelerated(type) && virCPUGetHostIsSupported(qemuCaps->arch)) { if (!(fullCPU = virQEMUCapsProbeHostCPU(qemuCaps->arch, NULL))) goto error; @@ -5827,7 +5832,7 @@ virQEMUCapsCacheLookupDefault(virFileCache *cache, if (virttype == VIR_DOMAIN_VIRT_NONE) virttype = capsType; - if (virttype == VIR_DOMAIN_VIRT_KVM && capsType == VIR_DOMAIN_VIRT_QEMU) { + if (virQEMUCapsTypeIsAccelerated(virttype) && capsType == VIR_DOMAIN_VIRT_QEMU) { virReportError(VIR_ERR_INVALID_ARG, _("KVM is not supported by '%s' on this host"), binary); -- 2.31.1

On Tue, Jan 04, 2022 at 07:52:44PM +0100, Andrea Bolognani wrote:
From: Roman Bolshakov <r.bolshakov@yadro.com>
It replaces hardcoded checks that select accelCPU/accelCPUModels (formerly known as kvmCPU/kvmCPUModels) for KVM. It'll be cleaner to use the function when multiple accelerators are supported in qemu driver.
Explicit KVM domain checks should be done only when a feature is available only for KVM.
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index ca060485fa..e2ce2a5d07 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -788,6 +788,11 @@ const char *virQEMUCapsArchToString(virArch arch) return virArchToString(arch); }
+static bool +virQEMUCapsTypeIsAccelerated(virDomainVirtType type) +{ + return type == VIR_DOMAIN_VIRT_KVM; +}
/* Checks whether a domain with @guest arch can run natively on @host. */ @@ -2328,7 +2333,7 @@ virQEMUCapsIsCPUModeSupported(virQEMUCaps *qemuCaps,
switch (mode) { case VIR_CPU_MODE_HOST_PASSTHROUGH: - return type == VIR_DOMAIN_VIRT_KVM && + return virQEMUCapsTypeIsAccelerated(type) && virQEMUCapsGuestIsNative(hostarch, qemuCaps->arch);
case VIR_CPU_MODE_HOST_MODEL: @@ -2990,7 +2995,7 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCaps *qemuCaps, qemuMonitor *mon, virDomainVirtType virtType) { - const char *model = virtType == VIR_DOMAIN_VIRT_KVM ? "host" : "max"; + const char *model = virQEMUCapsTypeIsAccelerated(virtType) ? "host" : "max"; g_autoptr(qemuMonitorCPUModelInfo) modelInfo = NULL; g_autoptr(qemuMonitorCPUModelInfo) nonMigratable = NULL; g_autoptr(GHashTable) hash = NULL; @@ -3700,7 +3705,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps, virArchToString(qemuCaps->arch), virDomainVirtTypeToString(type)); goto error; - } else if (type == VIR_DOMAIN_VIRT_KVM && + } else if (virQEMUCapsTypeIsAccelerated(type) && virCPUGetHostIsSupported(qemuCaps->arch)) { if (!(fullCPU = virQEMUCapsProbeHostCPU(qemuCaps->arch, NULL))) goto error; @@ -5827,7 +5832,7 @@ virQEMUCapsCacheLookupDefault(virFileCache *cache, if (virttype == VIR_DOMAIN_VIRT_NONE) virttype = capsType;
- if (virttype == VIR_DOMAIN_VIRT_KVM && capsType == VIR_DOMAIN_VIRT_QEMU) { + if (virQEMUCapsTypeIsAccelerated(virttype) && capsType == VIR_DOMAIN_VIRT_QEMU) { virReportError(VIR_ERR_INVALID_ARG, _("KVM is not supported by '%s' on this host"), binary);
s/KVM/Hardware acceleration/ 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 :|

On Wed, Jan 05, 2022 at 09:18:17AM +0000, Daniel P. Berrangé wrote:
On Tue, Jan 04, 2022 at 07:52:44PM +0100, Andrea Bolognani wrote:
- if (virttype == VIR_DOMAIN_VIRT_KVM && capsType == VIR_DOMAIN_VIRT_QEMU) { + if (virQEMUCapsTypeIsAccelerated(virttype) && capsType == VIR_DOMAIN_VIRT_QEMU) { virReportError(VIR_ERR_INVALID_ARG, _("KVM is not supported by '%s' on this host"), binary);
s/KVM/Hardware acceleration/
This is changed in a later patch (8/17). Does that work for you, or do you want me to try and shuffle things around? -- Andrea Bolognani / Red Hat / Virtualization

From: Roman Bolshakov <r.bolshakov@yadro.com> The function should be used to check if qemu capabilities include a hardware acceleration, i.e. accel is not TCG. Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index e2ce2a5d07..b504963ddf 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -794,6 +794,12 @@ virQEMUCapsTypeIsAccelerated(virDomainVirtType type) return type == VIR_DOMAIN_VIRT_KVM; } +static bool +virQEMUCapsHaveAccel(virQEMUCaps *qemuCaps) +{ + return virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM); +} + /* Checks whether a domain with @guest arch can run natively on @host. */ bool @@ -4999,7 +5005,7 @@ virQEMUCapsIsValid(void *data, return false; } - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) { + if (virQEMUCapsHaveAccel(qemuCaps)) { if (STRNEQ_NULLABLE(priv->hostCPUSignature, qemuCaps->hostCPUSignature)) { VIR_DEBUG("Outdated capabilities for '%s': host CPU changed " "('%s' vs '%s')", @@ -5033,7 +5039,9 @@ virQEMUCapsIsValid(void *data, qemuCaps->binary); return false; } + } + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) { kvmSupportsNesting = virQEMUCapsKVMSupportsNesting(); if (kvmSupportsNesting != qemuCaps->kvmSupportsNesting) { VIR_DEBUG("Outdated capabilities for '%s': kvm kernel nested " @@ -5498,7 +5506,7 @@ virQEMUCapsInitQMP(virQEMUCaps *qemuCaps, * for TCG capabilities by asking the same binary again and turning KVM * off. */ - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) && + if (virQEMUCapsHaveAccel(qemuCaps) && virQEMUCapsGet(qemuCaps, QEMU_CAPS_TCG) && virQEMUCapsInitQMPSingle(qemuCaps, libDir, runUid, runGid, true) < 0) return -1; @@ -5561,13 +5569,15 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch, virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM); virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU); - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) { + if (virQEMUCapsHaveAccel(qemuCaps)) { qemuCaps->hostCPUSignature = g_strdup(hostCPUSignature); qemuCaps->microcodeVersion = microcodeVersion; qemuCaps->cpuData = virCPUDataNewCopy(cpuData); qemuCaps->kernelVersion = g_strdup(kernelVersion); + } + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) { qemuCaps->kvmSupportsNesting = virQEMUCapsKVMSupportsNesting(); qemuCaps->kvmSupportsSecureGuest = virQEMUCapsKVMSupportsSecureGuest(); -- 2.31.1

On Tue, Jan 04, 2022 at 07:52:45PM +0100, Andrea Bolognani wrote:
From: Roman Bolshakov <r.bolshakov@yadro.com>
The function should be used to check if qemu capabilities include a hardware acceleration, i.e. accel is not TCG.
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> 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 :|

From: Roman Bolshakov <r.bolshakov@yadro.com> This makes possible to add more accelerators by touching less code and reduces code duplication. Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index b504963ddf..eac1e65a39 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -800,6 +800,16 @@ virQEMUCapsHaveAccel(virQEMUCaps *qemuCaps) return virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM); } +static const char * +virQEMUCapsAccelStr(virDomainVirtType type) +{ + if (type == VIR_DOMAIN_VIRT_KVM) { + return "kvm"; + } else { + return "tcg"; + } +} + /* Checks whether a domain with @guest arch can run natively on @host. */ bool @@ -4075,7 +4085,7 @@ virQEMUCapsLoadAccel(virQEMUCaps *qemuCaps, virDomainVirtType type) { virQEMUCapsAccel *caps = virQEMUCapsGetAccel(qemuCaps, type); - const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg"; + const char *typeStr = virQEMUCapsAccelStr(type); if (virQEMUCapsLoadHostCPUModelInfo(caps, ctxt, typeStr) < 0) return -1; @@ -4624,7 +4634,7 @@ virQEMUCapsFormatAccel(virQEMUCaps *qemuCaps, virDomainVirtType type) { virQEMUCapsAccel *caps = virQEMUCapsGetAccel(qemuCaps, type); - const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg"; + const char *typeStr = virQEMUCapsAccelStr(type); virQEMUCapsFormatHostCPUModelInfo(caps, buf, typeStr); virQEMUCapsFormatCPUModels(caps, buf, typeStr); -- 2.31.1

On Tue, Jan 04, 2022 at 07:52:46PM +0100, Andrea Bolognani wrote:
From: Roman Bolshakov <r.bolshakov@yadro.com>
This makes possible to add more accelerators by touching less code and reduces code duplication.
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index b504963ddf..eac1e65a39 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -800,6 +800,16 @@ virQEMUCapsHaveAccel(virQEMUCaps *qemuCaps) return virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM); }
+static const char * +virQEMUCapsAccelStr(virDomainVirtType type) +{ + if (type == VIR_DOMAIN_VIRT_KVM) { + return "kvm"; + } else { + return "tcg"; + } +}
..... VIR_ENUM_IMPL/DECL is a better long term plan. For enum values that don't make sense for QEMU just return a placeholder or something.
+ /* Checks whether a domain with @guest arch can run natively on @host. */ bool @@ -4075,7 +4085,7 @@ virQEMUCapsLoadAccel(virQEMUCaps *qemuCaps, virDomainVirtType type) { virQEMUCapsAccel *caps = virQEMUCapsGetAccel(qemuCaps, type); - const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg"; + const char *typeStr = virQEMUCapsAccelStr(type);
if (virQEMUCapsLoadHostCPUModelInfo(caps, ctxt, typeStr) < 0) return -1; @@ -4624,7 +4634,7 @@ virQEMUCapsFormatAccel(virQEMUCaps *qemuCaps, virDomainVirtType type) { virQEMUCapsAccel *caps = virQEMUCapsGetAccel(qemuCaps, type); - const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg"; + const char *typeStr = virQEMUCapsAccelStr(type);
virQEMUCapsFormatHostCPUModelInfo(caps, buf, typeStr); virQEMUCapsFormatCPUModels(caps, buf, typeStr); -- 2.31.1
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 :|

On Wed, Jan 05, 2022 at 09:23:09AM +0000, Daniel P. Berrangé wrote:
On Tue, Jan 04, 2022 at 07:52:46PM +0100, Andrea Bolognani wrote:
+static const char * +virQEMUCapsAccelStr(virDomainVirtType type) +{ + if (type == VIR_DOMAIN_VIRT_KVM) { + return "kvm"; + } else { + return "tcg"; + } +}
..... VIR_ENUM_IMPL/DECL is a better long term plan. For enum values that don't make sense for QEMU just return a placeholder or something.
Agreed. Would you accept that as a separate patch that's still part of this series but applies after all the existing code changes? As I mention in the cover letter, I tried to keep Roman's original code intact as much as possible, and I would prefer to avoid making any non-trivial changes to it to keep the authorship story relatively straight. -- Andrea Bolognani / Red Hat / Virtualization

On Wed, Jan 05, 2022 at 01:36:23AM -0800, Andrea Bolognani wrote:
On Wed, Jan 05, 2022 at 09:23:09AM +0000, Daniel P. Berrangé wrote:
On Tue, Jan 04, 2022 at 07:52:46PM +0100, Andrea Bolognani wrote:
+static const char * +virQEMUCapsAccelStr(virDomainVirtType type) +{ + if (type == VIR_DOMAIN_VIRT_KVM) { + return "kvm"; + } else { + return "tcg"; + } +}
..... VIR_ENUM_IMPL/DECL is a better long term plan. For enum values that don't make sense for QEMU just return a placeholder or something.
Agreed. Would you accept that as a separate patch that's still part of this series but applies after all the existing code changes? As I mention in the cover letter, I tried to keep Roman's original code intact as much as possible, and I would prefer to avoid making any non-trivial changes to it to keep the authorship story relatively straight.
Would still be bisectable, so that's ok. 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 :|

From: Roman Bolshakov <r.bolshakov@yadro.com> With more acceleration types, KVM should be used only in error messages related to KVM. Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index eac1e65a39..893af0b635 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -5854,8 +5854,8 @@ virQEMUCapsCacheLookupDefault(virFileCache *cache, if (virQEMUCapsTypeIsAccelerated(virttype) && capsType == VIR_DOMAIN_VIRT_QEMU) { virReportError(VIR_ERR_INVALID_ARG, - _("KVM is not supported by '%s' on this host"), - binary); + _("the accel '%s' is not supported by '%s' on this host"), + virQEMUCapsAccelStr(virttype), binary); return NULL; } -- 2.31.1

On Tue, Jan 04, 2022 at 07:52:47PM +0100, Andrea Bolognani wrote:
From: Roman Bolshakov <r.bolshakov@yadro.com>
With more acceleration types, KVM should be used only in error messages related to KVM.
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index eac1e65a39..893af0b635 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -5854,8 +5854,8 @@ virQEMUCapsCacheLookupDefault(virFileCache *cache,
if (virQEMUCapsTypeIsAccelerated(virttype) && capsType == VIR_DOMAIN_VIRT_QEMU) { virReportError(VIR_ERR_INVALID_ARG, - _("KVM is not supported by '%s' on this host"), - binary); + _("the accel '%s' is not supported by '%s' on this host"), + virQEMUCapsAccelStr(virttype), binary); return NULL; }
This should have been part of the earlier patch that changed the code to use virQEMUCapsTypeIsAccelerated 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 :|

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

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 :|

Apple Silicon (aarch64) has HVF support, but there is no 32-bit Intel hardware that is HVF-capable. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index c2ae87d747..da66cdbb22 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -3248,7 +3248,8 @@ virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps) hv_support = 0; if (qemuCaps->version >= 2012000 && - ARCH_IS_X86(qemuCaps->arch) && + (qemuCaps->arch == VIR_ARCH_X86_64 || + qemuCaps->arch == VIR_ARCH_AARCH64) && hv_support) { virQEMUCapsSet(qemuCaps, QEMU_CAPS_HVF); } -- 2.31.1

On Tue, Jan 04, 2022 at 07:52:49PM +0100, Andrea Bolognani wrote:
Apple Silicon (aarch64) has HVF support, but there is no 32-bit Intel hardware that is HVF-capable.
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> 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 :|

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- tests/testutilsqemu.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index 7fdb82daec..a75995c77a 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -106,6 +106,18 @@ static const char *const *kvm_machines[VIR_ARCH_LAST] = { [VIR_ARCH_S390X] = s390x_machines, }; +static const char *const *hvf_machines[VIR_ARCH_LAST] = { + [VIR_ARCH_I686] = NULL, + [VIR_ARCH_X86_64] = x86_64_machines, + [VIR_ARCH_AARCH64] = aarch64_machines, + [VIR_ARCH_ARMV7L] = NULL, + [VIR_ARCH_PPC64] = NULL, + [VIR_ARCH_PPC] = NULL, + [VIR_ARCH_RISCV32] = NULL, + [VIR_ARCH_RISCV64] = NULL, + [VIR_ARCH_S390X] = NULL, +}; + static const char *qemu_default_ram_id[VIR_ARCH_LAST] = { [VIR_ARCH_I686] = "pc.ram", [VIR_ARCH_X86_64] = "pc.ram", @@ -214,6 +226,18 @@ testQemuAddGuest(virCaps *caps, NULL, nmachines, machines); } + if (hvf_machines[emu_arch] != NULL) { + nmachines = g_strv_length((char **)hvf_machines[emu_arch]); + machines = virCapabilitiesAllocMachines(hvf_machines[emu_arch], + nmachines); + if (machines == NULL) + goto error; + + virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HVF, + qemu_emulators[emu_arch], + NULL, nmachines, machines); + } + return 0; error: @@ -403,6 +427,22 @@ int qemuTestCapsCacheInsert(virFileCache *cache, virQEMUCapsSet(tmpCaps, QEMU_CAPS_KVM); } } + if (hvf_machines[i] != NULL) { + for (j = 0; hvf_machines[i][j] != NULL; j++) { + virQEMUCapsAddMachine(tmpCaps, + VIR_DOMAIN_VIRT_HVF, + hvf_machines[i][j], + NULL, + NULL, + 0, + false, + false, + true, + defaultRAMid, + false); + virQEMUCapsSet(tmpCaps, QEMU_CAPS_HVF); + } + } } if (virFileCacheInsertData(cache, qemu_emulators[i], tmpCaps) < 0) { -- 2.31.1

On Tue, Jan 04, 2022 at 07:52:50PM +0100, Andrea Bolognani wrote:
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- tests/testutilsqemu.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index 7fdb82daec..a75995c77a 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -106,6 +106,18 @@ static const char *const *kvm_machines[VIR_ARCH_LAST] = { [VIR_ARCH_S390X] = s390x_machines, };
+static const char *const *hvf_machines[VIR_ARCH_LAST] = { + [VIR_ARCH_I686] = NULL, + [VIR_ARCH_X86_64] = x86_64_machines, + [VIR_ARCH_AARCH64] = aarch64_machines, + [VIR_ARCH_ARMV7L] = NULL, + [VIR_ARCH_PPC64] = NULL, + [VIR_ARCH_PPC] = NULL, + [VIR_ARCH_RISCV32] = NULL, + [VIR_ARCH_RISCV64] = NULL, + [VIR_ARCH_S390X] = NULL, +}; + static const char *qemu_default_ram_id[VIR_ARCH_LAST] = { [VIR_ARCH_I686] = "pc.ram", [VIR_ARCH_X86_64] = "pc.ram", @@ -214,6 +226,18 @@ testQemuAddGuest(virCaps *caps, NULL, nmachines, machines); }
+ if (hvf_machines[emu_arch] != NULL) { + nmachines = g_strv_length((char **)hvf_machines[emu_arch]); + machines = virCapabilitiesAllocMachines(hvf_machines[emu_arch], + nmachines); + if (machines == NULL) + goto error; + + virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HVF, + qemu_emulators[emu_arch], + NULL, nmachines, machines); + } + return 0;
error: @@ -403,6 +427,22 @@ int qemuTestCapsCacheInsert(virFileCache *cache, virQEMUCapsSet(tmpCaps, QEMU_CAPS_KVM); } } + if (hvf_machines[i] != NULL) { + for (j = 0; hvf_machines[i][j] != NULL; j++) { + virQEMUCapsAddMachine(tmpCaps, + VIR_DOMAIN_VIRT_HVF, + hvf_machines[i][j], + NULL, + NULL, + 0, + false, + false, + true, + defaultRAMid, + false); + virQEMUCapsSet(tmpCaps, QEMU_CAPS_HVF); + } + } }
IIUC this means in tests we're going to build capabilities that indicate support for KVM and HVF at the same time. This is not a scenario that applies in the real world, so I'm a little uncomfortable with this. It is the simple option, though I would prefer if the individual tests could express "gimme capabilities for linux" vs "gimme capabilities for macOS" Also relies on fact that we don't #ifdef any of the interesting code in the QEMU driver related to KVM/HVF. Probably ok-ish assumption in most cases, at least for unit tests. 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 :|

On Wed, Jan 05, 2022 at 10:10:07AM +0000, Daniel P. Berrangé wrote:
On Tue, Jan 04, 2022 at 07:52:50PM +0100, Andrea Bolognani wrote:
+ if (hvf_machines[i] != NULL) { + for (j = 0; hvf_machines[i][j] != NULL; j++) { + virQEMUCapsAddMachine(tmpCaps, + VIR_DOMAIN_VIRT_HVF, + hvf_machines[i][j], + NULL, + NULL, + 0, + false, + false, + true, + defaultRAMid, + false); + virQEMUCapsSet(tmpCaps, QEMU_CAPS_HVF); + } + }
IIUC this means in tests we're going to build capabilities that indicate support for KVM and HVF at the same time. This is not a scenario that applies in the real world, so I'm a little uncomfortable with this. It is the simple option, though I would prefer if the individual tests could express
"gimme capabilities for linux"
vs
"gimme capabilities for macOS"
Also relies on fact that we don't #ifdef any of the interesting code in the QEMU driver related to KVM/HVF. Probably ok-ish assumption in most cases, at least for unit tests.
Yeah, ideally we'd have that and also real replies files taken from QEMU running on macOS, but I don't currently have a way to generate the latter and the former would take more development time. In the interest of unblocking macOS users who are currently unable to run hardware accelerated VMs through libvirt at all, I'm personally okay with cutting some corners and improving things later. What if I changed things so that both the HVF test cases and the testutilsqemu bit above are only built on macOS? We'd still have the weird mix of capabilities on that platform, but at least Linux would be unaffected. We run the test suite on macOS as part of our CI pipeline, so coverage wouldn't be any worse. -- Andrea Bolognani / Red Hat / Virtualization

On Wed, Jan 05, 2022 at 03:02:07AM -0800, Andrea Bolognani wrote:
On Wed, Jan 05, 2022 at 10:10:07AM +0000, Daniel P. Berrangé wrote:
On Tue, Jan 04, 2022 at 07:52:50PM +0100, Andrea Bolognani wrote:
+ if (hvf_machines[i] != NULL) { + for (j = 0; hvf_machines[i][j] != NULL; j++) { + virQEMUCapsAddMachine(tmpCaps, + VIR_DOMAIN_VIRT_HVF, + hvf_machines[i][j], + NULL, + NULL, + 0, + false, + false, + true, + defaultRAMid, + false); + virQEMUCapsSet(tmpCaps, QEMU_CAPS_HVF); + } + }
IIUC this means in tests we're going to build capabilities that indicate support for KVM and HVF at the same time. This is not a scenario that applies in the real world, so I'm a little uncomfortable with this. It is the simple option, though I would prefer if the individual tests could express
"gimme capabilities for linux"
vs
"gimme capabilities for macOS"
Also relies on fact that we don't #ifdef any of the interesting code in the QEMU driver related to KVM/HVF. Probably ok-ish assumption in most cases, at least for unit tests.
Yeah, ideally we'd have that and also real replies files taken from QEMU running on macOS, but I don't currently have a way to generate the latter and the former would take more development time. In the interest of unblocking macOS users who are currently unable to run hardware accelerated VMs through libvirt at all, I'm personally okay with cutting some corners and improving things later.
What if I changed things so that both the HVF test cases and the testutilsqemu bit above are only built on macOS? We'd still have the weird mix of capabilities on that platform, but at least Linux would be unaffected. We run the test suite on macOS as part of our CI pipeline, so coverage wouldn't be any worse.
I was thinking more like - testQemuCapsInit only adds TCG+KVM emulators - testQemuCapsInitMacOS only adds TCG+HVF emulators In qemuxml2argvtest.c do virCapsPtr linuxCaps = driver->caps driver->caps = testQemuCapsInitMacOS(); DO_TEST("hvf-blah", QEMU_CAPS_HVF, QEMU_CAPS_PIIX3_USB_UHCI, .... QEMU_CAPS_USB_HUB); virObjectUnref(driver->caps); driver->caps = linuxCaps; feels like it ought to be reasonably simple to get working 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 :|

On Wed, Jan 05, 2022 at 11:14:20AM +0000, Daniel P. Berrangé wrote:
On Wed, Jan 05, 2022 at 03:02:07AM -0800, Andrea Bolognani wrote:
What if I changed things so that both the HVF test cases and the testutilsqemu bit above are only built on macOS? We'd still have the weird mix of capabilities on that platform, but at least Linux would be unaffected. We run the test suite on macOS as part of our CI pipeline, so coverage wouldn't be any worse.
I was thinking more like
- testQemuCapsInit only adds TCG+KVM emulators - testQemuCapsInitMacOS only adds TCG+HVF emulators
In qemuxml2argvtest.c do
virCapsPtr linuxCaps = driver->caps driver->caps = testQemuCapsInitMacOS(); DO_TEST("hvf-blah", QEMU_CAPS_HVF, QEMU_CAPS_PIIX3_USB_UHCI, .... QEMU_CAPS_USB_HUB);
virObjectUnref(driver->caps); driver->caps = linuxCaps;
feels like it ought to be reasonably simple to get working
Okay, I'll give it a try. -- Andrea Bolognani / Red Hat / Virtualization

We need to use a hardcoded list of capabilities because we don't yet have proper replies files obtained from QEMU running on actual macOS machines. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- .../hvf-aarch64-virt-headless.args | 48 +++++++++ .../hvf-aarch64-virt-headless.xml | 45 +++++++++ .../hvf-x86_64-q35-headless.args | 47 +++++++++ .../hvf-x86_64-q35-headless.xml | 44 +++++++++ tests/qemuxml2argvtest.c | 18 ++++ .../hvf-aarch64-virt-headless.xml | 94 ++++++++++++++++++ .../hvf-x86_64-q35-headless.xml | 97 +++++++++++++++++++ tests/qemuxml2xmltest.c | 18 ++++ 8 files changed, 411 insertions(+) create mode 100644 tests/qemuxml2argvdata/hvf-aarch64-virt-headless.args create mode 100644 tests/qemuxml2argvdata/hvf-aarch64-virt-headless.xml create mode 100644 tests/qemuxml2argvdata/hvf-x86_64-q35-headless.args create mode 100644 tests/qemuxml2argvdata/hvf-x86_64-q35-headless.xml create mode 100644 tests/qemuxml2xmloutdata/hvf-aarch64-virt-headless.xml create mode 100644 tests/qemuxml2xmloutdata/hvf-x86_64-q35-headless.xml diff --git a/tests/qemuxml2argvdata/hvf-aarch64-virt-headless.args b/tests/qemuxml2argvdata/hvf-aarch64-virt-headless.args new file mode 100644 index 0000000000..0f1eed66c2 --- /dev/null +++ b/tests/qemuxml2argvdata/hvf-aarch64-virt-headless.args @@ -0,0 +1,48 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-test \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-test/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-test/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-test/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-aarch64 \ +-name guest=test,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-test/master-key.aes \ +-machine virt,usb=off,dump-guest-core=off,gic-version=2 \ +-accel hvf \ +-drive file=/usr/share/edk2/aarch64/QEMU_EFI-silent-pflash.raw,if=pflash,format=raw,unit=0,readonly=on \ +-drive file=/var/lib/libvirt/qemu/nvram/test_VARS.fd,if=pflash,format=raw,unit=1 \ +-m 4096 \ +-realtime mlock=off \ +-smp 2,sockets=2,cores=1,threads=1 \ +-uuid 1b826c23-8767-47ad-a6b5-c83a88277f71 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-test/monitor.sock,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc,driftfix=slew \ +-no-shutdown \ +-boot strict=on \ +-device pcie-root-port,port=8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x1 \ +-device pcie-root-port,port=9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ +-device pcie-root-port,port=10,chassis=3,id=pci.3,bus=pcie.0,addr=0x1.0x2 \ +-device pcie-root-port,port=11,chassis=4,id=pci.4,bus=pcie.0,addr=0x1.0x3 \ +-device pcie-root-port,port=12,chassis=5,id=pci.5,bus=pcie.0,addr=0x1.0x4 \ +-device pcie-root-port,port=13,chassis=6,id=pci.6,bus=pcie.0,addr=0x1.0x5 \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.2,addr=0x0 \ +-drive file=/var/lib/libvirt/images/test.qcow2,format=qcow2,if=none,id=drive-virtio-disk0 \ +-device virtio-blk-pci,bus=pci.3,addr=0x0,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 \ +-netdev user,id=hostnet0 \ +-device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:9a:e6:c6,bus=pci.1,addr=0x0 \ +-chardev pty,id=charserial0 \ +-serial chardev:charserial0 \ +-chardev socket,id=charchannel0,path=/tmp/channel/domain--1-test/org.qemu.guest_agent.0,server=on,wait=off \ +-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.4,addr=0x0 \ +-object rng-random,id=objrng0,filename=/dev/urandom \ +-device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.5,addr=0x0 \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/hvf-aarch64-virt-headless.xml b/tests/qemuxml2argvdata/hvf-aarch64-virt-headless.xml new file mode 100644 index 0000000000..ef13820e17 --- /dev/null +++ b/tests/qemuxml2argvdata/hvf-aarch64-virt-headless.xml @@ -0,0 +1,45 @@ +<domain type='hvf'> + <name>test</name> + <uuid>1b826c23-8767-47ad-a6b5-c83a88277f71</uuid> + <memory unit='KiB'>4194304</memory> + <currentMemory unit='KiB'>4194304</currentMemory> + <vcpu placement='static'>2</vcpu> + <os> + <type arch='aarch64' machine='virt'>hvm</type> + <loader readonly='yes' type='pflash'>/usr/share/edk2/aarch64/QEMU_EFI-silent-pflash.raw</loader> + <nvram>/var/lib/libvirt/qemu/nvram/test_VARS.fd</nvram> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/test.qcow2'/> + <target dev='vda' bus='virtio'/> + </disk> + <controller type='usb' model='none'/> + <interface type='user'> + <mac address='52:54:00:9a:e6:c6'/> + <model type='virtio'/> + </interface> + <console type='pty'/> + <channel type='unix'> + <target type='virtio' name='org.qemu.guest_agent.0'/> + </channel> + <memballoon model='virtio'/> + <rng model='virtio'> + <backend model='random'>/dev/urandom</backend> + </rng> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/hvf-x86_64-q35-headless.args b/tests/qemuxml2argvdata/hvf-x86_64-q35-headless.args new file mode 100644 index 0000000000..b3358e3d59 --- /dev/null +++ b/tests/qemuxml2argvdata/hvf-x86_64-q35-headless.args @@ -0,0 +1,47 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-test \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-test/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-test/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-test/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name guest=test,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-test/master-key.aes \ +-machine q35,usb=off,dump-guest-core=off \ +-accel hvf \ +-m 4096 \ +-realtime mlock=off \ +-smp 2,sockets=2,cores=1,threads=1 \ +-uuid 1b826c23-8767-47ad-a6b5-c83a88277f71 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-test/monitor.sock,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc,driftfix=slew \ +-no-hpet \ +-no-shutdown \ +-boot strict=on \ +-device pcie-root-port,port=8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x1 \ +-device pcie-root-port,port=9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ +-device pcie-root-port,port=10,chassis=3,id=pci.3,bus=pcie.0,addr=0x1.0x2 \ +-device pcie-root-port,port=11,chassis=4,id=pci.4,bus=pcie.0,addr=0x1.0x3 \ +-device pcie-root-port,port=12,chassis=5,id=pci.5,bus=pcie.0,addr=0x1.0x4 \ +-device pcie-root-port,port=13,chassis=6,id=pci.6,bus=pcie.0,addr=0x1.0x5 \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.2,addr=0x0 \ +-drive file=/var/lib/libvirt/images/test.qcow2,format=qcow2,if=none,id=drive-virtio-disk0 \ +-device virtio-blk-pci,bus=pci.3,addr=0x0,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 \ +-netdev user,id=hostnet0 \ +-device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:9a:e6:c6,bus=pci.1,addr=0x0 \ +-chardev pty,id=charserial0 \ +-device isa-serial,chardev=charserial0,id=serial0 \ +-chardev socket,id=charchannel0,path=/tmp/channel/domain--1-test/org.qemu.guest_agent.0,server=on,wait=off \ +-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.4,addr=0x0 \ +-object rng-random,id=objrng0,filename=/dev/urandom \ +-device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.5,addr=0x0 \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/hvf-x86_64-q35-headless.xml b/tests/qemuxml2argvdata/hvf-x86_64-q35-headless.xml new file mode 100644 index 0000000000..cad560e9ca --- /dev/null +++ b/tests/qemuxml2argvdata/hvf-x86_64-q35-headless.xml @@ -0,0 +1,44 @@ +<domain type='hvf'> + <name>test</name> + <uuid>1b826c23-8767-47ad-a6b5-c83a88277f71</uuid> + <memory unit='KiB'>4194304</memory> + <currentMemory unit='KiB'>4194304</currentMemory> + <vcpu placement='static'>2</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + </features> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/test.qcow2'/> + <target dev='vda' bus='virtio'/> + </disk> + <controller type='usb' model='none'/> + <interface type='user'> + <mac address='52:54:00:9a:e6:c6'/> + <model type='virtio'/> + </interface> + <console type='pty'/> + <channel type='unix'> + <target type='virtio' name='org.qemu.guest_agent.0'/> + </channel> + <memballoon model='virtio'/> + <rng model='virtio'> + <backend model='random'>/dev/urandom</backend> + </rng> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 6c67b36d5c..57435e770e 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3500,6 +3500,24 @@ mymain(void) DO_TEST_CAPS_LATEST("devices-acpi-index"); + DO_TEST("hvf-x86_64-q35-headless", + QEMU_CAPS_HVF, + QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY, + QEMU_CAPS_DEVICE_PCIE_ROOT_PORT, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_ISA_SERIAL, + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM); + DO_TEST("hvf-aarch64-virt-headless", + QEMU_CAPS_HVF, + QEMU_CAPS_OBJECT_GPEX, + QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY, + QEMU_CAPS_DEVICE_PCIE_ROOT_PORT, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_PL011, + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM); + if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) virFileDeleteTree(fakerootdir); diff --git a/tests/qemuxml2xmloutdata/hvf-aarch64-virt-headless.xml b/tests/qemuxml2xmloutdata/hvf-aarch64-virt-headless.xml new file mode 100644 index 0000000000..b5193a02b4 --- /dev/null +++ b/tests/qemuxml2xmloutdata/hvf-aarch64-virt-headless.xml @@ -0,0 +1,94 @@ +<domain type='hvf'> + <name>test</name> + <uuid>1b826c23-8767-47ad-a6b5-c83a88277f71</uuid> + <memory unit='KiB'>4194304</memory> + <currentMemory unit='KiB'>4194304</currentMemory> + <vcpu placement='static'>2</vcpu> + <os> + <type arch='aarch64' machine='virt'>hvm</type> + <loader readonly='yes' type='pflash'>/usr/share/edk2/aarch64/QEMU_EFI-silent-pflash.raw</loader> + <nvram>/var/lib/libvirt/qemu/nvram/test_VARS.fd</nvram> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <gic version='2'/> + </features> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/test.qcow2'/> + <target dev='vda' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> + </disk> + <controller type='usb' index='0' model='none'/> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='1' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='1' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/> + </controller> + <controller type='pci' index='2' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='2' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='3' port='0xa'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='4' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='4' port='0xb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/> + </controller> + <controller type='pci' index='5' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='5' port='0xc'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x4'/> + </controller> + <controller type='pci' index='6' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='6' port='0xd'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x5'/> + </controller> + <interface type='user'> + <mac address='52:54:00:9a:e6:c6'/> + <model type='virtio'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </interface> + <serial type='pty'> + <target type='system-serial' port='0'> + <model name='pl011'/> + </target> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <channel type='unix'> + <target type='virtio' name='org.qemu.guest_agent.0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <audio id='1' type='none'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> + </memballoon> + <rng model='virtio'> + <backend model='random'>/dev/urandom</backend> + <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> + </rng> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/hvf-x86_64-q35-headless.xml b/tests/qemuxml2xmloutdata/hvf-x86_64-q35-headless.xml new file mode 100644 index 0000000000..fd2b376b9b --- /dev/null +++ b/tests/qemuxml2xmloutdata/hvf-x86_64-q35-headless.xml @@ -0,0 +1,97 @@ +<domain type='hvf'> + <name>test</name> + <uuid>1b826c23-8767-47ad-a6b5-c83a88277f71</uuid> + <memory unit='KiB'>4194304</memory> + <currentMemory unit='KiB'>4194304</currentMemory> + <vcpu placement='static'>2</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + </features> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/test.qcow2'/> + <target dev='vda' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> + </disk> + <controller type='usb' index='0' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='1' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='1' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/> + </controller> + <controller type='pci' index='2' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='2' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='3' port='0xa'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='4' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='4' port='0xb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/> + </controller> + <controller type='pci' index='5' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='5' port='0xc'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x4'/> + </controller> + <controller type='pci' index='6' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='6' port='0xd'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x5'/> + </controller> + <interface type='user'> + <mac address='52:54:00:9a:e6:c6'/> + <model type='virtio'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </interface> + <serial type='pty'> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <channel type='unix'> + <target type='virtio' name='org.qemu.guest_agent.0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> + </memballoon> + <rng model='virtio'> + <backend model='random'>/dev/urandom</backend> + <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> + </rng> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index c11d415e98..322f91636c 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1451,6 +1451,24 @@ mymain(void) DO_TEST_CAPS_LATEST("devices-acpi-index"); + DO_TEST("hvf-x86_64-q35-headless", + QEMU_CAPS_HVF, + QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY, + QEMU_CAPS_DEVICE_PCIE_ROOT_PORT, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_ISA_SERIAL, + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM); + DO_TEST("hvf-aarch64-virt-headless", + QEMU_CAPS_KVM, + QEMU_CAPS_OBJECT_GPEX, + QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY, + QEMU_CAPS_DEVICE_PCIE_ROOT_PORT, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_PL011, + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM); + cleanup: if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) virFileDeleteTree(fakerootdir); -- 2.31.1

From: Roman Bolshakov <r.bolshakov@yadro.com> It's worth to make the domain type a little bit more visible than a row in news. An example of hvf domain is available on QEMU driver page. While at it, mention Hypervisor.framework on index page. Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/drvqemu.rst | 48 +++++++++++++++++++++++++++++++++++++++++++--- docs/index.html.in | 1 + 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/docs/drvqemu.rst b/docs/drvqemu.rst index e18075d865..2611194fe6 100644 --- a/docs/drvqemu.rst +++ b/docs/drvqemu.rst @@ -1,13 +1,18 @@ .. role:: since .. role:: removed -========================== -KVM/QEMU hypervisor driver -========================== +============================== +QEMU/KVM/HVF hypervisor driver +============================== The libvirt KVM/QEMU driver can manage any QEMU emulator from version 2.11.0 or later. +It supports multiple QEMU accelerators: software +emulation also known as TCG, hardware-assisted virtualization on Linux +with KVM and hardware-assisted virtualization on macOS with +Hypervisor.framework (:since:`since 8.0.0`). + .. contents:: Project Links @@ -15,6 +20,7 @@ Project Links - The `KVM <https://www.linux-kvm.org/>`__ Linux hypervisor - The `QEMU <https://wiki.qemu.org/Index.html>`__ emulator +- `Hypervisor.framework`<https://developer.apple.com/documentation/hypervisor>__` reference Deployment pre-requisites ------------------------- @@ -27,6 +33,9 @@ Deployment pre-requisites - **KVM hypervisor**: The driver will probe ``/usr/bin`` for the presence of ``qemu-kvm`` and ``/dev/kvm`` device node. If both are found, then KVM fully virtualized, hardware accelerated guests will be available. +- **Hypervisor.framework (HVF)**: The driver will probe ``sysctl`` for the + presence of ``Hypervisor.framework``. If it is found and QEMU is newer than + 2.12, then it will be possible to create hardware accelerated guests. Connections to QEMU driver -------------------------- @@ -634,3 +643,36 @@ KVM hardware accelerated guest on i686 <graphics type='vnc' port='-1' keymap='de'/> </devices> </domain> + +HVF hardware accelerated guest on x86_64 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + <domain type='hvf'> + <name>hvf-demo</name> + <uuid>4dea24b3-1d52-d8f3-2516-782e98a23fa0</uuid> + <memory>131072</memory> + <vcpu>1</vcpu> + <os> + <type arch="x86_64">hvm</type> + </os> + <features> + <acpi/> + </features> + <clock sync="localtime"/> + <devices> + <emulator>/usr/local/bin/qemu-system-x86_64</emulator> + <controller type='scsi' index='0' model='virtio-scsi'/> + <disk type='volume' device='disk'> + <driver name='qemu' type='qcow2'/> + <source pool='default' volume='myos'/> + <target bus='scsi' dev='sda'/> + </disk> + <interface type='user'> + <mac address='24:42:53:21:52:45'/> + <model type='virtio'/> + </interface> + <graphics type='vnc' port='-1'/> + </devices> + </domain> diff --git a/docs/index.html.in b/docs/index.html.in index bf164edb58..2c4aa7c6d0 100644 --- a/docs/index.html.in +++ b/docs/index.html.in @@ -21,6 +21,7 @@ <li>is accessible from C, Python, Perl, Go and more</li> <li>is licensed under open source licenses</li> <li>supports <a href="drvqemu.html">KVM</a>, + <a href="drvqemu.html">Hypervisor.framework</a>, <a href="drvqemu.html">QEMU</a>, <a href="drvxen.html">Xen</a>, <a href="drvvirtuozzo.html">Virtuozzo</a>, <a href="drvesx.html">VMWare ESX</a>, -- 2.31.1

From: Roman Bolshakov <r.bolshakov@yadro.com> Many domain elements have "QEMU and KVM only" or "QEMU/KVM since x.y.z" remarks. Most of the elements work for HVF domain, so it makes sense to add respective notices for HVF domain. All the elements have been manually tested. Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/formatdomain.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 3e9de05249..e27fb23119 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -1426,7 +1426,8 @@ In case no restrictions need to be put on CPU model and its features, a simpler :since:`Since 7.1.0` with the QEMU driver. Both ``host-model`` and ``host-passthrough`` modes make sense when a domain - can run directly on the host CPUs (for example, domains with type ``kvm``). + can run directly on the host CPUs (for example, domains with type ``kvm`` + or ``hvf``). The actual host CPU is irrelevant for domains with emulated virtual CPUs (such as domains with type ``qemu``). However, for backward compatibility ``host-model`` may be implemented even for domains running on emulated CPUs @@ -1750,7 +1751,7 @@ Each of these states allow for the same four possible actions. The domain will be terminated and then restarted with a new name. (Only supported by the libxl hypervisor driver.) -QEMU/KVM supports the ``on_poweroff`` and ``on_reboot`` events handling the +QEMU/KVM/HVF supports the ``on_poweroff`` and ``on_reboot`` events handling the ``destroy`` and ``restart`` actions, but the combination of ``on_poweroff`` set to ``restart`` and ``on_reboot`` set to ``destroy`` is forbidden. @@ -1885,8 +1886,8 @@ are: Physical address extension mode allows 32-bit guests to address more than 4 GB of memory. ``acpi`` - ACPI is useful for power management, for example, with KVM guests it is - required for graceful shutdown to work. + ACPI is useful for power management, for example, with KVM or HVF guests it + is required for graceful shutdown to work. ``apic`` APIC allows the use of programmable IRQ management. :since:`Since 0.10.2 (QEMU only)` there is an optional attribute ``eoi`` with values ``on`` and @@ -6195,14 +6196,16 @@ A video device. You can provide the amount of video memory in kibibytes (blocks of 1024 bytes) using ``vram``. This is supported only for guest type of "vz", "qemu", - "vbox", "vmx" and "xen". If no value is provided the default is used. If the + "kvm", "hvf", "vbox", "vmx" and "xen". + If no value is provided the default is used. If the size is not a power of two it will be rounded to closest one. The number of screen can be set using ``heads``. This is supported only for - guests type of "vz", "kvm", "vbox" and "vmx". + guests type of "vz", "kvm", "hvf", "vbox" and "vmx". - For guest type of "kvm" or "qemu" and model type "qxl" there are optional - attributes. Attribute ``ram`` ( :since:`since 1.0.2` ) specifies the size of + For guest type of "kvm", "hvf" or "qemu" and model type "qxl" there are + optional attributes. + Attribute ``ram`` ( :since:`since 1.0.2` ) specifies the size of the primary bar, while the attribute ``vram`` specifies the secondary bar size. If ``ram`` or ``vram`` are not supplied a default value is used. The ``ram`` should also be rounded to power of two as ``vram``. There is also -- 2.31.1

From: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/docs.html.in | 3 + docs/index.html.in | 3 +- docs/macos.html.in | 229 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 docs/macos.html.in diff --git a/docs/docs.html.in b/docs/docs.html.in index 8132090762..225827b693 100644 --- a/docs/docs.html.in +++ b/docs/docs.html.in @@ -16,6 +16,9 @@ <dt><a href="windows.html">Windows</a></dt> <dd>Downloads for Windows</dd> + <dt><a href="macos.html">macOS</a></dt> + <dd>Working with libvirt on macOS</dd> + <dt><a href="migration.html">Migration</a></dt> <dd>Migrating guests between machines</dd> diff --git a/docs/index.html.in b/docs/index.html.in index 2c4aa7c6d0..3c065badb7 100644 --- a/docs/index.html.in +++ b/docs/index.html.in @@ -28,7 +28,8 @@ <a href="drvlxc.html">LXC</a>, <a href="drvbhyve.html">BHyve</a> and <a href="drivers.html">more</a></li> - <li>targets Linux, FreeBSD, <a href="windows.html">Windows</a> and macOS</li> + <li>targets Linux, FreeBSD, <a href="windows.html">Windows</a> and + <a href="macos.html">macOS</a></li> <li>is used by many <a href="apps.html">applications</a></li> </ul> <p>Recent / forthcoming <a href="news.html">release changes</a></p> diff --git a/docs/macos.html.in b/docs/macos.html.in new file mode 100644 index 0000000000..54c93ea2fb --- /dev/null +++ b/docs/macos.html.in @@ -0,0 +1,229 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml"> + <body> + <h1 >macOS support</h1> + + <ul id="toc"></ul> + + <p> + Libvirt works both as client and server (for <a href="drvqemu.html"> + "qemu" domain</a>) on macOS High Sierra (10.13) and macOS Mojave (10.14) + since 4.7.0. Other macOS variants likely work but we neither tested nor + received reports for them. + </p> + + <p> + <a href="drvqemu.html">"hvf" domain type</a> adds support of <a + href="https://developer.apple.com/documentation/hypervisor"> + Hypervisor.framework</a> since 4.10.0. To use "hvf" domain, QEMU must + be at least 2.12 and macOS must be no less than Yosemite (10.10). "hvf" + domain type is similar to "kvm" but it has less features. + </p> + + <p> + Hypervisor.framework is available on your machine if the sysctl command + returns 1: + + <pre>sysctl -n kern.hv_support</pre> + </p> + + <h2><a id="installation">Installation</a></h2> + + <p> + libvirt client (virsh), server (libvirtd) and development headers can be + installed from <a href="https://brew.sh">homebrew</a>: + + <pre>brew install libvirt</pre> + + <a href="http://virt-manager.org">virt-manager and virt-viewer</a> can be + installed from source via <a + href="https://github.com/jeffreywildman/homebrew-virt-manager"> + Jeffrey Wildman's tap</a>: + + <pre>brew tap jeffreywildman/homebrew-virt-manager +brew install virt-manager virt-viewer</pre> + </p> + + <h2><a id='local-libvirtd'>Running libvirtd locally</a></h2> + + <p> + The server can be started manually: + <pre>libvirtd</pre> + or on system boot: + <pre>brew services start libvirt</pre> + </p> + <p> + Once started, you can use virsh to work with libvirtd: + <pre>virsh define domain.xml +virsh start domain +virsh shutdown domain</pre> + + For more details on virsh, please see <a href="virshcmdref.html">virsh + command reference</a> or built-in help: + <pre>virsh help</pre> + </p> + + <p> + Domain XML examples can be found on <a href="drvqemu.html#xmlconfig">QEMU + driver page</a>. Full reference is available on <a + href="formatdomain.html">domain XML format page</a>. + </p> + + <p> + You can use virt-manager to connect to libvirtd (connection URI must be + specified on the first connection, then it'll be possible to omit it): + <pre>virt-manager -c qemu:///session</pre> + or, if you only need an access to the virtual display of a VM you can use + virt-viewer: + <pre>virt-viewer -c qemu:///session</pre> + </p> + + <h2><a id="external-hypervisors">Working with external hypervisors</a></h2> + <p> + Details on the example domain XML files, capabilities and connection + string syntax used for connecting to external hypervisors can be found + online on <a href="drivers.html">hypervisor specific driver + pages</a>. + </p> + + <h2><a id="tlscerts">TLS Certificates</a></h2> + + <p> + TLS certificates must be placed in the correct locations, before you will + be able to connect to QEMU servers over TLS. + </p> + + <p> + Information on generating TLS certificates can be found here: + </p> + + <a href="http://wiki.libvirt.org/page/TLSSetup">http://wiki.libvirt.org/page/TLSSetup</a> + + <p> + The Certificate Authority (CA) certificate file must be placed in: + </p> + + <ul> + <li>~/.cache/libvirt/pki/CA/cacert.pem</li> + </ul> + + <p> + The Client certificate file must be placed in: + </p> + + <ul> + <li>~/.cache/libvirt/pki/libvirt/clientcert.pem</li> + </ul> + + <p> + The Client key file must be placed in: + </p> + + <ul> + <li>~/.cache/libvirt/pki/libvirt/private/clientkey.pem</li> + </ul> + + <h2><a id="known-issues">Known issues</a></h2> + <p> + This is a list of issues that can be easily fixed and provide + substantial improvement of user experience: + </p> + <ul> + <li> + virt-install doesn't work unless disks are created upfront. The reason + is because VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA sets + preallocate=falloc which is not supported by qemu-img on macOS. + </li> + <li> + "hvf" is not default domain type when virt-install connects to the + local libvirtd on macOS + </li> + <li> + QXL VGA device and SPICE display cannot be used unless QEMU is compiled + with SPICE server. The changes to build and run SPICE server on macOS + haven't been sent to upstream yet. + </li> + <li> + "make check" reports many failing tests on macOS. Some of the tests + need to be adopted to run both on Linux and macOS. + </li> + <li> + "make syntax-check" needs be fixed too, it depends on GNU version of + grep but uses system (BSD) grep. + </li> + <li> + QEMU from homebrew is compiled without USB redirection support. + </li> + <li> + CPU usage is not gathered for VMs and therefore cannot be dispalyed in + virt-manager. + </li> + <li> + libvirtd logs are noisy because some features are missing. + </li> + </ul> + + <h2><a id="missing-features">Missing features</a></h2> + <p> + "hvf" is a new domain type and can't be compared to "kvm" feature-wise. + "kvm" domain relies on QEMU backend devices implemented in Linux kernel + such as para-virtualized vhost devices and PCI-passthrough with vfio. + + Nonetheless, some of the features available in "kvm" domain can be + implemented in userspace for "hvf" domain. + </p> + <ul> + <li> + Instruction emulation in "hvf" accelerator is not mature. The bugs are + tracked on <a + href="https://bugs.launchpad.net/qemu/+bugs?field.tag=hvf">QEMU bug + tracker</a>. + </li> + <li> + Power Management notifications are not implemented, therefore guests + cannot respond to <a + href="https://developer.apple.com/library/archive/qa/qa1340/_index.html"> + sleep events on the host</a>. + </li> + <li> + CPU pinning doesn't work but macOS provides <a + href="https://developer.apple.com/library/archive/releasenotes/Performance/RN-AffinityAPI/"> + Thread Affinity API</a> that can be used to implement it. + </li> + <li> + Network management is not available but macOS has an API that is used + by ifconfig to create bridge and tap devices. So, it should be possible + to implement network management and bridged networking. + </li> + <li> + Filesystem pass-through is not available. + </li> + <li> + PCI/SCSI/USB pass-through is not available. + </li> + </ul> + + + <h2><a id="feedback">Feedback</a></h2> + + <p> + Feedback and suggestions on changes and what else to include + <a href="contact.html">are desired</a>. + </p> + + <h2><a id="compiling">Compiling yourself</a></h2> + + <p> + Use these options when following the instructions on the + <a href="compiling.html">Compiling</a> page. + </p> + +<pre> +./configure \ + --without-wireshark-dissector \ + --without-dbus +</pre> + + </body> +</html> -- 2.31.1

On Tue, Jan 04, 2022 at 07:52:54PM +0100, Andrea Bolognani wrote:
From: Roman Bolshakov <r.bolshakov@yadro.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/docs.html.in | 3 + docs/index.html.in | 3 +- docs/macos.html.in | 229 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 docs/macos.html.in
diff --git a/docs/docs.html.in b/docs/docs.html.in index 8132090762..225827b693 100644 --- a/docs/docs.html.in +++ b/docs/docs.html.in @@ -16,6 +16,9 @@ <dt><a href="windows.html">Windows</a></dt> <dd>Downloads for Windows</dd>
+ <dt><a href="macos.html">macOS</a></dt> + <dd>Working with libvirt on macOS</dd> + <dt><a href="migration.html">Migration</a></dt> <dd>Migrating guests between machines</dd>
diff --git a/docs/index.html.in b/docs/index.html.in index 2c4aa7c6d0..3c065badb7 100644 --- a/docs/index.html.in +++ b/docs/index.html.in @@ -28,7 +28,8 @@ <a href="drvlxc.html">LXC</a>, <a href="drvbhyve.html">BHyve</a> and <a href="drivers.html">more</a></li> - <li>targets Linux, FreeBSD, <a href="windows.html">Windows</a> and macOS</li> + <li>targets Linux, FreeBSD, <a href="windows.html">Windows</a> and + <a href="macos.html">macOS</a></li> <li>is used by many <a href="apps.html">applications</a></li> </ul> <p>Recent / forthcoming <a href="news.html">release changes</a></p> diff --git a/docs/macos.html.in b/docs/macos.html.in new file mode 100644 index 0000000000..54c93ea2fb --- /dev/null +++ b/docs/macos.html.in @@ -0,0 +1,229 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml"> + <body> + <h1 >macOS support</h1> + + <ul id="toc"></ul> + + <p> + Libvirt works both as client and server (for <a href="drvqemu.html"> + "qemu" domain</a>) on macOS High Sierra (10.13) and macOS Mojave (10.14) + since 4.7.0. Other macOS variants likely work but we neither tested nor + received reports for them. + </p>
Per our platform support matrixs we only target 2 most recent versions which will be Monteray and Big Sur. I don't think we should mention platforms at all here as it will be frequently getting out of date.
+ <p> + <a href="drvqemu.html">"hvf" domain type</a> adds support of <a + href="https://developer.apple.com/documentation/hypervisor"> + Hypervisor.framework</a> since 4.10.0. To use "hvf" domain, QEMU must + be at least 2.12 and macOS must be no less than Yosemite (10.10). "hvf" + domain type is similar to "kvm" but it has less features. + </p>
Since 8.0.0 not 4.10.0
+ + <h2><a id="installation">Installation</a></h2> + + <p> + libvirt client (virsh), server (libvirtd) and development headers can be + installed from <a href="https://brew.sh">homebrew</a>: + + <pre>brew install libvirt</pre> + + <a href="http://virt-manager.org">virt-manager and virt-viewer</a> can be + installed from source via <a + href="https://github.com/jeffreywildman/homebrew-virt-manager"> + Jeffrey Wildman's tap</a>: + + <pre>brew tap jeffreywildman/homebrew-virt-manager +brew install virt-manager virt-viewer</pre> + </p>
This hasn't been touched in 3 years, so I'm not convinced we should be pointing people to it.
+ <h2><a id='local-libvirtd'>Running libvirtd locally</a></h2> + + <p> + The server can be started manually: + <pre>libvirtd</pre> + or on system boot: + <pre>brew services start libvirt</pre> + </p> + <p> + Once started, you can use virsh to work with libvirtd:
This doesn't distinguish between system and session mode at all.
+ <pre>virsh define domain.xml +virsh start domain +virsh shutdown domain</pre> + + For more details on virsh, please see <a href="virshcmdref.html">virsh + command reference</a> or built-in help: + <pre>virsh help</pre> + </p> + + <p> + Domain XML examples can be found on <a href="drvqemu.html#xmlconfig">QEMU + driver page</a>. Full reference is available on <a + href="formatdomain.html">domain XML format page</a>. + </p> + + <p> + You can use virt-manager to connect to libvirtd (connection URI must be + specified on the first connection, then it'll be possible to omit it): + <pre>virt-manager -c qemu:///session</pre> + or, if you only need an access to the virtual display of a VM you can use + virt-viewer: + <pre>virt-viewer -c qemu:///session</pre> + </p>
Do we really want to start documenting apps here, we don't for any other platform.
+ <h2><a id="external-hypervisors">Working with external hypervisors</a></h2> + <p> + Details on the example domain XML files, capabilities and connection + string syntax used for connecting to external hypervisors can be found + online on <a href="drivers.html">hypervisor specific driver + pages</a>. + </p> + + <h2><a id="tlscerts">TLS Certificates</a></h2> + + <p> + TLS certificates must be placed in the correct locations, before you will + be able to connect to QEMU servers over TLS. + </p> + + <p> + Information on generating TLS certificates can be found here: + </p> + + <a href="http://wiki.libvirt.org/page/TLSSetup">http://wiki.libvirt.org/page/TLSSetup</a> + + <p> + The Certificate Authority (CA) certificate file must be placed in: + </p> + + <ul> + <li>~/.cache/libvirt/pki/CA/cacert.pem</li> + </ul> + + <p> + The Client certificate file must be placed in: + </p> + + <ul> + <li>~/.cache/libvirt/pki/libvirt/clientcert.pem</li> + </ul> + + <p> + The Client key file must be placed in: + </p> + + <ul> + <li>~/.cache/libvirt/pki/libvirt/private/clientkey.pem</li> + </ul>
This is just repeating stuff we've already documented elsewhere. Presumably this was inspired by the windows.html page. The latter was justified due to wierd windows paths, but macOS paths are just our normal ones.
+ <h2><a id="known-issues">Known issues</a></h2> + <p> + This is a list of issues that can be easily fixed and provide + substantial improvement of user experience: + </p> + <ul> + <li> + virt-install doesn't work unless disks are created upfront. The reason + is because VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA sets + preallocate=falloc which is not supported by qemu-img on macOS. + </li>
This isn't the place for talking about bugs in apps.
+ <li> + "hvf" is not default domain type when virt-install connects to the + local libvirtd on macOS + </li>
Likewise
+ <li> + QXL VGA device and SPICE display cannot be used unless QEMU is compiled + with SPICE server. The changes to build and run SPICE server on macOS + haven't been sent to upstream yet. + </li>
"Feature X can't be used unless QEMU is built with feature X enabled" is true of any optional QEMU feture. This doesn't need to be specially documented by libvirt IMHO.
+ <li> + "make check" reports many failing tests on macOS. Some of the tests + need to be adopted to run both on Linux and macOS. + </li>
Is that still the case, I thought we fixed it.
+ <li> + "make syntax-check" needs be fixed too, it depends on GNU version of + grep but uses system (BSD) grep. + </li>
8526abc454ad0c2d8eb456c6753e2e333960cc4f made it use gsed
+ <li> + QEMU from homebrew is compiled without USB redirection support. + </li>
Not something libvirt needs to document, even if it is still true
+ <li> + CPU usage is not gathered for VMs and therefore cannot be dispalyed in
displayed
+ virt-manager. + </li> + <li> + libvirtd logs are noisy because some features are missing. + </li> + </ul> + + <h2><a id="missing-features">Missing features</a></h2> + <p> + "hvf" is a new domain type and can't be compared to "kvm" feature-wise. + "kvm" domain relies on QEMU backend devices implemented in Linux kernel + such as para-virtualized vhost devices and PCI-passthrough with vfio.
This sentance doesn't make any sense. HVF can certainly be compared to KVM featurewise. KVM has no dependancy on / expectation of devices being impl in the Linux kernel. If using KVM, then you can optionally take advantage of other Linux features for device backends. HVF and KVM are approximately equivalent. macOS however lacks kerenl accelerated device backends.
+ <ul> + <li> + Instruction emulation in "hvf" accelerator is not mature. The bugs are + tracked on <a + href="https://bugs.launchpad.net/qemu/+bugs?field.tag=hvf">QEMU bug + tracker</a>.
QEMU doesn't use launchpad any more.
+ </li>
+ <h2><a id="compiling">Compiling yourself</a></h2> + + <p> + Use these options when following the instructions on the + <a href="compiling.html">Compiling</a> page. + </p> + +<pre> +./configure \ + --without-wireshark-dissector \ + --without-dbus
We don't use autoconf any more. ALso if either of those options were required it would be considered a bug - we should auto-select all features We should just not document any of this, since standard build instructions should apply.
+</pre> + + </body> +</html> -- 2.31.1
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 :|

On Wed, Jan 05, 2022 at 10:04:59AM +0000, Daniel P. Berrangé wrote:
On Tue, Jan 04, 2022 at 07:52:54PM +0100, Andrea Bolognani wrote:
+ <p> + <a href="drvqemu.html">"hvf" domain type</a> adds support of <a + href="https://developer.apple.com/documentation/hypervisor"> + Hypervisor.framework</a> since 4.10.0. To use "hvf" domain, QEMU must + be at least 2.12 and macOS must be no less than Yosemite (10.10). "hvf" + domain type is similar to "kvm" but it has less features. + </p>
Since 8.0.0 not 4.10.0
Yeah, I basically didn't touch this at all because I wanted to convert it to ReStructuredText first - we should really not add any HTML documents to the repository at this point. In the respin, I'll perform the conversion and apply your feedback. -- Andrea Bolognani / Red Hat / Virtualization

From: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- NEWS.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 313b4f52b6..29a39da9dd 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -47,6 +47,14 @@ v8.0.0 (unreleased) Libvirt is now able to set the size of translation block cache size (tb-size) for TCG domains. + * qemu: Add hvf domain type for Hypervisor.framework + + QEMU introduced experimental support of Hypervisor.framework + since 2.12. + + It's supported on machines with Intel VT-x feature set that includes + Extended Page Tables (EPT) and Unrestricted Mode since macOS 10.10. + * **Improvements** * libxl: Implement the virDomainGetMessages API -- 2.31.1

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- NEWS.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS.rst b/NEWS.rst index 29a39da9dd..2e1b576979 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -53,7 +53,8 @@ v8.0.0 (unreleased) since 2.12. It's supported on machines with Intel VT-x feature set that includes - Extended Page Tables (EPT) and Unrestricted Mode since macOS 10.10. + Extended Page Tables (EPT) and Unrestricted Mode, as well as recent + machines powered by Apple Silicon, since macOS 10.10. * **Improvements** -- 2.31.1
participants (2)
-
Andrea Bolognani
-
Daniel P. Berrangé