On Thu, Oct 29, 2020 at 5:07 PM Dario Faggioli <dfaggi...@suse.com> wrote:
> 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 > I can't thank you enough Dario for starting this, I have waited for this quite a while and never found the time for it myself :-/ Looking at my todo notes I wondered if while touching it we should right away also add host-phys-bits-limit in the same spot? See https://git.qemu.org/?p=qemu.git;a=commit;h=258fe08bd341d > 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 <dfaggi...@suse.com> > --- > 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); > > > > -- Christian Ehrhardt Staff Engineer, Ubuntu Server Canonical Ltd