Add a limit attribute to restrict the maximum physical address bits
that would be used for the guest CPU:
<cpu mode='host-passthrough'>
<maxphysaddr mode='passthrough' limit='39'/>
</cpu>
https://gitlab.com/libvirt/libvirt/-/issues/450
https://bugzilla.redhat.com/show_bug.cgi?id=2171860
Signed-off-by: Ján Tomko <jtomko(a)redhat.com>
---
docs/formatdomain.rst | 7 ++++-
src/conf/cpu_conf.c | 13 ++++++++
src/conf/cpu_conf.h | 1 +
src/conf/schemas/cputypes.rng | 5 +++
.../qemuxml2argvdata/cpu-phys-bits-limit.xml | 20 ++++++++++++
.../cpu-phys-bits-limit.x86_64-latest.xml | 31 +++++++++++++++++++
tests/qemuxml2xmltest.c | 2 ++
7 files changed, 78 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/cpu-phys-bits-limit.xml
create mode 100644 tests/qemuxml2xmloutdata/cpu-phys-bits-limit.x86_64-latest.xml
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index cb3fe3dc1c..f5bbfdc20a 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1374,7 +1374,7 @@ following collection of elements. :since:`Since 0.7.5`
<cpu mode='host-passthrough' migratable='off'>
<cache mode='passthrough'/>
- <maxphysaddr mode='passthrough'/>
+ <maxphysaddr mode='passthrough' limit='39'/>
<feature policy='disable' name='lahf_lm'/>
...
@@ -1644,6 +1644,11 @@ In case no restrictions need to be put on CPU model and its
features, a simpler
The ``bits`` attribute is mandatory if the ``mode`` attribute is set to
``emulate`` and specifies the virtual CPU address size in bits.
+ ``limit``
+ The ``limit`` attribute can be used to restrict the maximum value of
+ address bits for ``passthrough`` mode, i.e. in case the host CPU reports
+ more bits than that, ``limit`` is used. :since:`Since 9.3.0`
+
Guest NUMA topology can be specified using the ``numa`` element. :since:`Since
0.9.8`
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 2b361d2c68..98adb0e5d5 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -668,6 +668,17 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
VIR_XML_PROP_NONNEGATIVE,
&def->addr->bits, -1) < 0)
return -1;
+
+ if ((rv = virXMLPropUInt(maxphysaddrNode, "limit", 10,
+ VIR_XML_PROP_NONZERO,
+ &def->addr->limit)) < 0) {
+ return -1;
+ } else if (rv > 0 && def->addr->mode !=
VIR_CPU_MAX_PHYS_ADDR_MODE_PASSTHROUGH) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("attribute 'limit' is only supported for
maxphysaddr mode 'passthrough'"));
+ return -1;
+ }
+
}
*cpu = g_steal_pointer(&def);
@@ -843,6 +854,8 @@ virCPUDefFormatBuf(virBuffer *buf,
virCPUMaxPhysAddrModeTypeToString(def->addr->mode));
if (def->addr->bits != -1)
virBufferAsprintf(buf, " bits='%d'",
def->addr->bits);
+ if (def->addr->limit > 0)
+ virBufferAsprintf(buf, " limit='%d'",
def->addr->limit);
virBufferAddLit(buf, "/>\n");
}
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index 82083d668c..3e4c53675c 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -128,6 +128,7 @@ VIR_ENUM_DECL(virCPUMaxPhysAddrMode);
typedef struct _virCPUMaxPhysAddrDef virCPUMaxPhysAddrDef;
struct _virCPUMaxPhysAddrDef {
int bits; /* -1 for unspecified */
+ unsigned int limit; /* 0 for unspecified */
virCPUMaxPhysAddrMode mode;
};
diff --git a/src/conf/schemas/cputypes.rng b/src/conf/schemas/cputypes.rng
index 3e79bdd563..db1aa57158 100644
--- a/src/conf/schemas/cputypes.rng
+++ b/src/conf/schemas/cputypes.rng
@@ -318,6 +318,11 @@
<ref name="unsignedInt"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="limit">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </optional>
</element>
</define>
diff --git a/tests/qemuxml2argvdata/cpu-phys-bits-limit.xml
b/tests/qemuxml2argvdata/cpu-phys-bits-limit.xml
new file mode 100644
index 0000000000..aabfb77523
--- /dev/null
+++ b/tests/qemuxml2argvdata/cpu-phys-bits-limit.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' limit='39'/>
+ </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/qemuxml2xmloutdata/cpu-phys-bits-limit.x86_64-latest.xml
b/tests/qemuxml2xmloutdata/cpu-phys-bits-limit.x86_64-latest.xml
new file mode 100644
index 0000000000..ced2d9c5ca
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/cpu-phys-bits-limit.x86_64-latest.xml
@@ -0,0 +1,31 @@
+<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' check='none'
migratable='on'>
+ <maxphysaddr mode='passthrough' limit='39'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index b1bc6e9216..598a8d9065 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -1247,6 +1247,8 @@ mymain(void)
DO_TEST_CAPS_LATEST("crypto-builtin");
+ DO_TEST_CAPS_LATEST("cpu-phys-bits-limit");
+
cleanup:
qemuTestDriverFree(&driver);
virFileWrapperClearPrefixes();
--
2.39.2