all lists on 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal