public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH qemu-server/docs/manager v7 0/4] vIOMMU-Feature #3784
@ 2023-10-12 10:02 Markus Frank
  2023-10-12 10:02 ` [pve-devel] [PATCH qemu-server v7 1/4] machine as property-string Markus Frank
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Markus Frank @ 2023-10-12 10:02 UTC (permalink / raw)
  To: pve-devel

I was able to clarify any ambiguity regarding vIOMMU:
https://lists.gnu.org/archive/html/qemu-devel/2023-10/msg02370.html

The iommu_platform parameter could be made an optional parameter for VirtIO
devices to add more isolation (with the downside of making them less performant)
in a follow-up patch series.

qemu-server:

v7:
* changed viommu to string and added virtio-iommu implementation
* seperated "machine as property-string" patch from "feature #3784" patch
* moved format definition/parsing/printing to QemuServer::Machine
* merged test-cases into "feature #3784" patch
* removed kvm check, since it does not prevent vIOMMU from working
(only nested virtualization requires kvm & host cpu)

v6:
* added helper function for machine config validation
* replaced old standard option for "pve-qemu-machine" to new property string

v5:
* set $kvm to 1 if is_native, so that api kvm check works.

v4:
* added kvm/q35 checks in API
* reused pve-qemu-machine

v3:
* replaced old machine type with property-string with viommu-parameter

v2:
* moved viommu-parameter inside of machine_fmt and added it the new
parameter machine_properties
new Config -> machine_properties: viommu=1,etc
* check if kvm and q35 are set


Markus Frank (2):
  machine as property-string
  feature #3784: Parameter for guest vIOMMU + test-cases

 PVE/API2/Qemu.pm                        | 11 ++++-
 PVE/QemuConfig.pm                       |  3 +-
 PVE/QemuServer.pm                       | 28 +++++++-----
 PVE/QemuServer/Machine.pm               | 60 ++++++++++++++++++++++++-
 test/cfg2cmd/q35-viommu-intel.conf      |  1 +
 test/cfg2cmd/q35-viommu-intel.conf.cmd  | 23 ++++++++++
 test/cfg2cmd/q35-viommu-virtio.conf     |  1 +
 test/cfg2cmd/q35-viommu-virtio.conf.cmd | 23 ++++++++++
 8 files changed, 135 insertions(+), 15 deletions(-)
 create mode 100644 test/cfg2cmd/q35-viommu-intel.conf
 create mode 100644 test/cfg2cmd/q35-viommu-intel.conf.cmd
 create mode 100644 test/cfg2cmd/q35-viommu-virtio.conf
 create mode 100644 test/cfg2cmd/q35-viommu-virtio.conf.cmd


docs:

v7:
* added virtio-iommu documentation
* changed and seperated requirements

v6:
* changed capitalization and rephrased the text a bit.

v5:
* changed Host and VM Requirements

Markus Frank (1):
  added vIOMMU documentation

 qm-pci-passthrough.adoc | 53 +++++++++++++++++++++++++++++++++++++++++
 qm.adoc                 |  1 +
 2 files changed, 54 insertions(+)


manager:

v7:
* changed viommu checkbox to ComboBox to select either none, intel or VirtIO

v6:
* replaced '=== "1"' check with PVE.Parser.parseBoolean
* replaced hidden kvm ui with view property
* a few style changes

v5:
* added check if kvm is undefined or null

v4:
* check if kvm is enabled
* added kvm+q35 hint

Markus Frank (1):
  ui: MachineEdit with viommu ComboBox

 www/manager6/qemu/MachineEdit.js | 45 ++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

-- 
2.39.2





^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] [PATCH qemu-server v7 1/4] machine as property-string
  2023-10-12 10:02 [pve-devel] [PATCH qemu-server/docs/manager v7 0/4] vIOMMU-Feature #3784 Markus Frank
@ 2023-10-12 10:02 ` Markus Frank
  2023-10-12 10:02 ` [pve-devel] [PATCH qemu-server v7 2/4] feature #3784: Parameter for guest vIOMMU + test-cases Markus Frank
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Markus Frank @ 2023-10-12 10:02 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Markus Frank <m.frank@proxmox.com>
---
 PVE/API2/Qemu.pm          |  9 +++++++--
 PVE/QemuConfig.pm         |  3 ++-
 PVE/QemuServer.pm         | 16 ++++++---------
 PVE/QemuServer/Machine.pm | 42 +++++++++++++++++++++++++++++++++++++--
 4 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 9606e72..93f0f9b 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -1043,11 +1043,13 @@ __PACKAGE__->register_method({
 			$conf->{vmgenid} = PVE::QemuServer::generate_uuid();
 		    }
 
-		    my $machine = $conf->{machine};
+		    my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
+		    my $machine = $machine_conf->{type};
 		    if (!$machine || $machine =~ m/^(?:pc|q35|virt)$/) {
 			# always pin Windows' machine version on create, they get to easily confused
 			if (PVE::QemuServer::Helpers::windows_version($conf->{ostype})) {
-			    $conf->{machine} = PVE::QemuServer::windows_get_pinned_machine_version($machine);
+			    $machine_conf->{type} = PVE::QemuServer::windows_get_pinned_machine_version($machine);
+			    $conf->{machine} = PVE::QemuServer::Machine::print_machine($machine_conf);
 			}
 		    }
 
@@ -1880,6 +1882,9 @@ my $update_vm_api  = sub {
 			);
 		    }
 		    $conf->{pending}->{$opt} = $param->{$opt};
+		} elsif ($opt eq 'machine') {
+		    my $machine_conf = PVE::QemuServer::Machine::parse_machine($param->{$opt});
+		    $conf->{pending}->{$opt} = $param->{$opt};
 		} else {
 		    $conf->{pending}->{$opt} = $param->{$opt};
 
diff --git a/PVE/QemuConfig.pm b/PVE/QemuConfig.pm
index 10e6929..6f86bb1 100644
--- a/PVE/QemuConfig.pm
+++ b/PVE/QemuConfig.pm
@@ -433,7 +433,8 @@ sub __snapshot_rollback_hook {
 	} else {
 	    # Note: old code did not store 'machine', so we try to be smart
 	    # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
-	    $data->{forcemachine} = $conf->{machine} || 'pc-i440fx-1.4';
+	    my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
+	    $data->{forcemachine} = $machine_conf->{type} || 'pc-i440fx-1.4';
 
 	    # we remove the 'machine' configuration if not explicitly specified
 	    # in the original config.
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index bf1de17..7791373 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -118,14 +118,6 @@ PVE::JSONSchema::register_standard_option('pve-qm-stateuri', {
     optional => 1,
 });
 
-PVE::JSONSchema::register_standard_option('pve-qemu-machine', {
-	description => "Specifies the QEMU machine type.",
-	type => 'string',
-	pattern => '(pc|pc(-i440fx)?-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|q35|pc-q35-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|virt(?:-\d+(\.\d+)+)?(\+pve\d+)?)',
-	maxLength => 40,
-	optional => 1,
-});
-
 # FIXME: remove in favor of just using the INotify one, it's cached there exactly the same way
 my $nodename_cache;
 sub nodename {
@@ -2204,8 +2196,9 @@ sub qemu_created_version_fixups {
     # check if we need to apply some handling for VMs that always use the latest machine version but
     # had a machine version transition happen that affected HW such that, e.g., an OS config change
     # would be required (we do not want to pin machine version for non-windows OS type)
+    my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
     if (
-	(!defined($conf->{machine}) || $conf->{machine} =~ m/^(?:pc|q35|virt)$/) # non-versioned machine
+	(!defined($machine_conf->{type}) || $machine_conf->{type} =~ m/^(?:pc|q35|virt)$/) # non-versioned machine
 	&& (!defined($meta->{'creation-qemu'}) || !min_version($meta->{'creation-qemu'}, 6, 1)) # created before 6.1
 	&& (!$forced_vers || min_version($forced_vers, 6, 1)) # handle snapshot-rollback/migrations
 	&& min_version($kvmver, 6, 1) # only need to apply the change since 6.1
@@ -3364,7 +3357,8 @@ sub windows_get_pinned_machine_version {
 sub get_vm_machine {
     my ($conf, $forcemachine, $arch, $add_pve_version, $kvmversion) = @_;
 
-    my $machine = $forcemachine || $conf->{machine};
+    my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
+    my $machine = $forcemachine || $machine_conf->{type};
 
     if (!$machine || $machine =~ m/^(?:pc|q35|virt)$/) {
 	$kvmversion //= kvm_user_version();
@@ -3609,6 +3603,8 @@ sub config_to_command {
     my $kvm = $conf->{kvm};
     my $nodename = nodename();
 
+    my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
+
     my $arch = get_vm_arch($conf);
     my $kvm_binary = get_command_for_arch($arch);
     my $kvmver = kvm_user_version($kvm_binary);
diff --git a/PVE/QemuServer/Machine.pm b/PVE/QemuServer/Machine.pm
index d9429ed..cb729ca 100644
--- a/PVE/QemuServer/Machine.pm
+++ b/PVE/QemuServer/Machine.pm
@@ -5,6 +5,7 @@ use warnings;
 
 use PVE::QemuServer::Helpers;
 use PVE::QemuServer::Monitor;
+use PVE::JSONSchema qw(get_standard_option parse_property_string);
 
 # Bump this for VM HW layout changes during a release (where the QEMU machine
 # version stays the same)
@@ -12,10 +13,46 @@ our $PVE_MACHINE_VERSION = {
     '4.1' => 2,
 };
 
+my $machine_fmt = {
+    type => {
+	default_key => 1,
+	description => "Specifies the QEMU machine type.",
+	type => 'string',
+	pattern => '(pc|pc(-i440fx)?-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|q35|pc-q35-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|virt(?:-\d+(\.\d+)+)?(\+pve\d+)?)',
+	maxLength => 40,
+	format_description => 'machine type',
+	optional => 1,
+    },
+};
+
+PVE::JSONSchema::register_format('pve-qemu-machine-fmt', $machine_fmt);
+
+PVE::JSONSchema::register_standard_option('pve-qemu-machine', {
+    description => "Specify the QEMU machine type.",
+    type => 'string',
+    optional => 1,
+    format => PVE::JSONSchema::get_format('pve-qemu-machine-fmt'),
+});
+
+sub parse_machine {
+    my ($value) = @_;
+
+    return if !$value;
+
+    my $res = parse_property_string($machine_fmt, $value);
+    return $res;
+}
+
+sub print_machine {
+    my ($machine_conf) = @_;
+    return print_property_string($machine_conf, $machine_fmt);
+}
+
 sub machine_type_is_q35 {
     my ($conf) = @_;
 
-    return $conf->{machine} && ($conf->{machine} =~ m/q35/) ? 1 : 0;
+    my $machine_conf = parse_machine($conf->{machine});
+    return $machine_conf->{type} && ($machine_conf->{type} =~ m/q35/) ? 1 : 0;
 }
 
 sub current_from_query_machines {
@@ -120,7 +157,8 @@ sub qemu_machine_pxe {
 
     my $machine =  get_current_qemu_machine($vmid);
 
-    if ($conf->{machine} && $conf->{machine} =~ m/\.pxe$/) {
+    my $machine_conf = parse_machine($conf->{machine});
+    if ($machine_conf->{type} && $machine_conf->{type} =~ m/\.pxe$/) {
 	$machine .= '.pxe';
     }
 
-- 
2.39.2





^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] [PATCH qemu-server v7 2/4] feature #3784: Parameter for guest vIOMMU + test-cases
  2023-10-12 10:02 [pve-devel] [PATCH qemu-server/docs/manager v7 0/4] vIOMMU-Feature #3784 Markus Frank
  2023-10-12 10:02 ` [pve-devel] [PATCH qemu-server v7 1/4] machine as property-string Markus Frank
