[PATCH] vfio/igd: Support non-boot gpus

Qwinci posted 1 patch 6 months, 4 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20250519150837.23146-3-qwinci222@gmail.com
Maintainers: Alex Williamson <alex.williamson@redhat.com>, "Cédric Le Goater" <clg@redhat.com>, Tomita Moeko <tomitamoeko@gmail.com>
hw/vfio/igd.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
[PATCH] vfio/igd: Support non-boot gpus
Posted by Qwinci 6 months, 4 weeks ago
Change the IGD detection logic to also accept gpus with
PCI_CLASS_DISPLAY_OTHER class which is used if the igpu is not
set as the primary boot gpu.

Signed-off-by: Qwinci <qwinci222@gmail.com>
---
 hw/vfio/igd.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index e7952d15a0..1ddfcc2c17 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -454,6 +454,16 @@ static bool vfio_pci_igd_override_gms(int gen, uint32_t gms, uint32_t *gmch)
 #define IGD_GGC_MMIO_OFFSET     0x108040
 #define IGD_BDSM_MMIO_OFFSET    0x1080C0
 
+static bool is_igd(VFIOPCIDevice *vdev) {
+    if (vfio_is_vga(vdev)) {
+        return true;
+    }
+
+    PCIDevice *pdev = &vdev->pdev;
+    uint16_t class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
+    return class == PCI_CLASS_DISPLAY_OTHER;
+}
+
 void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
 {
     VFIOQuirk *ggc_quirk, *bdsm_quirk;
@@ -461,7 +471,7 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
     int gen;
 
     if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
-        !vfio_is_vga(vdev) || nr != 0) {
+        !is_igd(vdev) || nr != 0) {
         return;
     }
 
@@ -519,7 +529,7 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
     Error *err = NULL;
 
     if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
-        !vfio_is_vga(vdev)) {
+        !is_igd(vdev)) {
         return true;
     }
 
@@ -685,7 +695,7 @@ static bool vfio_pci_kvmgt_config_quirk(VFIOPCIDevice *vdev, Error **errp)
     int gen;
 
     if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
-        !vfio_is_vga(vdev)) {
+        !is_igd(vdev)) {
         return true;
     }
 
-- 
2.48.1
Re: [PATCH] vfio/igd: Support non-boot gpus
Posted by Alex Williamson 6 months, 4 weeks ago
[Please Cc maintainers - added here]

On Mon, 19 May 2025 18:08:39 +0300
Qwinci <qwinci222@gmail.com> wrote:

> Change the IGD detection logic to also accept gpus with
> PCI_CLASS_DISPLAY_OTHER class which is used if the igpu is not
> set as the primary boot gpu.
> 
> Signed-off-by: Qwinci <qwinci222@gmail.com>
> ---
>  hw/vfio/igd.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
> index e7952d15a0..1ddfcc2c17 100644
> --- a/hw/vfio/igd.c
> +++ b/hw/vfio/igd.c
> @@ -454,6 +454,16 @@ static bool vfio_pci_igd_override_gms(int gen, uint32_t gms, uint32_t *gmch)
>  #define IGD_GGC_MMIO_OFFSET     0x108040
>  #define IGD_BDSM_MMIO_OFFSET    0x1080C0
>  
> +static bool is_igd(VFIOPCIDevice *vdev) {
> +    if (vfio_is_vga(vdev)) {
> +        return true;
> +    }
> +
> +    PCIDevice *pdev = &vdev->pdev;
> +    uint16_t class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
> +    return class == PCI_CLASS_DISPLAY_OTHER;
> +}

But the function isn't detecting IGD, it's detecting VGA or DISPLAY
class devices.  So it's misnamed and we might want a new
vfio_is_display() and if necessary a wrapper for both that tests
vfio_is_vga_or_display(), or maybe a vfio_is_base_display() if we want
to test only the base class.

More importantly maybe, sure there might be IGD as non-primary
configurations, but are the quirks still relevant to those devices?
Which ones?  Thanks,

Alex

