diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0771598fb5..3f65b8adc7 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6838,6 +6838,23 @@ qemuBuildCpuCommandLine(virCommand *cmd,
virBufferAddLit(&buf, ",l3-cache=off");
}
+ if (def->cpu && def->cpu->addr) {
+ virCPUMaxPhysAddrDef *addr = def->cpu->addr;
+
+ switch (addr->mode) {
+ case VIR_CPU_MAX_PHYS_ADDR_MODE_PASSTHROUGH:
+ virBufferAddLit(&buf, ",host-phys-bits=on");
+ break;
+
+ case VIR_CPU_MAX_PHYS_ADDR_MODE_EMULATE:
+ virBufferAsprintf(&buf, ",phys-bits=%d", addr->bits);
+ break;
+
+ case VIR_CPU_MAX_PHYS_ADDR_MODE_LAST:
+ break;
+ }
+ }
+
cpu = virBufferContentAndReset(&cpu_buf);
cpu_flags = virBufferContentAndReset(&buf);
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 66085a63a6..41349829de 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -366,6 +366,14 @@ qemuValidateDomainDefCpu(virQEMUDriver *driver,
virCPUMaxPhysAddrModeTypeToString(VIR_CPU_MAX_PHYS_ADDR_MODE_EMULATE));
return -1;
}
+
+ if (driver->hostcpu &&
+ driver->hostcpu->addr &&
+ cpu->addr->bits > driver->hostcpu->addr->bits) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("The number of virtual CPU address bits cannot exceed the number supported by the host CPU"));
+ return -1;
+ }
break;
case VIR_CPU_MAX_PHYS_ADDR_MODE_LAST:
diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-emulate.args b/tests/qemuxml2argvdata/cpu-phys-bits-emulate.args
new file mode 100644
index 0000000000..f612f6889b
--- /dev/null
+++ b/tests/qemuxml2argvdata/cpu-phys-bits-emulate.args
@@ -0,0 +1,32 @@
+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 guest=foo,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-foo/master-key.aes \
+-machine pc,usb=off,dump-guest-core=off \
+-accel kvm \
+-cpu host,phys-bits=42 \
+-m 214 \
+-overcommit mem-lock=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,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-usb \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \
+-msg timestamp=on
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 @@
+
+ foo
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+
+
diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-emulate2.args b/tests/qemuxml2argvdata/cpu-phys-bits-emulate2.args
new file mode 100644
index 0000000000..3489f44ded
--- /dev/null
+++ b/tests/qemuxml2argvdata/cpu-phys-bits-emulate2.args
@@ -0,0 +1,32 @@
+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 guest=foo,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-foo/master-key.aes \
+-machine pc,usb=off,dump-guest-core=off \
+-accel kvm \
+-cpu core2duo,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,ds-cpl=on,vmx=on,est=on,tm2=on,cx16=on,xtpr=on,lahf-lm=on,phys-bits=42 \
+-m 214 \
+-overcommit mem-lock=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,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-usb \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \
+-msg timestamp=on
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 @@
+
+ foo
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+
+
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 @@
+
+ foo
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+
+
diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-passthrough.args b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough.args
new file mode 100644
index 0000000000..df04195d1e
--- /dev/null
+++ b/tests/qemuxml2argvdata/cpu-phys-bits-passthrough.args
@@ -0,0 +1,32 @@
+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 guest=foo,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-foo/master-key.aes \
+-machine pc,usb=off,dump-guest-core=off \
+-accel kvm \
+-cpu host,host-phys-bits=on \
+-m 214 \
+-overcommit mem-lock=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,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-usb \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \
+-msg timestamp=on
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 @@
+
+ foo
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+
+
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 @@
+
+ foo
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+
+
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 @@
+
+ foo
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index bebe4f08a3..7831441976 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -3476,6 +3476,13 @@ mymain(void)
/* HVF guests should not work on Linux with KVM */
DO_TEST_CAPS_LATEST_PARSE_ERROR("hvf-x86_64-q35-headless");
+ DO_TEST("cpu-phys-bits-passthrough", QEMU_CAPS_KVM);
+ DO_TEST("cpu-phys-bits-emulate", QEMU_CAPS_KVM);
+ DO_TEST("cpu-phys-bits-emulate2", QEMU_CAPS_KVM);
+ 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);