@ 2023-10-12 10:02 ` Markus Frank
  2023-10-12 10:02 ` [pve-devel] [PATCH docs v7 3/4] added vIOMMU documentation Markus Frank
  2023-10-12 10:02 ` [pve-devel] [PATCH manager v7 4/4] ui: MachineEdit with viommu ComboBox Markus Frank
  3 siblings, 0 replies; 5+ messages in thread
From: Markus Frank @ 2023-10-12 10:02 UTC (permalink / raw)
  To: pve-devel

vIOMMU enables the option to passthrough pci devices to L2 VMs
in L1 VMs via Nested Virtualisation.

Currently there are two vIOMMU implementation in QEMU to choose:
intel & virtio

virtio-iommu is more recent but less used in production than intel-iommu.

Intel IOMMU:
-machine ...,kernel-irqchip=split
-device intel-iommu

Virtio IOMMU:
-device virtio-iommu-pci

Signed-off-by: Markus Frank <m.frank@proxmox.com>
---
 PVE/API2/Qemu.pm                        |  2 ++
 PVE/QemuServer.pm                       | 12 ++++++++++++
 PVE/QemuServer/Machine.pm               | 20 +++++++++++++++++++-
 test/cfg2cmd/q35-viommu-intel.conf      |  1 +
 test/cfg2cmd/q35-viommu-intel.conf.cmd  | 23 +++++++++++++++++++++++
 test/cfg2cmd/q35-viommu-virtio.conf     |  1 +
 test/cfg2cmd/q35-viommu-virtio.conf.cmd | 23 +++++++++++++++++++++++
 7 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 test/cfg2cmd/q35-viommu-intel.conf
 create mode 100644 test/cfg2cmd/q35-viommu-intel.conf.cmd
 create mode 100644 test/cfg2cmd/q35-viommu-virtio.conf
 create mode 100644 test/cfg2cmd/q35-viommu-virtio.conf.cmd

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 93f0f9b..7177d55 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -1052,6 +1052,7 @@ __PACKAGE__->register_method({
 			    $conf->{machine} = PVE::QemuServer::Machine::print_machine($machine_conf);
 			}
 		    }
+		    PVE::QemuServer::Machine::check_machine_config($conf, $machine_conf);
 
 		    PVE::QemuConfig->write_config($vmid, $conf);
 
@@ -1884,6 +1885,7 @@ my $update_vm_api  = sub {
 		    $conf->{pending}->{$opt} = $param->{$opt};
 		} elsif ($opt eq 'machine') {
 		    my $machine_conf = PVE::QemuServer::Machine::parse_machine($param->{$opt});
+		    PVE::QemuServer::Machine::check_machine_config($conf, $machine_conf);
 		    $conf->{pending}->{$opt} = $param->{$opt};
 		} else {
 		    $conf->{pending}->{$opt} = $param->{$opt};
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 7791373..fa2a773 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -4170,6 +4170,18 @@ sub config_to_command {
     }
     push @$machineFlags, "type=${machine_type_min}";
 
+    PVE::QemuServer::Machine::check_machine_config($conf, $machine_conf);
+
+    if ($machine_conf->{viommu}) {
+	if ($machine_conf->{viommu} eq 'intel') {
+	    unshift @$devices, '-device', 'intel-iommu,intremap=on,caching-mode=on';
+	    push @$machineFlags, 'kernel-irqchip=split';
+	}
+	if ($machine_conf->{viommu} eq 'virtio') {
+	    push @$devices, '-device', 'virtio-iommu-pci';
+	}
+    }
+
     push @$cmd, @$devices;
     push @$cmd, '-rtc', join(',', @$rtcFlags) if scalar(@$rtcFlags);
     push @$cmd, '-machine', join(',', @$machineFlags) if scalar(@$machineFlags);
diff --git a/PVE/QemuServer/Machine.pm b/PVE/QemuServer/Machine.pm
index cb729ca..66e0041 100644
--- a/PVE/QemuServer/Machine.pm
+++ b/PVE/QemuServer/Machine.pm
@@ -23,12 +23,19 @@ my $machine_fmt = {
 	format_description => 'machine type',
 	optional => 1,
     },
+    viommu => {
+	type => 'string',
+	description => "Enable/disable guest vIOMMU"
+	    ." (needs kvm to be enabled and q35 to be set as machine type).",
+	enum => ['intel', 'virtio'],
+	optional => 1,
+    },
 };
 
 PVE::JSONSchema::register_format('pve-qemu-machine-fmt', $machine_fmt);
 
 PVE::JSONSchema::register_standard_option('pve-qemu-machine', {
-    description => "Specify the QEMU machine type.",
+    description => "Specify the QEMU machine type & enable/disable vIOMMU.",
     type => 'string',
     optional => 1,
     format => PVE::JSONSchema::get_format('pve-qemu-machine-fmt'),
@@ -48,6 +55,17 @@ sub print_machine {
     return print_property_string($machine_conf, $machine_fmt);
 }
 
+sub check_machine_config {
+    my ($conf, $machine_conf) = @_;
+    my $q35 = $machine_conf->{type} && ($machine_conf->{type} =~ m/q35/) ? 1 : 0;
+    my $kvm = $conf->{kvm};
+    my $arch = PVE::QemuServer::get_vm_arch($conf);
+    $kvm //= 1 if PVE::QemuServer::is_native($arch);
+    if ($machine_conf->{viommu} && $machine_conf->{viommu} eq "intel" && !$q35) {
+	die "to use Intel vIOMMU please set the machine type to q35\n";
+    }
+}
+
 sub machine_type_is_q35 {
     my ($conf) = @_;
 
diff --git a/test/cfg2cmd/q35-viommu-intel.conf b/test/cfg2cmd/q35-viommu-intel.conf
new file mode 100644
index 0000000..e500ab0
--- /dev/null
+++ b/test/cfg2cmd/q35-viommu-intel.conf
@@ -0,0 +1 @@
+machine: q35,viommu=intel
diff --git a/test/cfg2cmd/q35-viommu-intel.conf.cmd b/test/cfg2cmd/q35-viommu-intel.conf.cmd
new file mode 100644
index 0000000..24e873d
--- /dev/null
+++ b/test/cfg2cmd/q35-viommu-intel.conf.cmd
@@ -0,0 +1,23 @@
+/usr/bin/kvm \
+  -id 8006 \
+  -name 'vm8006,debug-threads=on' \
+  -no-shutdown \
+  -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \
+  -mon 'chardev=qmp,mode=control' \
+  -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect=5' \
+  -mon 'chardev=qmp-event,mode=control' \
+  -pidfile /var/run/qemu-server/8006.pid \
+  -daemonize \
+  -smp '1,sockets=1,cores=1,maxcpus=1' \
+  -nodefaults \
+  -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \
+  -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \
+  -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \
+  -m 512 \
+  -device 'intel-iommu,intremap=on,caching-mode=on' \
+  -readconfig /usr/share/qemu-server/pve-q35-4.0.cfg \
+  -device 'usb-tablet,id=tablet,bus=ehci.0,port=1' \
+  -device 'VGA,id=vga,bus=pcie.0,addr=0x1' \
+  -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
+  -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
+  -machine 'type=q35+pve0,kernel-irqchip=split'
diff --git a/test/cfg2cmd/q35-viommu-virtio.conf b/test/cfg2cmd/q35-viommu-virtio.conf
new file mode 100644
index 0000000..d31b339
--- /dev/null
+++ b/test/cfg2cmd/q35-viommu-virtio.conf
@@ -0,0 +1 @@
+machine: type=q35,viommu=virtio
diff --git a/test/cfg2cmd/q35-viommu-virtio.conf.cmd b/test/cfg2cmd/q35-viommu-virtio.conf.cmd
new file mode 100644
index 0000000..294c353
--- /dev/null
+++ b/test/cfg2cmd/q35-viommu-virtio.conf.cmd
@@ -0,0 +1,23 @@
+/usr/bin/kvm \
+  -id 8006 \
+  -name 'vm8006,debug-threads=on' \
+  -no-shutdown \
+  -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \
+  -mon 'chardev=qmp,mode=control' \
+  -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect=5' \
+  -mon 'chardev=qmp-event,mode=control' \
+  -pidfile /var/run/qemu-server/8006.pid \
+  -daemonize \
+  -smp '1,sockets=1,cores=1,maxcpus=1' \
+  -nodefaults \
+  -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \
+  -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \
+  -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \
+  -m 512 \
+  -readconfig /usr/share/qemu-server/pve-q35-4.0.cfg \
+  -device 'usb-tablet,id=tablet,bus=ehci.0,port=1' \
+  -device 'VGA,id=vga,bus=pcie.0,addr=0x1' \
+  -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
+  -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
+  -device virtio-iommu-pci \
+  -machine 'type=q35+pve0'
-- 
2.39.2





^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] [PATCH docs v7 3/4] added vIOMMU documentation
  2023-10-12 10:02 [pve-devel] [PATCH qemu-server/docs/manager v7 0/4] vIOMMU-Feature #3784 Markus Frank
  2023-10-12 10:02 ` [pve-devel] [PATCH qemu-server v7 1/4] machine as property-string Markus Frank
  2023-10-12 10:02 ` [pve-devel] [PATCH qemu-server v7 2/4] feature #3784: Parameter for guest vIOMMU + test-cases Markus Frank
@ 2023-10-12 10:02 ` Markus Frank
  2023-10-12 10:02 ` [pve-devel] [PATCH manager v7 4/4] ui: MachineEdit with viommu ComboBox Markus Frank
  3 siblings, 0 replies; 5+ messages in thread
From: Markus Frank @ 2023-10-12 10:02 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Markus Frank <m.frank@proxmox.com>
---
 qm-pci-passthrough.adoc | 53 +++++++++++++++++++++++++++++++++++++++++
 qm.adoc                 |  1 +
 2 files changed, 54 insertions(+)

diff --git a/qm-pci-passthrough.adoc b/qm-pci-passthrough.adoc
index b90a0b9..7f7d4a7 100644
--- a/qm-pci-passthrough.adoc
+++ b/qm-pci-passthrough.adoc
@@ -408,6 +408,59 @@ properly used with HA and hardware changes are detected and non root users
 can configure them. See xref:resource_mapping[Resource Mapping]
 for details on that.
 
+[[qm_pci_viommu]]
+vIOMMU (emulated IOMMU)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Using the vIOMMU option allows you to to passthrough PCI devices to layer-2
+VMs in layer-1 VMs via
+https://pve.proxmox.com/wiki/Nested_Virtualization[nested virtualization].
+There are currently two vIOMMU implementations available: Intel and VirtIO.
+
+Host requirement:
+
+* Add `intel_iommu=on` or `amd_iommu=on` depending on your CPU to your kernel
+command line.
+
+Nested virtualization VM requirement:
+
+* Enable *kvm* and use the *host* cpu type to use nested virtualization.
+
+Intel vIOMMU
+^^^^^^^^^^^^
+
+Intel vIOMMU specific VM requirements:
+
+* Whether you are using an Intel or AMD CPU on your host, it is important to set
+`intel_iommu=on` in the VMs kernel parameters.
+
+* To use Intel vIOMMU you need to set *q35* as the machine type.
+
+If all requirements are met, you can add `viommu=intel` to the machine parameter
+in the configuration of the VM that should be able to passthrough PCI devices.
+
+----
+# qm set VMID -machine q35,viommu=intel
+----
+
+https://wiki.qemu.org/Features/VT-d[QEMU documentation for VT-d]
+
+VirtIO vIOMMU
+^^^^^^^^^^^^^
+
+This vIOMMU implementation is more recent and does not have as many limitations
+as Intel vIOMMU but is currently less used in production and less documentated.
+
+With VirtIO vIOMMU there is *no* need to set any kernel parameters.
+It is also *not* necessary to use q35 as the machine type, but it is advisable
+if you want to use PCIe.
+
+----
+# qm set VMID -machine q35,viommu=virtio
+----
+
+https://web.archive.org/web/20230804075844/https://michael2012z.medium.com/virtio-iommu-789369049443[Blog-Post by Michael Zhao explaining virtio-iommu]
+
 ifdef::wiki[]
 
 See Also
diff --git a/qm.adoc b/qm.adoc
index b3c3034..2e5b109 100644
--- a/qm.adoc
+++ b/qm.adoc
@@ -145,6 +145,7 @@ default https://en.wikipedia.org/wiki/Intel_440FX[Intel 440FX] or the
 https://ark.intel.com/content/www/us/en/ark/products/31918/intel-82q35-graphics-and-memory-controller.html[Q35]
 chipset, which also provides a virtual PCIe bus, and thus may be desired if
 one wants to pass through PCIe hardware.
+Additionally, you can select a xref:qm_pci_viommu[vIOMMU] implementation.
 
 [[qm_hard_disk]]
 Hard Disk
-- 
2.39.2





^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] [PATCH manager v7 4/4] ui: MachineEdit with viommu ComboBox
  2023-10-12 10:02 [pve-devel] [PATCH qemu-server/docs/manager v7 0/4] vIOMMU-Feature #3784 Markus Frank
                   ` (2 preceding siblings ...)
  2023-10-12 10:02 ` [pve-devel] [PATCH docs v7 3/4] added vIOMMU documentation Markus Frank
@ 2023-10-12 10:02 ` Markus Frank
  3 siblings, 0 replies; 5+ messages in thread