>  void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
>  {
>      VFIOQuirk *ggc_quirk, *bdsm_quirk;
> @@ -461,7 +471,7 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
>      int gen;
>  
>      if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
> -        !vfio_is_vga(vdev) || nr != 0) {
> +        !is_igd(vdev) || nr != 0) {
>          return;
>      }
>  
> @@ -519,7 +529,7 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
>      Error *err = NULL;
>  
>      if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
> -        !vfio_is_vga(vdev)) {
> +        !is_igd(vdev)) {
>          return true;
>      }
>  
> @@ -685,7 +695,7 @@ static bool vfio_pci_kvmgt_config_quirk(VFIOPCIDevice *vdev, Error **errp)
>      int gen;
>  
>      if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
> -        !vfio_is_vga(vdev)) {
> +        !is_igd(vdev)) {
>          return true;
>      }
>
Re: [PATCH] vfio/igd: Support non-boot gpus
Posted by Tomita Moeko 6 months, 4 weeks ago
On 5/20/25 01:15, Alex Williamson wrote:
> [Please Cc maintainers - added here]
> 
> On Mon, 19 May 2025 18:08:39 +0300
> Qwinci <qwinci222@gmail.com> wrote:
> 
>> Change the IGD detection logic to also accept gpus with
>> PCI_CLASS_DISPLAY_OTHER class which is used if the igpu is not
>> set as the primary boot gpu.
>>
>> Signed-off-by: Qwinci <qwinci222@gmail.com>
>> ---
>>  hw/vfio/igd.c | 16 +++++++++++++---
>>  1 file changed, 13 insertions(+), 3 deletions(-)
>>
>> diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
>> index e7952d15a0..1ddfcc2c17 100644
>> --- a/hw/vfio/igd.c
>> +++ b/hw/vfio/igd.c
>> @@ -454,6 +454,16 @@ static bool vfio_pci_igd_override_gms(int gen, uint32_t gms, uint32_t *gmch)
>>  #define IGD_GGC_MMIO_OFFSET     0x108040
>>  #define IGD_BDSM_MMIO_OFFSET    0x1080C0
>>  
>> +static bool is_igd(VFIOPCIDevice *vdev) {
>> +    if (vfio_is_vga(vdev)) {
>> +        return true;
>> +    }
>> +
>> +    PCIDevice *pdev = &vdev->pdev;
>> +    uint16_t class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
>> +    return class == PCI_CLASS_DISPLAY_OTHER;
>> +}
> 
> But the function isn't detecting IGD, it's detecting VGA or DISPLAY
> class devices.  So it's misnamed and we might want a new
> vfio_is_display() and if necessary a wrapper for both that tests
> vfio_is_vga_or_display(), or maybe a vfio_is_base_display() if we want
> to test only the base class.

+1, matching the base class is enough here I think.

> More importantly maybe, sure there might be IGD as non-primary
> configurations, but are the quirks still relevant to those devices?
> Which ones?  Thanks,
> 
> Alex

Actually this is what I've worked on for a while. Only the OpRegion
quirk is needed in this configuration, Windows driver requires it.
Additionally, legacy mode should be disabled when IGD is non-primary as
VGA ranges are not routed to IGD.

It also requires a more recent version kernel (6.15+) [1] for OpRegion
support on IGD as non-primary graphics.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=41112160ca87d6b5280813ef61f1c35bb9ee2f82

Thanks,
Moeko

