Re: [pve-devel] [PATCH qemu-server 3/3] fix #2794: allow legacy IGD passthrough

2020-06-25 Thread Stefan Reiter

On 6/24/20 9:46 AM, Thomas Lamprecht wrote:

Am 6/22/20 um 10:17 AM schrieb Stefan Reiter:

@@ -89,7 +97,8 @@ sub get_pci_addr_map {
   $pci_addr_map = {
   piix3 => { bus => 0, addr => 1, conflict_ok => qw(ehci)  },
   ehci => { bus => 0, addr => 1, conflict_ok => qw(piix3) }, # instead of 
piix3 on arm
-vga => { bus => 0, addr => 2 },
+vga => { bus => 0, addr => 2, conflict_ok => qw(legacy-igd) },


sorry, but how do they conflict? the address differs so the check can't hit.
Or is this just for documentation purpose?



What do you mean the address differs? 'legacy-igd' and 'vga' both share bus 0 
addr 2, so without the conflict_ok the 'run_pci_addr_checks.pl' test fails. 
This is only save because legacy-igd requires vga=none anyway, as documented by 
the comment below.


+'legacy-igd' => { bus => 0, addr => 2, conflict_ok => qw(vga) }, # 
legacy-igd requires vga=none


ignore me, confused with non legacy IGD, sorry.



So the only thing left then is the description formatting. Should I send 
a v2 for that or do you want to do a followup?


___
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


Re: [pve-devel] [PATCH qemu-server 3/3] fix #2794: allow legacy IGD passthrough

2020-06-24 Thread Thomas Lamprecht
Am 6/22/20 um 10:17 AM schrieb Stefan Reiter:
>>> @@ -89,7 +97,8 @@ sub get_pci_addr_map {
>>>   $pci_addr_map = {
>>>   piix3 => { bus => 0, addr => 1, conflict_ok => qw(ehci)  },
>>>   ehci => { bus => 0, addr => 1, conflict_ok => qw(piix3) }, # instead 
>>> of piix3 on arm
>>> -vga => { bus => 0, addr => 2 },
>>> +vga => { bus => 0, addr => 2, conflict_ok => qw(legacy-igd) },
>>
>> sorry, but how do they conflict? the address differs so the check can't hit.
>> Or is this just for documentation purpose?
>>
> 
> What do you mean the address differs? 'legacy-igd' and 'vga' both share bus 0 
> addr 2, so without the conflict_ok the 'run_pci_addr_checks.pl' test fails. 
> This is only save because legacy-igd requires vga=none anyway, as documented 
> by the comment below.
> 
>>> +'legacy-igd' => { bus => 0, addr => 2, conflict_ok => qw(vga) }, # 
>>> legacy-igd requires vga=none 

ignore me, confused with non legacy IGD, sorry. 

___
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


Re: [pve-devel] [PATCH qemu-server 3/3] fix #2794: allow legacy IGD passthrough

2020-06-22 Thread Stefan Reiter

On 6/18/20 5:00 PM, Thomas Lamprecht wrote:

Am 6/18/20 um 4:36 PM schrieb Stefan Reiter:

Legacy IGD passthrough requires address 00:1f.0 to not be assigned to
anything on QEMU startup (currently it's assigned to bridge pci.2).
Changing this in general would break live-migration, so introduce a new
hostpci parameter "legacy-igd", which if set to 1 will move that bridge
to be nested under bridge 1.

This is safe because:
* Bridge 1 is unconditionally created on i440fx, so nesting is ok
* Defaults are not changed, i.e. PCI layout only changes when the new
parameter is specified manually
* hostpci forbids migration anyway

Additionally, the PT device has to be assigned address 00:02.0 in the
guest as well, which is usually used for VGA assignment. Luckily, IGD PT
requires vga=none, so that is not an issue either.

See https://git.qemu.org/?p=qemu.git;a=blob;f=docs/igd-assign.txt

Signed-off-by: Stefan Reiter 
---
  PVE/QemuServer.pm | 10 --
  PVE/QemuServer/PCI.pm | 45 +--
  2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 1c08222..1abe64b 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -3102,7 +3102,7 @@ sub config_to_command {
  }
  
  # host pci device passthrough

-my ($kvm_off, $gpu_passthrough) = 
PVE::QemuServer::PCI::print_hostpci_devices(
+my ($kvm_off, $gpu_passthrough, $legacy_igd) = 
PVE::QemuServer::PCI::print_hostpci_devices(
$conf, $devices, $winversion, $q35, $bridges, $arch, $machine_type);
  
  # usb devices

@@ -3458,7 +3458,13 @@ sub config_to_command {
  
  for my $k (sort {$b cmp $a} keys %$bridges) {

next if $q35 && $k < 4; # q35.cfg already includes bridges up to 3
-   $pciaddr = print_pci_addr("pci.$k", undef, $arch, $machine_type);
+
+   my $k_name = $k;
+   if ($k == 2 && $legacy_igd) {
+   $k_name = "$k-igd";
+   }
+   $pciaddr = print_pci_addr("pci.$k_name", undef, $arch, $machine_type);
+


ugh, hacks all the way down, but well it seems that pass through stuff relies 
on that -.-



The entire legacy-igd thing is pretty much a hack (on QEMUs side too I 
mean), and I don't really see a way around this part if we do want to 
support it...


The $k_name thing could be done away with if we hardcode the address 
here, but I'd rather have it in the pci_addr_map, so we know to not use 
it in the future.



my $devstr = "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr";
if ($q35) {
# add after -readconfig pve-q35.cfg
diff --git a/PVE/QemuServer/PCI.pm b/PVE/QemuServer/PCI.pm
index 39f9970..e835f39 100644
--- a/PVE/QemuServer/PCI.pm
+++ b/PVE/QemuServer/PCI.pm
@@ -55,6 +55,14 @@ EODESCR
optional => 1,
default => 0,
  },
+'legacy-igd' => {
+   type => 'boolean',
+   description => "Pass this device in legacy IGD mode (allows required"
+. " 1f.0 PCI bridge and assigns correct address)."
+. " Requires i440fx machine type and VGA set to 'none'.",


I'd rather use 100 cc lines for that and do not align subsequent concatenated 
lines indentation
but just indent them 4 spaces more than the prev level.



Ok


+   optional => 1,
+   default => 0,
+},
  'mdev' => {
type => 'string',
  format_description => 'string',
@@ -89,7 +97,8 @@ sub get_pci_addr_map {
  $pci_addr_map = {
piix3 => { bus => 0, addr => 1, conflict_ok => qw(ehci)  },
ehci => { bus => 0, addr => 1, conflict_ok => qw(piix3) }, # instead of 
piix3 on arm
-   vga => { bus => 0, addr => 2 },
+   vga => { bus => 0, addr => 2, conflict_ok => qw(legacy-igd) },


sorry, but how do they conflict? the address differs so the check can't hit.
Or is this just for documentation purpose?



What do you mean the address differs? 'legacy-igd' and 'vga' both share 
bus 0 addr 2, so without the conflict_ok the 'run_pci_addr_checks.pl' 
test fails. This is only save because legacy-igd requires vga=none 
anyway, as documented by the comment below.



+   'legacy-igd' => { bus => 0, addr => 2, conflict_ok => qw(vga) }, # 
legacy-igd requires vga=none
balloon0 => { bus => 0, addr => 3 },
watchdog => { bus => 0, addr => 4 },
scsihw0 => { bus => 0, addr => 5, conflict_ok => qw(pci.3) },
@@ -149,6 +158,7 @@ sub get_pci_addr_map {
'xhci' => { bus => 1, addr => 27 },
'pci.4' => { bus => 1, addr => 28 },
'rng0' => { bus => 1, addr => 29 },
+   'pci.2-igd' => { bus => 1, addr => 30 }, # replaces pci.2 in case a 
legacy IGD device is passed through
'virtio6' => { bus => 2, addr => 1 },
'virtio7' => { bus => 2, addr => 2 },
'virtio8' => { bus => 2, addr => 3 },
@@ -351,6 +361,7 @@ sub print_hostpci_devices {
  
  my $kvm_off = 0;

  my $gpu_passthrough = 0;
+my $legacy_igd = 0;
  
  for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; 

Re: [pve-devel] [PATCH qemu-server 3/3] fix #2794: allow legacy IGD passthrough

2020-06-18 Thread Thomas Lamprecht
Am 6/18/20 um 4:36 PM schrieb Stefan Reiter:
> Legacy IGD passthrough requires address 00:1f.0 to not be assigned to
> anything on QEMU startup (currently it's assigned to bridge pci.2).
> Changing this in general would break live-migration, so introduce a new
> hostpci parameter "legacy-igd", which if set to 1 will move that bridge
> to be nested under bridge 1.
> 
> This is safe because:
> * Bridge 1 is unconditionally created on i440fx, so nesting is ok
> * Defaults are not changed, i.e. PCI layout only changes when the new
> parameter is specified manually
> * hostpci forbids migration anyway
> 
> Additionally, the PT device has to be assigned address 00:02.0 in the
> guest as well, which is usually used for VGA assignment. Luckily, IGD PT
> requires vga=none, so that is not an issue either.
> 
> See https://git.qemu.org/?p=qemu.git;a=blob;f=docs/igd-assign.txt
> 
> Signed-off-by: Stefan Reiter 
> ---
>  PVE/QemuServer.pm | 10 --
>  PVE/QemuServer/PCI.pm | 45 +--
>  2 files changed, 47 insertions(+), 8 deletions(-)
> 
> diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
> index 1c08222..1abe64b 100644
> --- a/PVE/QemuServer.pm
> +++ b/PVE/QemuServer.pm
> @@ -3102,7 +3102,7 @@ sub config_to_command {
>  }
>  
>  # host pci device passthrough
> -my ($kvm_off, $gpu_passthrough) = 
> PVE::QemuServer::PCI::print_hostpci_devices(
> +my ($kvm_off, $gpu_passthrough, $legacy_igd) = 
> PVE::QemuServer::PCI::print_hostpci_devices(
>   $conf, $devices, $winversion, $q35, $bridges, $arch, $machine_type);
>  
>  # usb devices
> @@ -3458,7 +3458,13 @@ sub config_to_command {
>  
>  for my $k (sort {$b cmp $a} keys %$bridges) {
>   next if $q35 && $k < 4; # q35.cfg already includes bridges up to 3
> - $pciaddr = print_pci_addr("pci.$k", undef, $arch, $machine_type);
> +
> + my $k_name = $k;
> + if ($k == 2 && $legacy_igd) {
> + $k_name = "$k-igd";
> + }
> + $pciaddr = print_pci_addr("pci.$k_name", undef, $arch, $machine_type);
> +

ugh, hacks all the way down, but well it seems that pass through stuff relies 
on that -.-

>   my $devstr = "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr";
>   if ($q35) {
>   # add after -readconfig pve-q35.cfg
> diff --git a/PVE/QemuServer/PCI.pm b/PVE/QemuServer/PCI.pm
> index 39f9970..e835f39 100644
> --- a/PVE/QemuServer/PCI.pm
> +++ b/PVE/QemuServer/PCI.pm
> @@ -55,6 +55,14 @@ EODESCR
>   optional => 1,
>   default => 0,
>  },
> +'legacy-igd' => {
> + type => 'boolean',
> + description => "Pass this device in legacy IGD mode (allows required"
> +  . " 1f.0 PCI bridge and assigns correct address)."
> +  . " Requires i440fx machine type and VGA set to 'none'.",

I'd rather use 100 cc lines for that and do not align subsequent concatenated 
lines indentation
but just indent them 4 spaces more than the prev level.

> + optional => 1,
> + default => 0,
> +},
>  'mdev' => {
>   type => 'string',
>  format_description => 'string',
> @@ -89,7 +97,8 @@ sub get_pci_addr_map {
>  $pci_addr_map = {
>   piix3 => { bus => 0, addr => 1, conflict_ok => qw(ehci)  },
>   ehci => { bus => 0, addr => 1, conflict_ok => qw(piix3) }, # instead of 
> piix3 on arm
> - vga => { bus => 0, addr => 2 },
> + vga => { bus => 0, addr => 2, conflict_ok => qw(legacy-igd) },

sorry, but how do they conflict? the address differs so the check can't hit.
Or is this just for documentation purpose?

> + 'legacy-igd' => { bus => 0, addr => 2, conflict_ok => qw(vga) }, # 
> legacy-igd requires vga=none
>   balloon0 => { bus => 0, addr => 3 },
>   watchdog => { bus => 0, addr => 4 },
>   scsihw0 => { bus => 0, addr => 5, conflict_ok => qw(pci.3) },
> @@ -149,6 +158,7 @@ sub get_pci_addr_map {
>   'xhci' => { bus => 1, addr => 27 },
>   'pci.4' => { bus => 1, addr => 28 },
>   'rng0' => { bus => 1, addr => 29 },
> + 'pci.2-igd' => { bus => 1, addr => 30 }, # replaces pci.2 in case a 
> legacy IGD device is passed through
>   'virtio6' => { bus => 2, addr => 1 },
>   'virtio7' => { bus => 2, addr => 2 },
>   'virtio8' => { bus => 2, addr => 3 },
> @@ -351,6 +361,7 @@ sub print_hostpci_devices {
>  
>  my $kvm_off = 0;
>  my $gpu_passthrough = 0;
> +my $legacy_igd = 0;
>  
>  for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++)  {
>   my $id = "hostpci$i";
> @@ -372,7 +383,32 @@ sub print_hostpci_devices {
>   $pciaddr = print_pcie_addr($id);
>   }
>   } else {
> - $pciaddr = print_pci_addr($id, $bridges, $arch, $machine_type);
> + my $pci_name = $d->{'legacy-igd'} ? 'legacy-igd' : $id;
> + $pciaddr = print_pci_addr($pci_name, $bridges, $arch, 
> $machine_type);
> + }
> +
> + my $pcidevices = $d->{pciid};
> + my $multifunction = 1 if @$pcidevices > 1;
> +
> + if 

[pve-devel] [PATCH qemu-server 3/3] fix #2794: allow legacy IGD passthrough

2020-06-18 Thread Stefan Reiter
Legacy IGD passthrough requires address 00:1f.0 to not be assigned to
anything on QEMU startup (currently it's assigned to bridge pci.2).
Changing this in general would break live-migration, so introduce a new
hostpci parameter "legacy-igd", which if set to 1 will move that bridge
to be nested under bridge 1.

This is safe because:
* Bridge 1 is unconditionally created on i440fx, so nesting is ok
* Defaults are not changed, i.e. PCI layout only changes when the new
parameter is specified manually
* hostpci forbids migration anyway

Additionally, the PT device has to be assigned address 00:02.0 in the
guest as well, which is usually used for VGA assignment. Luckily, IGD PT
requires vga=none, so that is not an issue either.

See https://git.qemu.org/?p=qemu.git;a=blob;f=docs/igd-assign.txt

Signed-off-by: Stefan Reiter 
---
 PVE/QemuServer.pm | 10 --
 PVE/QemuServer/PCI.pm | 45 +--
 2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 1c08222..1abe64b 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -3102,7 +3102,7 @@ sub config_to_command {
 }
 
 # host pci device passthrough
-my ($kvm_off, $gpu_passthrough) = 
PVE::QemuServer::PCI::print_hostpci_devices(
+my ($kvm_off, $gpu_passthrough, $legacy_igd) = 
PVE::QemuServer::PCI::print_hostpci_devices(
$conf, $devices, $winversion, $q35, $bridges, $arch, $machine_type);
 
 # usb devices
@@ -3458,7 +3458,13 @@ sub config_to_command {
 
 for my $k (sort {$b cmp $a} keys %$bridges) {
next if $q35 && $k < 4; # q35.cfg already includes bridges up to 3
-   $pciaddr = print_pci_addr("pci.$k", undef, $arch, $machine_type);
+
+   my $k_name = $k;
+   if ($k == 2 && $legacy_igd) {
+   $k_name = "$k-igd";
+   }
+   $pciaddr = print_pci_addr("pci.$k_name", undef, $arch, $machine_type);
+
my $devstr = "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr";
if ($q35) {
# add after -readconfig pve-q35.cfg
diff --git a/PVE/QemuServer/PCI.pm b/PVE/QemuServer/PCI.pm
index 39f9970..e835f39 100644
--- a/PVE/QemuServer/PCI.pm
+++ b/PVE/QemuServer/PCI.pm
@@ -55,6 +55,14 @@ EODESCR
optional => 1,
default => 0,
 },
+'legacy-igd' => {
+   type => 'boolean',
+   description => "Pass this device in legacy IGD mode (allows required"
+. " 1f.0 PCI bridge and assigns correct address)."
+. " Requires i440fx machine type and VGA set to 'none'.",
+   optional => 1,
+   default => 0,
+},
 'mdev' => {
type => 'string',
 format_description => 'string',
@@ -89,7 +97,8 @@ sub get_pci_addr_map {
 $pci_addr_map = {
piix3 => { bus => 0, addr => 1, conflict_ok => qw(ehci)  },
ehci => { bus => 0, addr => 1, conflict_ok => qw(piix3) }, # instead of 
piix3 on arm
-   vga => { bus => 0, addr => 2 },
+   vga => { bus => 0, addr => 2, conflict_ok => qw(legacy-igd) },
+   'legacy-igd' => { bus => 0, addr => 2, conflict_ok => qw(vga) }, # 
legacy-igd requires vga=none
balloon0 => { bus => 0, addr => 3 },
watchdog => { bus => 0, addr => 4 },
scsihw0 => { bus => 0, addr => 5, conflict_ok => qw(pci.3) },
@@ -149,6 +158,7 @@ sub get_pci_addr_map {
'xhci' => { bus => 1, addr => 27 },
'pci.4' => { bus => 1, addr => 28 },
'rng0' => { bus => 1, addr => 29 },
+   'pci.2-igd' => { bus => 1, addr => 30 }, # replaces pci.2 in case a 
legacy IGD device is passed through
'virtio6' => { bus => 2, addr => 1 },
'virtio7' => { bus => 2, addr => 2 },
'virtio8' => { bus => 2, addr => 3 },
@@ -351,6 +361,7 @@ sub print_hostpci_devices {
 
 my $kvm_off = 0;
 my $gpu_passthrough = 0;
+my $legacy_igd = 0;
 
 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++)  {
my $id = "hostpci$i";
@@ -372,7 +383,32 @@ sub print_hostpci_devices {
$pciaddr = print_pcie_addr($id);
}
} else {
-   $pciaddr = print_pci_addr($id, $bridges, $arch, $machine_type);
+   my $pci_name = $d->{'legacy-igd'} ? 'legacy-igd' : $id;
+   $pciaddr = print_pci_addr($pci_name, $bridges, $arch, 
$machine_type);
+   }
+
+   my $pcidevices = $d->{pciid};
+   my $multifunction = 1 if @$pcidevices > 1;
+
+   if ($d->{'legacy-igd'}) {
+   die "only one device can be assigned in legacy-igd mode\n"
+   if $legacy_igd;
+   $legacy_igd = 1;
+
+   die "legacy IGD assignment requires VGA mode to be 'none'\n"
+   if !defined($conf->{'vga'}) || $conf->{'vga'} ne 'none';
+   die "legacy IGD assignment requires rombar to be enabled\n"
+   if defined($d->{rombar}) && !$d->{rombar};
+   die "legacy IGD assignment is not compatible with x-vga\n"
+   if $d->{'x-vga'};
+   die "legacy IGD