[pve-devel] [RFC qemu-server v2 4/4] machine: warn intel-iommu users about too large address width
Daniel Kral
d.kral at proxmox.com
Tue Sep 2 13:22:01 CEST 2025
Similarily to the guest address width exceeding the vIOMMU address
width, also warn users about the Intel vIOMMU address width being larger
than the maximum allowed value, the maximum guest address width, as
reported by the hardware.
Signed-off-by: Daniel Kral <d.kral at proxmox.com>
---
I only added this as it was relatively cheap to implement now, but the
user will be stopped by starting the VM anyway by issuing something
like:
kvm: -device vfio-pci,host=0000:00:02.0,id=hostpci0,bus=pci.0,addr=0x10:
vfio 0000:00:02.0: Failed to set vIOMMU: aw-bits 48 > host aw-bits 39
src/PVE/QemuServer/Machine.pm | 16 ++++++++++++++++
src/test/run_config2command_tests.pl | 8 ++++++++
2 files changed, 24 insertions(+)
diff --git a/src/PVE/QemuServer/Machine.pm b/src/PVE/QemuServer/Machine.pm
index c083a27b..18b4a1b5 100644
--- a/src/PVE/QemuServer/Machine.pm
+++ b/src/PVE/QemuServer/Machine.pm
@@ -133,12 +133,28 @@ sub assert_valid_machine_property {
}
}
+sub get_maximum_iommu_address_width {
+ my $max_iommu_aw_bits;
+
+ if (-d "/sys/class/iommu/dmar0") {
+ my $cap = PVE::Tools::file_read_firstline("/sys/class/iommu/dmar0/intel-iommu/cap");
+ # bits 21:16 contain the host's iommu maximum guest address width (MGAW) value
+ # hex(...) warns on 64-bit hex values, so use substr(...) to retrieve needed byte
+ $max_iommu_aw_bits = (hex("0x" . substr($cap, -6, 2)) & 0x3F) + 1;
+ }
+
+ return $max_iommu_aw_bits;
+}
+
sub check_valid_iommu_address_width {
my ($machine_conf, $machine_version, $cpu_aw_bits) = @_;
if ($machine_conf->{viommu} && $machine_conf->{viommu} eq 'intel') {
my $iommu_aw_bits_default = min_version($machine_version, 9, 2) ? 48 : 39;
my $iommu_aw_bits = $machine_conf->{'aw-bits'} // $iommu_aw_bits_default;
+ my $max_iommu_aw_bits = get_maximum_iommu_address_width();
+ warn "Intel vIOMMU address width larger than maximum: $iommu_aw_bits > $max_iommu_aw_bits\n"
+ if $iommu_aw_bits && $max_iommu_aw_bits && $iommu_aw_bits > $max_iommu_aw_bits;
warn "guest address width exceeds vIOMMU address width: $cpu_aw_bits > $iommu_aw_bits\n"
if $cpu_aw_bits && $iommu_aw_bits && $cpu_aw_bits > $iommu_aw_bits;
}
diff --git a/src/test/run_config2command_tests.pl b/src/test/run_config2command_tests.pl
index 0623b5c1..7594c52a 100755
--- a/src/test/run_config2command_tests.pl
+++ b/src/test/run_config2command_tests.pl
@@ -350,6 +350,14 @@ $qemu_server_config->mock(
},
);
+my $qemu_server_machine;
+$qemu_server_machine = Test::MockModule->new('PVE::QemuServer::Machine');
+$qemu_server_machine->mock(
+ get_maximum_iommu_address_width => sub {
+ return 48;
+ },
+);
+
my $qemu_server_memory;
$qemu_server_memory = Test::MockModule->new('PVE::QemuServer::Memory');
$qemu_server_memory->mock(
--
2.47.2
More information about the pve-devel
mailing list