>>  void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
>>  {
>>      VFIOQuirk *ggc_quirk, *bdsm_quirk;
>> @@ -461,7 +471,7 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
>>      int gen;
>>  
>>      if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
>> -        !vfio_is_vga(vdev) || nr != 0) {
>> +        !is_igd(vdev) || nr != 0) {
>>          return;
>>      }
>>  
>> @@ -519,7 +529,7 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
>>      Error *err = NULL;
>>  
>>      if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
>> -        !vfio_is_vga(vdev)) {
>> +        !is_igd(vdev)) {
>>          return true;
>>      }
>>  
>> @@ -685,7 +695,7 @@ static bool vfio_pci_kvmgt_config_quirk(VFIOPCIDevice *vdev, Error **errp)
>>      int gen;
>>  
>>      if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
>> -        !vfio_is_vga(vdev)) {
>> +        !is_igd(vdev)) {
>>          return true;
>>      }
>>  
>
Re: [PATCH] vfio/igd: Support non-boot gpus
Posted by Visa 6 months, 4 weeks ago
Thanks for the comments, Ill make a new patch with a `vfio_is_display`
function`,
should I still change all uses of the `vfio_is_vga` function to use that one
even if the other quirks aren't needed in that configuration?


ma 19.5.2025 klo 20.28 Tomita Moeko (tomitamoeko@gmail.com) kirjoitti:

> On 5/20/25 01:15, Alex Williamson wrote:
> > [Please Cc maintainers - added here]
> >
> > On Mon, 19 May 2025 18:08:39 +0300
> > Qwinci <qwinci222@gmail.com> wrote:
> >
> >> Change the IGD detection logic to also accept gpus with
> >> PCI_CLASS_DISPLAY_OTHER class which is used if the igpu is not
> >> set as the primary boot gpu.
> >>
> >> Signed-off-by: Qwinci <qwinci222@gmail.com>
> >> ---
> >>  hw/vfio/igd.c | 16 +++++++++++++---
> >>  1 file changed, 13 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
> >> index e7952d15a0..1ddfcc2c17 100644
> >> --- a/hw/vfio/igd.c
> >> +++ b/hw/vfio/igd.c
> >> @@ -454,6 +454,16 @@ static bool vfio_pci_igd_override_gms(int gen,
> uint32_t gms, uint32_t *gmch)
> >>  #define IGD_GGC_MMIO_OFFSET     0x108040
> >>  #define IGD_BDSM_MMIO_OFFSET    0x1080C0
> >>
> >> +static bool is_igd(VFIOPCIDevice *vdev) {
> >> +    if (vfio_is_vga(vdev)) {
> >> +        return true;
> >> +    }
> >> +
> >> +    PCIDevice *pdev = &vdev->pdev;
> >> +    uint16_t class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
> >> +    return class == PCI_CLASS_DISPLAY_OTHER;
> >> +}
> >
> > But the function isn't detecting IGD, it's detecting VGA or DISPLAY
> > class devices.  So it's misnamed and we might want a new
> > vfio_is_display() and if necessary a wrapper for both that tests
> > vfio_is_vga_or_display(), or maybe a vfio_is_base_display() if we want
> > to test only the base class.
>
> +1, matching the base class is enough here I think.
>
> > More importantly maybe, sure there might be IGD as non-primary
> > configurations, but are the quirks still relevant to those devices?
> > Which ones?  Thanks,
> >
> > Alex
>
> Actually this is what I've worked on for a while. Only the OpRegion
> quirk is needed in this configuration, Windows driver requires it.
> Additionally, legacy mode should be disabled when IGD is non-primary as
> VGA ranges are not routed to IGD.
>
> It also requires a more recent version kernel (6.15+) [1] for OpRegion
> support on IGD as non-primary graphics.
>
> [1]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=41112160ca87d6b5280813ef61f1c35bb9ee2f82
>
> Thanks,
> Moeko
>
> >>  void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
> >>  {
> >>      VFIOQuirk *ggc_quirk, *bdsm_quirk;
> >> @@ -461,7 +471,7 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev,
> int nr)
> >>      int gen;
> >>
> >>      if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
> >> -        !vfio_is_vga(vdev) || nr != 0) {
> >> +        !is_igd(vdev) || nr != 0) {
> >>          return;
> >>      }
> >>
> >> @@ -519,7 +529,7 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice
> *vdev, Error **errp)
> >>      Error *err = NULL;
> >>
> >>      if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
> >> -        !vfio_is_vga(vdev)) {
> >> +        !is_igd(vdev)) {
> >>          return true;
> >>      }
> >>
> >> @@ -685,7 +695,7 @@ static bool
> vfio_pci_kvmgt_config_quirk(VFIOPCIDevice *vdev, Error **errp)
> >>      int gen;
> >>
> >>      if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
> >> -        !vfio_is_vga(vdev)) {
> >> +        !is_igd(vdev)) {
> >>          return true;
> >>      }
> >>
> >
>