From: Markus Frank @ 2023-10-12 10:02 UTC (permalink / raw)
  To: pve-devel

Added a proxmoxKVComboBox for selecting a vIOMMU implementation for a
VM. If i440fx is selected, a hint tells that q35 is required for Intel vIOMMU.

The UI also needs to parse the new machine parameter as PropertyString.

Signed-off-by: Markus Frank <m.frank@proxmox.com>
---
 www/manager6/qemu/MachineEdit.js | 45 ++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/www/manager6/qemu/MachineEdit.js b/www/manager6/qemu/MachineEdit.js
index f928c80c..b9e42f14 100644
--- a/www/manager6/qemu/MachineEdit.js
+++ b/www/manager6/qemu/MachineEdit.js
@@ -1,6 +1,7 @@
 Ext.define('PVE.qemu.MachineInputPanel', {
     extend: 'Proxmox.panel.InputPanel',
     xtype: 'pveMachineInputPanel',
+    onlineHelp: 'qm_system_settings',
 
     controller: {
 	xclass: 'Ext.app.ViewController',
@@ -12,11 +13,14 @@ Ext.define('PVE.qemu.MachineInputPanel', {
 	onMachineChange: function(field, value) {
 	    let me = this;
 	    let version = me.lookup('version');
+	    let q35Hint = me.lookup('q35Hint');
 	    let store = version.getStore();
 	    let oldRec = store.findRecord('id', version.getValue(), 0, false, false, true);
 	    let type = value === 'q35' ? 'q35' : 'i440fx';
 	    store.clearFilter();
 	    store.addFilter(val => val.data.id === 'latest' || val.data.type === type);
+	    // show hint when Intel vIOMMU cannot be used
+	    q35Hint.setVisible(type === 'i440fx');
 	    if (!me.getView().isWindows) {
 		version.setValue('latest');
 	    } else {
@@ -40,12 +44,30 @@ Ext.define('PVE.qemu.MachineInputPanel', {
 	    delete values.delete;
 	}
 	delete values.version;
+	if (values.machine === undefined) {
+	    if (values.viommu) {
+		delete values.delete;
+		values.machine = "pc";
+	    } else {
+		values.delete = "machine";
+	    }
+	}
+	if (values.viommu) {
+	    values.machine += ",viommu=" + values.viommu;
+	}
+	if (values.delete === "viommu") {
+	    delete values.delete;
+	}
+	delete values.viommu;
 	return values;
     },
 
     setValues: function(values) {
 	let me = this;
 
+	let machineConf = PVE.Parser.parsePropertyString(values.machine, "type");
+	values.machine = machineConf.type;
+
 	me.isWindows = values.isWindows;
 	if (values.machine === 'pc') {
 	    values.machine = '__default__';
@@ -58,6 +80,9 @@ Ext.define('PVE.qemu.MachineInputPanel', {
 		values.version = 'pc-q35-5.1';
 	    }
 	}
+
+	values.viommu = machineConf.viommu || "__default__";
+
 	if (values.machine !== '__default__' && values.machine !== 'q35') {
 	    values.version = values.machine;
 	    values.machine = values.version.match(/q35/) ? 'q35' : '__default__';
@@ -113,6 +138,26 @@ Ext.define('PVE.qemu.MachineInputPanel', {
 	    fieldLabel: gettext('Note'),
 	    value: gettext('Machine version change may affect hardware layout and settings in the guest OS.'),
 	},
+	{
+	    xtype: 'proxmoxKVComboBox',
+	    fieldLabel: gettext('vIOMMU'),
+	    name: 'viommu',
+	    reference: 'viommu',
+	    value: '__default__',
+	    comboItems: [
+		['__default__', 'none'],
+		['intel', 'Intel'],
+		['virtio', 'VirtIO'],
+	    ],
+	},
+	{
+	    xtype: 'displayfield',
+	    name: 'q35Hint',
+	    reference: 'q35Hint',
+	    userCls: 'pmx-hint',
+	    value: gettext('Intel vIOMMU needs the q35 machine type'),
+	    hidden: true,
+	},
     ],
 });
 
-- 
2.39.2





^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-10-12 10:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-12 10:02 [pve-devel] [PATCH qemu-server/docs/manager v7 0/4] vIOMMU-Feature #3784 Markus Frank
2023-10-12 10:02 ` [pve-devel] [PATCH qemu-server v7 1/4] machine as property-string Markus Frank
2023-10-12 10:02 ` [pve-devel] [PATCH qemu-server v7 2/4] feature #3784: Parameter for guest vIOMMU + test-cases Markus Frank
2023-10-12 10:02 ` [pve-devel] [PATCH docs v7 3/4] added vIOMMU documentation Markus Frank
2023-10-12 10:02 ` [pve-devel] [PATCH manager v7 4/4] ui: MachineEdit with viommu ComboBox Markus Frank

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal