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?
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@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);