From: Markus Frank <m.frank@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH qemu-server v9 1/3] fix #3784: config: Parameter for guest vIOMMU + test-cases
Date: Thu, 11 Apr 2024 12:48:20 +0200 [thread overview]
Message-ID: <20240411104822.832432-2-m.frank@proxmox.com> (raw)
In-Reply-To: <20240411104822.832432-1-m.frank@proxmox.com>
vIOMMU enables the option to passthrough pci devices to L2 VMs
in L1 VMs via Nested Virtualisation and adds an extra isolation.
Uses the new property-string from the "config: define machine schema
as property-string"-commit to add the viommu option to the machine
parameter.
Currently there are two vIOMMU implementation in QEMU to choose:
intel or virtio
Virtio-iommu is more recent but less used in production than intel-iommu.
The assert_valid_machine_property function prevents using intel-iommu with
i440fx.
Signed-off-by: Markus Frank <m.frank@proxmox.com>
---
PVE/API2/Qemu.pm | 2 ++
PVE/QemuServer.pm | 12 +++++++++++
PVE/QemuServer/Machine.pm | 17 ++++++++++++++-
test/cfg2cmd/i440fx-viommu-intel.conf | 2 ++
test/cfg2cmd/i440fx-viommu-virtio.conf | 1 +
test/cfg2cmd/i440fx-viommu-virtio.conf.cmd | 25 ++++++++++++++++++++++
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 ++++++++++++++++++++
10 files changed, 106 insertions(+), 1 deletion(-)
create mode 100644 test/cfg2cmd/i440fx-viommu-intel.conf
create mode 100644 test/cfg2cmd/i440fx-viommu-virtio.conf
create mode 100644 test/cfg2cmd/i440fx-viommu-virtio.conf.cmd
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 f3ce83d..3eabddd 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -1136,6 +1136,7 @@ __PACKAGE__->register_method({
$conf->{machine} = PVE::QemuServer::Machine::print_machine($machine_conf);
}
}
+ PVE::QemuServer::Machine::assert_valid_machine_property($conf, $machine_conf);
$conf->{lock} = 'import' if $live_import_mapping;
@@ -2000,6 +2001,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::assert_valid_machine_property($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 abe175a..c94c90d 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -4080,6 +4080,18 @@ sub config_to_command {
}
push @$machineFlags, "type=${machine_type_min}";
+ PVE::QemuServer::Machine::assert_valid_machine_property($conf, $machine_conf);
+
+ my $viommu = $machine_conf->{viommu};
+ if ($viommu) {
+ if ($viommu eq 'intel') {
+ unshift @$devices, '-device', 'intel-iommu,intremap=on,caching-mode=on';
+ push @$machineFlags, 'kernel-irqchip=split';
+ } elsif ($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 5e3a75c..3d92c96 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 and set guest vIOMMU variant (Intel vIOMMU needs 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 => 'string',
optional => 1,
format => PVE::JSONSchema::get_format('pve-qemu-machine-fmt'),
@@ -48,6 +55,14 @@ sub print_machine {
return print_property_string($machine_conf, $machine_fmt);
}
+sub assert_valid_machine_property {
+ my ($conf, $machine_conf) = @_;
+ my $q35 = $machine_conf->{type} && ($machine_conf->{type} =~ m/q35/) ? 1 : 0;
+ 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/i440fx-viommu-intel.conf b/test/cfg2cmd/i440fx-viommu-intel.conf
new file mode 100644
index 0000000..bc1eb95
--- /dev/null
+++ b/test/cfg2cmd/i440fx-viommu-intel.conf
@@ -0,0 +1,2 @@
+# EXPECT_ERROR: to use Intel vIOMMU please set the machine type to q35
+machine: pc,viommu=intel
diff --git a/test/cfg2cmd/i440fx-viommu-virtio.conf b/test/cfg2cmd/i440fx-viommu-virtio.conf
new file mode 100644
index 0000000..fe7b514
--- /dev/null
+++ b/test/cfg2cmd/i440fx-viommu-virtio.conf
@@ -0,0 +1 @@
+machine: pc,viommu=virtio
diff --git a/test/cfg2cmd/i440fx-viommu-virtio.conf.cmd b/test/cfg2cmd/i440fx-viommu-virtio.conf.cmd
new file mode 100644
index 0000000..0352354
--- /dev/null
+++ b/test/cfg2cmd/i440fx-viommu-virtio.conf.cmd
@@ -0,0 +1,25 @@
+/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 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \
+ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \
+ -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \
+ -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \
+ -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
+ -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=pc+pve0'
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
next prev parent reply other threads:[~2024-04-11 10:49 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-11 10:48 [pve-devel] [PATCH qemu-server/docs/manager v9 0/3] vIOMMU-Feature #3784 Markus Frank
2024-04-11 10:48 ` Markus Frank [this message]
2024-04-11 14:44 ` [pve-devel] applied: Re: [PATCH qemu-server v9 1/3] fix #3784: config: Parameter for guest vIOMMU + test-cases Thomas Lamprecht
2024-04-11 10:48 ` [pve-devel] [PATCH docs v9 2/3] add vIOMMU documentation Markus Frank
2024-04-11 14:47 ` [pve-devel] applied: " Thomas Lamprecht
2024-04-11 10:48 ` [pve-devel] [PATCH manager v9 3/3] ui: machine: add viommu ComboBox Markus Frank
2024-04-11 15:13 ` Thomas Lamprecht
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240411104822.832432-2-m.frank@proxmox.com \
--to=m.frank@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.