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 <[email protected]>
---
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



_______________________________________________
pve-devel mailing list
[email protected]
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to