This patch maps /domain/cpu/maxphysaddr into -cpu parameters: - <maxphysaddr mode='passthrough'/> becomes host-phys-bits=on - <maxphysaddr mode='emualte' bits='42'/> becomes phys-bits=42 Passthrough mode can only be used if the chosen CPU model is 'host-passthrough'. The feature is available since QEMU 2.7.0. Signed-off-by: Dario Faggioli <dfaggioli@xxxxxxxx> --- src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 src/qemu/qemu_command.c | 28 ++++++++++++ src/qemu/qemu_domain.c | 46 ++++++++++++++++++++ tests/qemuxml2argvdata/cpu-phys-bits-emulate.args | 29 +++++++++++++ tests/qemuxml2argvdata/cpu-phys-bits-emulate.xml | 20 +++++++++ tests/qemuxml2argvdata/cpu-phys-bits-emulate2.args | 30 +++++++++++++ tests/qemuxml2argvdata/cpu-phys-bits-emulate2.xml | 20 +++++++++ tests/qemuxml2argvdata/cpu-phys-bits-emulate3.err | 1 tests/qemuxml2argvdata/cpu-phys-bits-emulate3.xml | 20 +++++++++ .../cpu-phys-bits-passthrough.args | 29 +++++++++++++ .../qemuxml2argvdata/cpu-phys-bits-passthrough.xml | 20 +++++++++ .../cpu-phys-bits-passthrough2.err | 1 .../cpu-phys-bits-passthrough2.xml | 20 +++++++++ .../cpu-phys-bits-passthrough3.err | 1 .../cpu-phys-bits-passthrough3.xml | 20 +++++++++ tests/qemuxml2argvtest.c | 7 +++ 17 files changed, 295 insertions(+) create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-emulate.args create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-emulate.xml create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-emulate2.args create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-emulate2.xml create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-emulate3.err create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-emulate3.xml create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-passthrough.args create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-passthrough.xml create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-passthrough2.err create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-passthrough2.xml create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-passthrough3.err create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-passthrough3.xml diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index a67fb785b5..70adb423f1 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -603,6 +603,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "virtio-balloon.free-page-reporting", "block-export-add", "netdev.vhost-vdpa", + "host-phys-bits", ); @@ -1679,6 +1680,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMaxCPU[] = { { "unavailable-features", QEMU_CAPS_CPU_UNAVAILABLE_FEATURES }, { "kvm-no-adjvtime", QEMU_CAPS_CPU_KVM_NO_ADJVTIME }, { "migratable", QEMU_CAPS_CPU_MIGRATABLE }, + { "host-phys-bits", QEMU_CAPS_CPU_PHYS_BITS }, }; static virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 047ba8a0ee..0fe97d2fd1 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -583,6 +583,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_VIRTIO_BALLOON_FREE_PAGE_REPORTING, /*virtio balloon free-page-reporting */ QEMU_CAPS_BLOCK_EXPORT_ADD, /* 'block-export-add' command is supported */ QEMU_CAPS_NETDEV_VHOST_VDPA, /* -netdev vhost-vdpa*/ + QEMU_CAPS_CPU_PHYS_BITS, /* -cpu phys-bits=42 or host-phys-bits=on */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 7847706594..d58f80547e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6507,6 +6507,34 @@ qemuBuildCpuCommandLine(virCommandPtr cmd, virBufferAddLit(&buf, ",l3-cache=off"); } + if (def->cpu && def->cpu->addr) { + virCPUMaxPhysAddrDefPtr addr = def->cpu->addr; + + switch (addr->mode) { + case VIR_CPU_MAX_PHYS_ADDR_MODE_PASSTHROUGH: + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_PHYS_BITS)) + virBufferAddLit(&buf, ",host-phys-bits=on"); + else + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting host physical address bits is " + "not supported by this QEMU")); + break; + + case VIR_CPU_MAX_PHYS_ADDR_MODE_EMULATE: + if (addr->bits != -1 && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_PHYS_BITS)) + virBufferAsprintf(&buf, ",phys-bits=%d", addr->bits); + else + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Physical address bits unspecified or " + "setting it not supported by this QEMU")); + break; + + case VIR_CPU_MAX_PHYS_ADDR_MODE_LAST: + break; + } + } + cpu = virBufferContentAndReset(&cpu_buf); cpu_flags = virBufferContentAndReset(&buf); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index d7dbca487a..e9f20d82a1 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4051,6 +4051,52 @@ qemuDomainDefCPUPostParse(virDomainDefPtr def, } } + if (def->cpu->addr) { + virCPUMaxPhysAddrDefPtr addr = def->cpu->addr; + + if (!ARCH_IS_X86(def->os.arch)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU maximum physical address bits specification " + "is not supported for '%s' architecture"), + virArchToString(def->os.arch)); + return -1; + } + + switch (addr->mode) { + case VIR_CPU_MAX_PHYS_ADDR_MODE_PASSTHROUGH: + if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU maximum physical address bits mode '%s' " + "can only be used with '%s' CPUs"), + virCPUMaxPhysAddrModeTypeToString(addr->mode), + virCPUModeTypeToString(VIR_CPU_MODE_HOST_PASSTHROUGH)); + return -1; + } + if (addr->bits != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU maximum physical address bits number " + "specification cannot be used with " + "mode='%s'"), + virCPUMaxPhysAddrModeTypeToString(VIR_CPU_MAX_PHYS_ADDR_MODE_PASSTHROUGH)); + return -1; + } + break; + + case VIR_CPU_MAX_PHYS_ADDR_MODE_EMULATE: + if (addr->bits == -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("if using CPU maximum physical address " + "mode='%s', bits= must be specified too"), + virCPUMaxPhysAddrModeTypeToString(VIR_CPU_MAX_PHYS_ADDR_MODE_EMULATE)); + return -1; + } + break; + + case VIR_CPU_MAX_PHYS_ADDR_MODE_LAST: + break; + } + } + for (i = 0; i < def->cpu->nfeatures; i++) { virCPUFeatureDefPtr feature = &def->cpu->features[i]; diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-emulate.args b/tests/qemuxml2argvdata/cpu-phys-bits-emulate.args new file mode 100644 index 0000000000..5627b41b25 --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-emulate.args @@ -0,0 +1,29 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-foo \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-foo/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-foo/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-foo/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name foo \ +-S \ +-machine pc,accel=kvm,usb=off,dump-guest-core=off \ +-cpu host,phys-bits=42 \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-foo/monitor.sock,server,\ +nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-usb \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-emulate.xml b/tests/qemuxml2argvdata/cpu-phys-bits-emulate.xml new file mode 100644 index 0000000000..f8bd63bc68 --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-emulate.xml @@ -0,0 +1,20 @@ +<domain type='kvm'> + <name>foo</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='host-passthrough'> + <maxphysaddr mode='emulate' bits='42'/> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-emulate2.args b/tests/qemuxml2argvdata/cpu-phys-bits-emulate2.args new file mode 100644 index 0000000000..f105f96f02 --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-emulate2.args @@ -0,0 +1,30 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-foo \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-foo/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-foo/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-foo/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name foo \ +-S \ +-machine pc,accel=kvm,usb=off,dump-guest-core=off \ +-cpu core2duo,+ds,+acpi,+ss,+ht,+tm,+pbe,+ds_cpl,+vmx,+est,+tm2,+cx16,+xtpr,\ ++lahf_lm,phys-bits=42 \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-foo/monitor.sock,server,\ +nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-usb \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-emulate2.xml b/tests/qemuxml2argvdata/cpu-phys-bits-emulate2.xml new file mode 100644 index 0000000000..188b3066ed --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-emulate2.xml @@ -0,0 +1,20 @@ +<domain type='kvm'> + <name>foo</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='host-model'> + <maxphysaddr bits='42' mode='emulate'/> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-emulate3.err b/tests/qemuxml2argvdata/cpu-phys-bits-emulate3.err new file mode 100644 index 0000000000..5e21998259 --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-emulate3.err @@ -0,0 +1 @@ +unsupported configuration: if using CPU maximum physical address mode='emulate', bits= must be specified too diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-emulate3.xml b/tests/qemuxml2argvdata/cpu-phys-bits-emulate3.xml new file mode 100644 index 0000000000..30a14894dd --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-emulate3.xml @@ -0,0 +1,20 @@ +<domain type='kvm'> + <name>foo</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='host-passthrough'> + <maxphysaddr mode='emulate'/> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-passthrough.args b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough.args new file mode 100644 index 0000000000..a4f3f55bb9 --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough.args @@ -0,0 +1,29 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-foo \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-foo/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-foo/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-foo/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name foo \ +-S \ +-machine pc,accel=kvm,usb=off,dump-guest-core=off \ +-cpu host,host-phys-bits=on \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-foo/monitor.sock,server,\ +nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-usb \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-passthrough.xml b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough.xml new file mode 100644 index 0000000000..db570beb8d --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough.xml @@ -0,0 +1,20 @@ +<domain type='kvm'> + <name>foo</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='host-passthrough'> + <maxphysaddr mode='passthrough'/> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-passthrough2.err b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough2.err new file mode 100644 index 0000000000..22009cc6e6 --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough2.err @@ -0,0 +1 @@ +unsupported configuration: CPU maximum physical address bits mode 'passthrough' can only be used with 'host-passthrough' CPUs diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-passthrough2.xml b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough2.xml new file mode 100644 index 0000000000..511bbf9949 --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough2.xml @@ -0,0 +1,20 @@ +<domain type='kvm'> + <name>foo</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='host-model'> + <maxphysaddr mode='passthrough'/> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-passthrough3.err b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough3.err new file mode 100644 index 0000000000..28f2e43432 --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough3.err @@ -0,0 +1 @@ +unsupported configuration: CPU maximum physical address bits number specification cannot be used with mode='passthrough' diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-passthrough3.xml b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough3.xml new file mode 100644 index 0000000000..a94e567dcb --- /dev/null +++ b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough3.xml @@ -0,0 +1,20 @@ +<domain type='kvm'> + <name>foo</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='host-passthrough'> + <maxphysaddr mode='passthrough' bits='42'/> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index c5a0095e0d..fd17fea744 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3409,6 +3409,13 @@ mymain(void) DO_TEST_CAPS_LATEST("virtio-9p-multidevs"); + DO_TEST("cpu-phys-bits-passthrough", QEMU_CAPS_KVM, QEMU_CAPS_CPU_PHYS_BITS); + DO_TEST("cpu-phys-bits-emulate", QEMU_CAPS_KVM, QEMU_CAPS_CPU_PHYS_BITS); + DO_TEST("cpu-phys-bits-emulate2", QEMU_CAPS_KVM, QEMU_CAPS_CPU_PHYS_BITS); + DO_TEST_PARSE_ERROR("cpu-phys-bits-emulate3", QEMU_CAPS_KVM); + DO_TEST_PARSE_ERROR("cpu-phys-bits-passthrough2", QEMU_CAPS_KVM); + DO_TEST_PARSE_ERROR("cpu-phys-bits-passthrough3", QEMU_CAPS_KVM); + if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) virFileDeleteTree(fakerootdir);