Linux PCI subsystem development
 help / color / mirror / Atom feed
* [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2)
@ 2026-09-22  7:18 Dave Airlie
  2026-09-22  7:25 ` sashiko-bot
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Dave Airlie @ 2026-09-22  7:18 UTC (permalink / raw)
  To: dri-devel, linux-pci, kvm
  Cc: Jason Gunthorpe, Dave Airlie, Alex Williamson, Bjorn Helgaas,
	Rodrigo Vivi, Alex Deucher

From: Dave Airlie <airlied@redhat.com>

This changes the vgaarb client API so that the user can pass a
private data pointer into the register that will get used in
the decode callback.

This allows a bunch of pdev conversions in the drivers, and lets
some future vfio cleanups be nicer.

I'd like to merge this via the drm next tree but also fine with
it going via pci.

Signed-off-by: Dave Airlie <airlied@redhat.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
---
v2: fix loongson (spotted by sashiko)
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  6 +++---
 drivers/gpu/drm/i915/display/intel_vga.c   |  7 ++++---
 drivers/gpu/drm/loongson/lsdc_drv.c        |  4 ++--
 drivers/gpu/drm/nouveau/nouveau_vga.c      |  6 +++---
 drivers/gpu/drm/radeon/radeon_device.c     |  7 +++----
 drivers/pci/vgaarb.c                       | 13 +++++++++----
 drivers/vfio/pci/vfio_pci_core.c           |  9 +++++----
 include/linux/vgaarb.h                     |  8 +++++---
 8 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 62b5b4a23f17..1344b2b1bd16 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1435,10 +1435,10 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
  * Enable/disable vga decode (all asics).
  * Returns VGA resource flags.
  */
-static unsigned int amdgpu_device_vga_set_decode(struct pci_dev *pdev,
+static unsigned int amdgpu_device_vga_set_decode(void *data,
 		bool state)
 {
-	struct amdgpu_device *adev = drm_to_adev(pci_get_drvdata(pdev));
+	struct amdgpu_device *adev = (struct amdgpu_device *)data;
 
 	amdgpu_asic_set_vga_state(adev, state);
 	if (state)
@@ -4208,7 +4208,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 	 * ignore it
 	 */
 	if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
-		vga_client_register(adev->pdev, amdgpu_device_vga_set_decode);
+		vga_client_register(adev->pdev, amdgpu_device_vga_set_decode, adev);
 
 	px = amdgpu_device_supports_px(adev);
 
diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c
index 4966fd7eea92..0889edb36190 100644
--- a/drivers/gpu/drm/i915/display/intel_vga.c
+++ b/drivers/gpu/drm/i915/display/intel_vga.c
@@ -283,9 +283,10 @@ void intel_vga_disable(struct intel_display *display)
 	intel_de_posting_read(display, vga_reg);
 }
 
-static unsigned int intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
+static unsigned int intel_vga_set_decode(void *data, bool enable_decode)
 {
-	struct intel_display *display = to_intel_display(pdev);
+	struct intel_display *display = (struct intel_display *)data;
+	struct pci_dev *pdev = to_pci_dev(display->drm->dev);
 	unsigned int decodes = VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 
 	drm_dbg_kms(display->drm, "%s VGA decode due to VGA arbitration\n",
@@ -331,7 +332,7 @@ void intel_vga_register(struct intel_display *display)
 	 * then we do not take part in VGA arbitration and the
 	 * vga_client_register() fails with -ENODEV.
 	 */
-	ret = vga_client_register(pdev, intel_vga_set_decode);
+	ret = vga_client_register(pdev, intel_vga_set_decode, display);
 	drm_WARN_ON(display->drm, ret && ret != -ENODEV);
 }
 
diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c
index 3fd828d23271..5a13df31eb90 100644
--- a/drivers/gpu/drm/loongson/lsdc_drv.c
+++ b/drivers/gpu/drm/loongson/lsdc_drv.c
@@ -254,7 +254,7 @@ lsdc_create_device(struct pci_dev *pdev,
 
 /* For multiple GPU driver instance co-exixt in the system */
 
-static unsigned int lsdc_vga_set_decode(struct pci_dev *pdev, bool state)
+static unsigned int lsdc_vga_set_decode(void *data, bool state)
 {
 	return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 }
@@ -291,7 +291,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	pci_set_drvdata(pdev, ddev);
 
-	vga_client_register(pdev, lsdc_vga_set_decode);
+	vga_client_register(pdev, lsdc_vga_set_decode, NULL);
 
 	drmm_kms_helper_poll_init(ddev);
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c
index 29a801124e56..6662e30466f2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vga.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
@@ -9,9 +9,9 @@
 #include "nouveau_vga.h"
 
 static unsigned int
-nouveau_vga_set_decode(struct pci_dev *pdev, bool state)
+nouveau_vga_set_decode(void *data, bool state)
 {
-	struct nouveau_drm *drm = pci_get_drvdata(pdev);
+	struct nouveau_drm *drm = (struct nouveau_drm *)data;
 	struct nvif_object *device = &drm->client.device.object;
 
 	if (drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE &&
@@ -103,7 +103,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
 		return;
 	pdev = to_pci_dev(dev->dev);
 
-	vga_client_register(pdev, nouveau_vga_set_decode);
+	vga_client_register(pdev, nouveau_vga_set_decode, drm);
 
 	/* don't register Thunderbolt eGPU with vga_switcheroo */
 	if (pci_is_thunderbolt_attached(pdev))
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 9523240110a6..cf8a6bd00c77 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1076,10 +1076,9 @@ void radeon_combios_fini(struct radeon_device *rdev)
  * Enable/disable vga decode (all asics).
  * Returns VGA resource flags.
  */
-static unsigned int radeon_vga_set_decode(struct pci_dev *pdev, bool state)
+static unsigned int radeon_vga_set_decode(void *data, bool state)
 {
-	struct drm_device *dev = pci_get_drvdata(pdev);
-	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_device *rdev = (struct radeon_device *)data;
 	radeon_vga_set_state(rdev, state);
 	if (state)
 		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
@@ -1431,7 +1430,7 @@ int radeon_device_init(struct radeon_device *rdev,
 	/* if we have > 1 VGA cards, then disable the radeon VGA resources */
 	/* this will fail for cards that aren't VGA class devices, just
 	 * ignore it */
-	vga_client_register(rdev->pdev, radeon_vga_set_decode);
+	vga_client_register(rdev->pdev, radeon_vga_set_decode, rdev);
 
 	if (rdev->flags & RADEON_IS_PX)
 		runtime = true;
diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 3de05aee7859..3e58b2c05c85 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -51,7 +51,8 @@ struct vga_device {
 	unsigned int mem_norm_cnt;	/* normal MEM count */
 	bool bridge_has_one_vga;
 	bool is_firmware_default;	/* device selected by firmware */
-	unsigned int (*set_decode)(struct pci_dev *pdev, bool decode);
+	unsigned int (*set_decode)(void *data, bool decode);
+	void *set_decode_data;
 };
 
 static LIST_HEAD(vga_list);
@@ -935,6 +936,7 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
  * vga_client_register - register or unregister a VGA arbitration client
  * @pdev: PCI device of the VGA client
  * @set_decode: VGA decode change callback
+ * @data: private data to pass to callback
  *
  * Clients have two callback mechanisms they can use.
  *
@@ -956,15 +958,18 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
  * Returns: 0 on success, -ENODEV on failure
  */
 int vga_client_register(struct pci_dev *pdev,
-		unsigned int (*set_decode)(struct pci_dev *pdev, bool decode))
+		unsigned int (*set_decode)(void *data, bool decode),
+		void *data)
 {
 	unsigned long flags;
 	struct vga_device *vgadev;
 
 	spin_lock_irqsave(&vga_lock, flags);
 	vgadev = vgadev_find(pdev);
-	if (vgadev)
+	if (vgadev) {
 		vgadev->set_decode = set_decode;
+		vgadev->set_decode_data = data;
+	}
 	spin_unlock_irqrestore(&vga_lock, flags);
 	if (!vgadev)
 		return -ENODEV;
@@ -1464,7 +1469,7 @@ static void vga_arbiter_notify_clients(void)
 	spin_lock_irqsave(&vga_lock, flags);
 	list_for_each_entry(vgadev, &vga_list, list) {
 		if (vgadev->set_decode) {
-			new_decodes = vgadev->set_decode(vgadev->pdev,
+			new_decodes = vgadev->set_decode(vgadev->set_decode_data,
 							 new_state);
 			vga_update_device_decodes(vgadev, new_decodes);
 		}
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 6757054e9d87..b04ce3ded08c 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -162,9 +162,10 @@ static inline void vfio_pci_core_debugfs_init(struct vfio_pci_core_device *vdev)
  * has no way to get to it and routing can be disabled externally at the
  * bridge.
  */
-static unsigned int vfio_pci_set_decode(struct pci_dev *pdev, bool single_vga)
+static unsigned int vfio_pci_set_decode(void *data, bool single_vga)
 {
-	struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev);
+	struct vfio_pci_core_device *vdev = data;
+	struct pci_dev *pdev = vdev->pdev;
 	struct pci_dev *tmp = NULL;
 	unsigned char max_busnr;
 	unsigned int decodes;
@@ -2159,10 +2160,10 @@ static int vfio_pci_vga_init(struct vfio_pci_core_device *vdev)
 	if (ret)
 		return ret;
 
-	ret = vga_client_register(pdev, vfio_pci_set_decode);
+	ret = vga_client_register(pdev, vfio_pci_set_decode, vdev);
 	if (ret)
 		return ret;
-	vga_set_legacy_decoding(pdev, vfio_pci_set_decode(pdev, false));
+	vga_set_legacy_decoding(pdev, vfio_pci_set_decode(vdev, false));
 	return 0;
 }
 
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
index 97129a1bbb7d..71a364669eaf 100644
--- a/include/linux/vgaarb.h
+++ b/include/linux/vgaarb.h
@@ -33,7 +33,8 @@ struct pci_dev *vga_default_device(void);
 void vga_set_default_device(struct pci_dev *pdev);
 int vga_remove_vgacon(struct pci_dev *pdev);
 int vga_client_register(struct pci_dev *pdev,
-		unsigned int (*set_decode)(struct pci_dev *pdev, bool state));
+		unsigned int (*set_decode)(void *data, bool state),
+		void *data);
 #else /* CONFIG_VGA_ARB */
 static inline void vga_set_legacy_decoding(struct pci_dev *pdev,
 		unsigned int decodes)
@@ -59,7 +60,8 @@ static inline int vga_remove_vgacon(struct pci_dev *pdev)
 	return 0;
 }
 static inline int vga_client_register(struct pci_dev *pdev,
-		unsigned int (*set_decode)(struct pci_dev *pdev, bool state))
+		unsigned int (*set_decode)(void *data, bool state),
+		void *data)
 {
 	return 0;
 }
@@ -97,7 +99,7 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev,
 
 static inline void vga_client_unregister(struct pci_dev *pdev)
 {
-	vga_client_register(pdev, NULL);
+	vga_client_register(pdev, NULL, NULL);
 }
 
 #endif /* LINUX_VGA_H */
-- 
2.54.0


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

* Re: [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2)
  2026-09-22  7:18 [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2) Dave Airlie
@ 2026-09-22  7:25 ` sashiko-bot
  2026-09-22  8:44 ` Jani Nikula
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-09-22  7:25 UTC (permalink / raw)
  To: Dave Airlie; +Cc: dri-devel, kvm, linux-pci

> From: Dave Airlie <airlied@redhat.com>
> 
> This changes the vgaarb client API so that the user can pass a
> private data pointer into the register that will get used in
> the decode callback.
> 
> This allows a bunch of pdev conversions in the drivers, and lets
> some future vfio cleanups be nicer.
> 
> I'd like to merge this via the drm next tree but also fine with
> it going via pci.
> 
> Signed-off-by: Dave Airlie <airlied@redhat.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260922071807.2533884-1-airlied@gmail.com?part=1


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

* Re: [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2)
  2026-09-22  7:18 [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2) Dave Airlie
  2026-09-22  7:25 ` sashiko-bot
@ 2026-09-22  8:44 ` Jani Nikula
  2026-09-22 15:05 ` Alex Deucher
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Jani Nikula @ 2026-09-22  8:44 UTC (permalink / raw)
  To: Dave Airlie, dri-devel, linux-pci, kvm
  Cc: Jason Gunthorpe, Dave Airlie, Alex Williamson, Bjorn Helgaas,
	Rodrigo Vivi, Alex Deucher

On Tue, 22 Sep 2026, Dave Airlie <airlied@gmail.com> wrote:
> From: Dave Airlie <airlied@redhat.com>
>
> This changes the vgaarb client API so that the user can pass a
> private data pointer into the register that will get used in
> the decode callback.
>
> This allows a bunch of pdev conversions in the drivers, and lets
> some future vfio cleanups be nicer.
>
> I'd like to merge this via the drm next tree but also fine with
> it going via pci.
>
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> ---
> v2: fix loongson (spotted by sashiko)
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  6 +++---
>  drivers/gpu/drm/i915/display/intel_vga.c   |  7 ++++---
>  drivers/gpu/drm/loongson/lsdc_drv.c        |  4 ++--
>  drivers/gpu/drm/nouveau/nouveau_vga.c      |  6 +++---
>  drivers/gpu/drm/radeon/radeon_device.c     |  7 +++----
>  drivers/pci/vgaarb.c                       | 13 +++++++++----
>  drivers/vfio/pci/vfio_pci_core.c           |  9 +++++----
>  include/linux/vgaarb.h                     |  8 +++++---
>  8 files changed, 34 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 62b5b4a23f17..1344b2b1bd16 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1435,10 +1435,10 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
>   * Enable/disable vga decode (all asics).
>   * Returns VGA resource flags.
>   */
> -static unsigned int amdgpu_device_vga_set_decode(struct pci_dev *pdev,
> +static unsigned int amdgpu_device_vga_set_decode(void *data,
>  		bool state)
>  {
> -	struct amdgpu_device *adev = drm_to_adev(pci_get_drvdata(pdev));
> +	struct amdgpu_device *adev = (struct amdgpu_device *)data;

The cast is superfluous. Ditto everywhere else.

Other than that,

Reviewed-by: Jani Nikula <jani.nikula@intel.com>


>  
>  	amdgpu_asic_set_vga_state(adev, state);
>  	if (state)
> @@ -4208,7 +4208,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>  	 * ignore it
>  	 */
>  	if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
> -		vga_client_register(adev->pdev, amdgpu_device_vga_set_decode);
> +		vga_client_register(adev->pdev, amdgpu_device_vga_set_decode, adev);
>  
>  	px = amdgpu_device_supports_px(adev);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c
> index 4966fd7eea92..0889edb36190 100644
> --- a/drivers/gpu/drm/i915/display/intel_vga.c
> +++ b/drivers/gpu/drm/i915/display/intel_vga.c
> @@ -283,9 +283,10 @@ void intel_vga_disable(struct intel_display *display)
>  	intel_de_posting_read(display, vga_reg);
>  }
>  
> -static unsigned int intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
> +static unsigned int intel_vga_set_decode(void *data, bool enable_decode)
>  {
> -	struct intel_display *display = to_intel_display(pdev);
> +	struct intel_display *display = (struct intel_display *)data;
> +	struct pci_dev *pdev = to_pci_dev(display->drm->dev);
>  	unsigned int decodes = VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
>  
>  	drm_dbg_kms(display->drm, "%s VGA decode due to VGA arbitration\n",
> @@ -331,7 +332,7 @@ void intel_vga_register(struct intel_display *display)
>  	 * then we do not take part in VGA arbitration and the
>  	 * vga_client_register() fails with -ENODEV.
>  	 */
> -	ret = vga_client_register(pdev, intel_vga_set_decode);
> +	ret = vga_client_register(pdev, intel_vga_set_decode, display);
>  	drm_WARN_ON(display->drm, ret && ret != -ENODEV);
>  }
>  
> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c
> index 3fd828d23271..5a13df31eb90 100644
> --- a/drivers/gpu/drm/loongson/lsdc_drv.c
> +++ b/drivers/gpu/drm/loongson/lsdc_drv.c
> @@ -254,7 +254,7 @@ lsdc_create_device(struct pci_dev *pdev,
>  
>  /* For multiple GPU driver instance co-exixt in the system */
>  
> -static unsigned int lsdc_vga_set_decode(struct pci_dev *pdev, bool state)
> +static unsigned int lsdc_vga_set_decode(void *data, bool state)
>  {
>  	return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
>  }
> @@ -291,7 +291,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  
>  	pci_set_drvdata(pdev, ddev);
>  
> -	vga_client_register(pdev, lsdc_vga_set_decode);
> +	vga_client_register(pdev, lsdc_vga_set_decode, NULL);
>  
>  	drmm_kms_helper_poll_init(ddev);
>  
> diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c
> index 29a801124e56..6662e30466f2 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_vga.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
> @@ -9,9 +9,9 @@
>  #include "nouveau_vga.h"
>  
>  static unsigned int
> -nouveau_vga_set_decode(struct pci_dev *pdev, bool state)
> +nouveau_vga_set_decode(void *data, bool state)
>  {
> -	struct nouveau_drm *drm = pci_get_drvdata(pdev);
> +	struct nouveau_drm *drm = (struct nouveau_drm *)data;
>  	struct nvif_object *device = &drm->client.device.object;
>  
>  	if (drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE &&
> @@ -103,7 +103,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
>  		return;
>  	pdev = to_pci_dev(dev->dev);
>  
> -	vga_client_register(pdev, nouveau_vga_set_decode);
> +	vga_client_register(pdev, nouveau_vga_set_decode, drm);
>  
>  	/* don't register Thunderbolt eGPU with vga_switcheroo */
>  	if (pci_is_thunderbolt_attached(pdev))
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
> index 9523240110a6..cf8a6bd00c77 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -1076,10 +1076,9 @@ void radeon_combios_fini(struct radeon_device *rdev)
>   * Enable/disable vga decode (all asics).
>   * Returns VGA resource flags.
>   */
> -static unsigned int radeon_vga_set_decode(struct pci_dev *pdev, bool state)
> +static unsigned int radeon_vga_set_decode(void *data, bool state)
>  {
> -	struct drm_device *dev = pci_get_drvdata(pdev);
> -	struct radeon_device *rdev = dev->dev_private;
> +	struct radeon_device *rdev = (struct radeon_device *)data;
>  	radeon_vga_set_state(rdev, state);
>  	if (state)
>  		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
> @@ -1431,7 +1430,7 @@ int radeon_device_init(struct radeon_device *rdev,
>  	/* if we have > 1 VGA cards, then disable the radeon VGA resources */
>  	/* this will fail for cards that aren't VGA class devices, just
>  	 * ignore it */
> -	vga_client_register(rdev->pdev, radeon_vga_set_decode);
> +	vga_client_register(rdev->pdev, radeon_vga_set_decode, rdev);
>  
>  	if (rdev->flags & RADEON_IS_PX)
>  		runtime = true;
> diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
> index 3de05aee7859..3e58b2c05c85 100644
> --- a/drivers/pci/vgaarb.c
> +++ b/drivers/pci/vgaarb.c
> @@ -51,7 +51,8 @@ struct vga_device {
>  	unsigned int mem_norm_cnt;	/* normal MEM count */
>  	bool bridge_has_one_vga;
>  	bool is_firmware_default;	/* device selected by firmware */
> -	unsigned int (*set_decode)(struct pci_dev *pdev, bool decode);
> +	unsigned int (*set_decode)(void *data, bool decode);
> +	void *set_decode_data;
>  };
>  
>  static LIST_HEAD(vga_list);
> @@ -935,6 +936,7 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
>   * vga_client_register - register or unregister a VGA arbitration client
>   * @pdev: PCI device of the VGA client
>   * @set_decode: VGA decode change callback
> + * @data: private data to pass to callback
>   *
>   * Clients have two callback mechanisms they can use.
>   *
> @@ -956,15 +958,18 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
>   * Returns: 0 on success, -ENODEV on failure
>   */
>  int vga_client_register(struct pci_dev *pdev,
> -		unsigned int (*set_decode)(struct pci_dev *pdev, bool decode))
> +		unsigned int (*set_decode)(void *data, bool decode),
> +		void *data)
>  {
>  	unsigned long flags;
>  	struct vga_device *vgadev;
>  
>  	spin_lock_irqsave(&vga_lock, flags);
>  	vgadev = vgadev_find(pdev);
> -	if (vgadev)
> +	if (vgadev) {
>  		vgadev->set_decode = set_decode;
> +		vgadev->set_decode_data = data;
> +	}
>  	spin_unlock_irqrestore(&vga_lock, flags);
>  	if (!vgadev)
>  		return -ENODEV;
> @@ -1464,7 +1469,7 @@ static void vga_arbiter_notify_clients(void)
>  	spin_lock_irqsave(&vga_lock, flags);
>  	list_for_each_entry(vgadev, &vga_list, list) {
>  		if (vgadev->set_decode) {
> -			new_decodes = vgadev->set_decode(vgadev->pdev,
> +			new_decodes = vgadev->set_decode(vgadev->set_decode_data,
>  							 new_state);
>  			vga_update_device_decodes(vgadev, new_decodes);
>  		}
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 6757054e9d87..b04ce3ded08c 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -162,9 +162,10 @@ static inline void vfio_pci_core_debugfs_init(struct vfio_pci_core_device *vdev)
>   * has no way to get to it and routing can be disabled externally at the
>   * bridge.
>   */
> -static unsigned int vfio_pci_set_decode(struct pci_dev *pdev, bool single_vga)
> +static unsigned int vfio_pci_set_decode(void *data, bool single_vga)
>  {
> -	struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev);
> +	struct vfio_pci_core_device *vdev = data;
> +	struct pci_dev *pdev = vdev->pdev;
>  	struct pci_dev *tmp = NULL;
>  	unsigned char max_busnr;
>  	unsigned int decodes;
> @@ -2159,10 +2160,10 @@ static int vfio_pci_vga_init(struct vfio_pci_core_device *vdev)
>  	if (ret)
>  		return ret;
>  
> -	ret = vga_client_register(pdev, vfio_pci_set_decode);
> +	ret = vga_client_register(pdev, vfio_pci_set_decode, vdev);
>  	if (ret)
>  		return ret;
> -	vga_set_legacy_decoding(pdev, vfio_pci_set_decode(pdev, false));
> +	vga_set_legacy_decoding(pdev, vfio_pci_set_decode(vdev, false));
>  	return 0;
>  }
>  
> diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
> index 97129a1bbb7d..71a364669eaf 100644
> --- a/include/linux/vgaarb.h
> +++ b/include/linux/vgaarb.h
> @@ -33,7 +33,8 @@ struct pci_dev *vga_default_device(void);
>  void vga_set_default_device(struct pci_dev *pdev);
>  int vga_remove_vgacon(struct pci_dev *pdev);
>  int vga_client_register(struct pci_dev *pdev,
> -		unsigned int (*set_decode)(struct pci_dev *pdev, bool state));
> +		unsigned int (*set_decode)(void *data, bool state),
> +		void *data);
>  #else /* CONFIG_VGA_ARB */
>  static inline void vga_set_legacy_decoding(struct pci_dev *pdev,
>  		unsigned int decodes)
> @@ -59,7 +60,8 @@ static inline int vga_remove_vgacon(struct pci_dev *pdev)
>  	return 0;
>  }
>  static inline int vga_client_register(struct pci_dev *pdev,
> -		unsigned int (*set_decode)(struct pci_dev *pdev, bool state))
> +		unsigned int (*set_decode)(void *data, bool state),
> +		void *data)
>  {
>  	return 0;
>  }
> @@ -97,7 +99,7 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev,
>  
>  static inline void vga_client_unregister(struct pci_dev *pdev)
>  {
> -	vga_client_register(pdev, NULL);
> +	vga_client_register(pdev, NULL, NULL);
>  }
>  
>  #endif /* LINUX_VGA_H */

-- 
Jani Nikula, Intel

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

* Re: [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2)
  2026-09-22  7:18 [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2) Dave Airlie
  2026-09-22  7:25 ` sashiko-bot
  2026-09-22  8:44 ` Jani Nikula
@ 2026-09-22 15:05 ` Alex Deucher
  2026-09-28 19:33 ` Dave Airlie
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Alex Deucher @ 2026-09-22 15:05 UTC (permalink / raw)
  To: Dave Airlie
  Cc: dri-devel, linux-pci, kvm, Jason Gunthorpe, Dave Airlie,
	Alex Williamson, Bjorn Helgaas, Rodrigo Vivi, Alex Deucher

On Tue, Sep 22, 2026 at 3:18 AM Dave Airlie <airlied@gmail.com> wrote:
>
> From: Dave Airlie <airlied@redhat.com>
>
> This changes the vgaarb client API so that the user can pass a
> private data pointer into the register that will get used in
> the decode callback.
>
> This allows a bunch of pdev conversions in the drivers, and lets
> some future vfio cleanups be nicer.
>
> I'd like to merge this via the drm next tree but also fine with
> it going via pci.
>
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Alex Deucher <alexander.deucher@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
> v2: fix loongson (spotted by sashiko)
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  6 +++---
>  drivers/gpu/drm/i915/display/intel_vga.c   |  7 ++++---
>  drivers/gpu/drm/loongson/lsdc_drv.c        |  4 ++--
>  drivers/gpu/drm/nouveau/nouveau_vga.c      |  6 +++---
>  drivers/gpu/drm/radeon/radeon_device.c     |  7 +++----
>  drivers/pci/vgaarb.c                       | 13 +++++++++----
>  drivers/vfio/pci/vfio_pci_core.c           |  9 +++++----
>  include/linux/vgaarb.h                     |  8 +++++---
>  8 files changed, 34 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 62b5b4a23f17..1344b2b1bd16 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1435,10 +1435,10 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
>   * Enable/disable vga decode (all asics).
>   * Returns VGA resource flags.
>   */
> -static unsigned int amdgpu_device_vga_set_decode(struct pci_dev *pdev,
> +static unsigned int amdgpu_device_vga_set_decode(void *data,
>                 bool state)
>  {
> -       struct amdgpu_device *adev = drm_to_adev(pci_get_drvdata(pdev));
> +       struct amdgpu_device *adev = (struct amdgpu_device *)data;
>
>         amdgpu_asic_set_vga_state(adev, state);
>         if (state)
> @@ -4208,7 +4208,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>          * ignore it
>          */
>         if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
> -               vga_client_register(adev->pdev, amdgpu_device_vga_set_decode);
> +               vga_client_register(adev->pdev, amdgpu_device_vga_set_decode, adev);
>
>         px = amdgpu_device_supports_px(adev);
>
> diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c
> index 4966fd7eea92..0889edb36190 100644
> --- a/drivers/gpu/drm/i915/display/intel_vga.c
> +++ b/drivers/gpu/drm/i915/display/intel_vga.c
> @@ -283,9 +283,10 @@ void intel_vga_disable(struct intel_display *display)
>         intel_de_posting_read(display, vga_reg);
>  }
>
> -static unsigned int intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
> +static unsigned int intel_vga_set_decode(void *data, bool enable_decode)
>  {
> -       struct intel_display *display = to_intel_display(pdev);
> +       struct intel_display *display = (struct intel_display *)data;
> +       struct pci_dev *pdev = to_pci_dev(display->drm->dev);
>         unsigned int decodes = VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
>
>         drm_dbg_kms(display->drm, "%s VGA decode due to VGA arbitration\n",
> @@ -331,7 +332,7 @@ void intel_vga_register(struct intel_display *display)
>          * then we do not take part in VGA arbitration and the
>          * vga_client_register() fails with -ENODEV.
>          */
> -       ret = vga_client_register(pdev, intel_vga_set_decode);
> +       ret = vga_client_register(pdev, intel_vga_set_decode, display);
>         drm_WARN_ON(display->drm, ret && ret != -ENODEV);
>  }
>
> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c
> index 3fd828d23271..5a13df31eb90 100644
> --- a/drivers/gpu/drm/loongson/lsdc_drv.c
> +++ b/drivers/gpu/drm/loongson/lsdc_drv.c
> @@ -254,7 +254,7 @@ lsdc_create_device(struct pci_dev *pdev,
>
>  /* For multiple GPU driver instance co-exixt in the system */
>
> -static unsigned int lsdc_vga_set_decode(struct pci_dev *pdev, bool state)
> +static unsigned int lsdc_vga_set_decode(void *data, bool state)
>  {
>         return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
>  }
> @@ -291,7 +291,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>
>         pci_set_drvdata(pdev, ddev);
>
> -       vga_client_register(pdev, lsdc_vga_set_decode);
> +       vga_client_register(pdev, lsdc_vga_set_decode, NULL);
>
>         drmm_kms_helper_poll_init(ddev);
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c
> index 29a801124e56..6662e30466f2 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_vga.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
> @@ -9,9 +9,9 @@
>  #include "nouveau_vga.h"
>
>  static unsigned int
> -nouveau_vga_set_decode(struct pci_dev *pdev, bool state)
> +nouveau_vga_set_decode(void *data, bool state)
>  {
> -       struct nouveau_drm *drm = pci_get_drvdata(pdev);
> +       struct nouveau_drm *drm = (struct nouveau_drm *)data;
>         struct nvif_object *device = &drm->client.device.object;
>
>         if (drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE &&
> @@ -103,7 +103,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
>                 return;
>         pdev = to_pci_dev(dev->dev);
>
> -       vga_client_register(pdev, nouveau_vga_set_decode);
> +       vga_client_register(pdev, nouveau_vga_set_decode, drm);
>
>         /* don't register Thunderbolt eGPU with vga_switcheroo */
>         if (pci_is_thunderbolt_attached(pdev))
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
> index 9523240110a6..cf8a6bd00c77 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -1076,10 +1076,9 @@ void radeon_combios_fini(struct radeon_device *rdev)
>   * Enable/disable vga decode (all asics).
>   * Returns VGA resource flags.
>   */
> -static unsigned int radeon_vga_set_decode(struct pci_dev *pdev, bool state)
> +static unsigned int radeon_vga_set_decode(void *data, bool state)
>  {
> -       struct drm_device *dev = pci_get_drvdata(pdev);
> -       struct radeon_device *rdev = dev->dev_private;
> +       struct radeon_device *rdev = (struct radeon_device *)data;
>         radeon_vga_set_state(rdev, state);
>         if (state)
>                 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
> @@ -1431,7 +1430,7 @@ int radeon_device_init(struct radeon_device *rdev,
>         /* if we have > 1 VGA cards, then disable the radeon VGA resources */
>         /* this will fail for cards that aren't VGA class devices, just
>          * ignore it */
> -       vga_client_register(rdev->pdev, radeon_vga_set_decode);
> +       vga_client_register(rdev->pdev, radeon_vga_set_decode, rdev);
>
>         if (rdev->flags & RADEON_IS_PX)
>                 runtime = true;
> diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
> index 3de05aee7859..3e58b2c05c85 100644
> --- a/drivers/pci/vgaarb.c
> +++ b/drivers/pci/vgaarb.c
> @@ -51,7 +51,8 @@ struct vga_device {
>         unsigned int mem_norm_cnt;      /* normal MEM count */
>         bool bridge_has_one_vga;
>         bool is_firmware_default;       /* device selected by firmware */
> -       unsigned int (*set_decode)(struct pci_dev *pdev, bool decode);
> +       unsigned int (*set_decode)(void *data, bool decode);
> +       void *set_decode_data;
>  };
>
>  static LIST_HEAD(vga_list);
> @@ -935,6 +936,7 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
>   * vga_client_register - register or unregister a VGA arbitration client
>   * @pdev: PCI device of the VGA client
>   * @set_decode: VGA decode change callback
> + * @data: private data to pass to callback
>   *
>   * Clients have two callback mechanisms they can use.
>   *
> @@ -956,15 +958,18 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
>   * Returns: 0 on success, -ENODEV on failure
>   */
>  int vga_client_register(struct pci_dev *pdev,
> -               unsigned int (*set_decode)(struct pci_dev *pdev, bool decode))
> +               unsigned int (*set_decode)(void *data, bool decode),
> +               void *data)
>  {
>         unsigned long flags;
>         struct vga_device *vgadev;
>
>         spin_lock_irqsave(&vga_lock, flags);
>         vgadev = vgadev_find(pdev);
> -       if (vgadev)
> +       if (vgadev) {
>                 vgadev->set_decode = set_decode;
> +               vgadev->set_decode_data = data;
> +       }
>         spin_unlock_irqrestore(&vga_lock, flags);
>         if (!vgadev)
>                 return -ENODEV;
> @@ -1464,7 +1469,7 @@ static void vga_arbiter_notify_clients(void)
>         spin_lock_irqsave(&vga_lock, flags);
>         list_for_each_entry(vgadev, &vga_list, list) {
>                 if (vgadev->set_decode) {
> -                       new_decodes = vgadev->set_decode(vgadev->pdev,
> +                       new_decodes = vgadev->set_decode(vgadev->set_decode_data,
>                                                          new_state);
>                         vga_update_device_decodes(vgadev, new_decodes);
>                 }
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 6757054e9d87..b04ce3ded08c 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -162,9 +162,10 @@ static inline void vfio_pci_core_debugfs_init(struct vfio_pci_core_device *vdev)
>   * has no way to get to it and routing can be disabled externally at the
>   * bridge.
>   */
> -static unsigned int vfio_pci_set_decode(struct pci_dev *pdev, bool single_vga)
> +static unsigned int vfio_pci_set_decode(void *data, bool single_vga)
>  {
> -       struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev);
> +       struct vfio_pci_core_device *vdev = data;
> +       struct pci_dev *pdev = vdev->pdev;
>         struct pci_dev *tmp = NULL;
>         unsigned char max_busnr;
>         unsigned int decodes;
> @@ -2159,10 +2160,10 @@ static int vfio_pci_vga_init(struct vfio_pci_core_device *vdev)
>         if (ret)
>                 return ret;
>
> -       ret = vga_client_register(pdev, vfio_pci_set_decode);
> +       ret = vga_client_register(pdev, vfio_pci_set_decode, vdev);
>         if (ret)
>                 return ret;
> -       vga_set_legacy_decoding(pdev, vfio_pci_set_decode(pdev, false));
> +       vga_set_legacy_decoding(pdev, vfio_pci_set_decode(vdev, false));
>         return 0;
>  }
>
> diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
> index 97129a1bbb7d..71a364669eaf 100644
> --- a/include/linux/vgaarb.h
> +++ b/include/linux/vgaarb.h
> @@ -33,7 +33,8 @@ struct pci_dev *vga_default_device(void);
>  void vga_set_default_device(struct pci_dev *pdev);
>  int vga_remove_vgacon(struct pci_dev *pdev);
>  int vga_client_register(struct pci_dev *pdev,
> -               unsigned int (*set_decode)(struct pci_dev *pdev, bool state));
> +               unsigned int (*set_decode)(void *data, bool state),
> +               void *data);
>  #else /* CONFIG_VGA_ARB */
>  static inline void vga_set_legacy_decoding(struct pci_dev *pdev,
>                 unsigned int decodes)
> @@ -59,7 +60,8 @@ static inline int vga_remove_vgacon(struct pci_dev *pdev)
>         return 0;
>  }
>  static inline int vga_client_register(struct pci_dev *pdev,
> -               unsigned int (*set_decode)(struct pci_dev *pdev, bool state))
> +               unsigned int (*set_decode)(void *data, bool state),
> +               void *data)
>  {
>         return 0;
>  }
> @@ -97,7 +99,7 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev,
>
>  static inline void vga_client_unregister(struct pci_dev *pdev)
>  {
> -       vga_client_register(pdev, NULL);
> +       vga_client_register(pdev, NULL, NULL);
>  }
>
>  #endif /* LINUX_VGA_H */
> --
> 2.54.0
>

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

* Re: [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2)
  2026-09-22  7:18 [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2) Dave Airlie
                   ` (2 preceding siblings ...)
  2026-09-22 15:05 ` Alex Deucher
@ 2026-09-28 19:33 ` Dave Airlie
  2026-09-28 20:00 ` Alex Williamson
  2026-09-28 20:14 ` Bjorn Helgaas
  5 siblings, 0 replies; 8+ messages in thread
From: Dave Airlie @ 2026-09-28 19:33 UTC (permalink / raw)
  To: dri-devel, linux-pci, kvm
  Cc: Jason Gunthorpe, Dave Airlie, Alex Williamson, Bjorn Helgaas,
	Rodrigo Vivi, Alex Deucher

> This changes the vgaarb client API so that the user can pass a
> private data pointer into the register that will get used in
> the decode callback.
>
> This allows a bunch of pdev conversions in the drivers, and lets
> some future vfio cleanups be nicer.
>
> I'd like to merge this via the drm next tree but also fine with
> it going via pci.
>
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> ---
> v2: fix loongson (spotted by sashiko)

@Alex Williamson or @Jason Gunthorpe can I get an ack on the vfio
piece, since I think the initial report on this problem came from
Jason.

Dave.

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  6 +++---
>  drivers/gpu/drm/i915/display/intel_vga.c   |  7 ++++---
>  drivers/gpu/drm/loongson/lsdc_drv.c        |  4 ++--
>  drivers/gpu/drm/nouveau/nouveau_vga.c      |  6 +++---
>  drivers/gpu/drm/radeon/radeon_device.c     |  7 +++----
>  drivers/pci/vgaarb.c                       | 13 +++++++++----
>  drivers/vfio/pci/vfio_pci_core.c           |  9 +++++----
>  include/linux/vgaarb.h                     |  8 +++++---
>  8 files changed, 34 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 62b5b4a23f17..1344b2b1bd16 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1435,10 +1435,10 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
>   * Enable/disable vga decode (all asics).
>   * Returns VGA resource flags.
>   */
> -static unsigned int amdgpu_device_vga_set_decode(struct pci_dev *pdev,
> +static unsigned int amdgpu_device_vga_set_decode(void *data,
>                 bool state)
>  {
> -       struct amdgpu_device *adev = drm_to_adev(pci_get_drvdata(pdev));
> +       struct amdgpu_device *adev = (struct amdgpu_device *)data;
>
>         amdgpu_asic_set_vga_state(adev, state);
>         if (state)
> @@ -4208,7 +4208,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>          * ignore it
>          */
>         if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
> -               vga_client_register(adev->pdev, amdgpu_device_vga_set_decode);
> +               vga_client_register(adev->pdev, amdgpu_device_vga_set_decode, adev);
>
>         px = amdgpu_device_supports_px(adev);
>
> diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c
> index 4966fd7eea92..0889edb36190 100644
> --- a/drivers/gpu/drm/i915/display/intel_vga.c
> +++ b/drivers/gpu/drm/i915/display/intel_vga.c
> @@ -283,9 +283,10 @@ void intel_vga_disable(struct intel_display *display)
>         intel_de_posting_read(display, vga_reg);
>  }
>
> -static unsigned int intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
> +static unsigned int intel_vga_set_decode(void *data, bool enable_decode)
>  {
> -       struct intel_display *display = to_intel_display(pdev);
> +       struct intel_display *display = (struct intel_display *)data;
> +       struct pci_dev *pdev = to_pci_dev(display->drm->dev);
>         unsigned int decodes = VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
>
>         drm_dbg_kms(display->drm, "%s VGA decode due to VGA arbitration\n",
> @@ -331,7 +332,7 @@ void intel_vga_register(struct intel_display *display)
>          * then we do not take part in VGA arbitration and the
>          * vga_client_register() fails with -ENODEV.
>          */
> -       ret = vga_client_register(pdev, intel_vga_set_decode);
> +       ret = vga_client_register(pdev, intel_vga_set_decode, display);
>         drm_WARN_ON(display->drm, ret && ret != -ENODEV);
>  }
>
> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c
> index 3fd828d23271..5a13df31eb90 100644
> --- a/drivers/gpu/drm/loongson/lsdc_drv.c
> +++ b/drivers/gpu/drm/loongson/lsdc_drv.c
> @@ -254,7 +254,7 @@ lsdc_create_device(struct pci_dev *pdev,
>
>  /* For multiple GPU driver instance co-exixt in the system */
>
> -static unsigned int lsdc_vga_set_decode(struct pci_dev *pdev, bool state)
> +static unsigned int lsdc_vga_set_decode(void *data, bool state)
>  {
>         return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
>  }
> @@ -291,7 +291,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>
>         pci_set_drvdata(pdev, ddev);
>
> -       vga_client_register(pdev, lsdc_vga_set_decode);
> +       vga_client_register(pdev, lsdc_vga_set_decode, NULL);
>
>         drmm_kms_helper_poll_init(ddev);
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c
> index 29a801124e56..6662e30466f2 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_vga.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
> @@ -9,9 +9,9 @@
>  #include "nouveau_vga.h"
>
>  static unsigned int
> -nouveau_vga_set_decode(struct pci_dev *pdev, bool state)
> +nouveau_vga_set_decode(void *data, bool state)
>  {
> -       struct nouveau_drm *drm = pci_get_drvdata(pdev);
> +       struct nouveau_drm *drm = (struct nouveau_drm *)data;
>         struct nvif_object *device = &drm->client.device.object;
>
>         if (drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE &&
> @@ -103,7 +103,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
>                 return;
>         pdev = to_pci_dev(dev->dev);
>
> -       vga_client_register(pdev, nouveau_vga_set_decode);
> +       vga_client_register(pdev, nouveau_vga_set_decode, drm);
>
>         /* don't register Thunderbolt eGPU with vga_switcheroo */
>         if (pci_is_thunderbolt_attached(pdev))
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
> index 9523240110a6..cf8a6bd00c77 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -1076,10 +1076,9 @@ void radeon_combios_fini(struct radeon_device *rdev)
>   * Enable/disable vga decode (all asics).
>   * Returns VGA resource flags.
>   */
> -static unsigned int radeon_vga_set_decode(struct pci_dev *pdev, bool state)
> +static unsigned int radeon_vga_set_decode(void *data, bool state)
>  {
> -       struct drm_device *dev = pci_get_drvdata(pdev);
> -       struct radeon_device *rdev = dev->dev_private;
> +       struct radeon_device *rdev = (struct radeon_device *)data;
>         radeon_vga_set_state(rdev, state);
>         if (state)
>                 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
> @@ -1431,7 +1430,7 @@ int radeon_device_init(struct radeon_device *rdev,
>         /* if we have > 1 VGA cards, then disable the radeon VGA resources */
>         /* this will fail for cards that aren't VGA class devices, just
>          * ignore it */
> -       vga_client_register(rdev->pdev, radeon_vga_set_decode);
> +       vga_client_register(rdev->pdev, radeon_vga_set_decode, rdev);
>
>         if (rdev->flags & RADEON_IS_PX)
>                 runtime = true;
> diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
> index 3de05aee7859..3e58b2c05c85 100644
> --- a/drivers/pci/vgaarb.c
> +++ b/drivers/pci/vgaarb.c
> @@ -51,7 +51,8 @@ struct vga_device {
>         unsigned int mem_norm_cnt;      /* normal MEM count */
>         bool bridge_has_one_vga;
>         bool is_firmware_default;       /* device selected by firmware */
> -       unsigned int (*set_decode)(struct pci_dev *pdev, bool decode);
> +       unsigned int (*set_decode)(void *data, bool decode);
> +       void *set_decode_data;
>  };
>
>  static LIST_HEAD(vga_list);
> @@ -935,6 +936,7 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
>   * vga_client_register - register or unregister a VGA arbitration client
>   * @pdev: PCI device of the VGA client
>   * @set_decode: VGA decode change callback
> + * @data: private data to pass to callback
>   *
>   * Clients have two callback mechanisms they can use.
>   *
> @@ -956,15 +958,18 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
>   * Returns: 0 on success, -ENODEV on failure
>   */
>  int vga_client_register(struct pci_dev *pdev,
> -               unsigned int (*set_decode)(struct pci_dev *pdev, bool decode))
> +               unsigned int (*set_decode)(void *data, bool decode),
> +               void *data)
>  {
>         unsigned long flags;
>         struct vga_device *vgadev;
>
>         spin_lock_irqsave(&vga_lock, flags);
>         vgadev = vgadev_find(pdev);
> -       if (vgadev)
> +       if (vgadev) {
>                 vgadev->set_decode = set_decode;
> +               vgadev->set_decode_data = data;
> +       }
>         spin_unlock_irqrestore(&vga_lock, flags);
>         if (!vgadev)
>                 return -ENODEV;
> @@ -1464,7 +1469,7 @@ static void vga_arbiter_notify_clients(void)
>         spin_lock_irqsave(&vga_lock, flags);
>         list_for_each_entry(vgadev, &vga_list, list) {
>                 if (vgadev->set_decode) {
> -                       new_decodes = vgadev->set_decode(vgadev->pdev,
> +                       new_decodes = vgadev->set_decode(vgadev->set_decode_data,
>                                                          new_state);
>                         vga_update_device_decodes(vgadev, new_decodes);
>                 }
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 6757054e9d87..b04ce3ded08c 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -162,9 +162,10 @@ static inline void vfio_pci_core_debugfs_init(struct vfio_pci_core_device *vdev)
>   * has no way to get to it and routing can be disabled externally at the
>   * bridge.
>   */
> -static unsigned int vfio_pci_set_decode(struct pci_dev *pdev, bool single_vga)
> +static unsigned int vfio_pci_set_decode(void *data, bool single_vga)
>  {
> -       struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev);
> +       struct vfio_pci_core_device *vdev = data;
> +       struct pci_dev *pdev = vdev->pdev;
>         struct pci_dev *tmp = NULL;
>         unsigned char max_busnr;
>         unsigned int decodes;
> @@ -2159,10 +2160,10 @@ static int vfio_pci_vga_init(struct vfio_pci_core_device *vdev)
>         if (ret)
>                 return ret;
>
> -       ret = vga_client_register(pdev, vfio_pci_set_decode);
> +       ret = vga_client_register(pdev, vfio_pci_set_decode, vdev);
>         if (ret)
>                 return ret;
> -       vga_set_legacy_decoding(pdev, vfio_pci_set_decode(pdev, false));
> +       vga_set_legacy_decoding(pdev, vfio_pci_set_decode(vdev, false));
>         return 0;
>  }
>
> diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
> index 97129a1bbb7d..71a364669eaf 100644
> --- a/include/linux/vgaarb.h
> +++ b/include/linux/vgaarb.h
> @@ -33,7 +33,8 @@ struct pci_dev *vga_default_device(void);
>  void vga_set_default_device(struct pci_dev *pdev);
>  int vga_remove_vgacon(struct pci_dev *pdev);
>  int vga_client_register(struct pci_dev *pdev,
> -               unsigned int (*set_decode)(struct pci_dev *pdev, bool state));
> +               unsigned int (*set_decode)(void *data, bool state),
> +               void *data);
>  #else /* CONFIG_VGA_ARB */
>  static inline void vga_set_legacy_decoding(struct pci_dev *pdev,
>                 unsigned int decodes)
> @@ -59,7 +60,8 @@ static inline int vga_remove_vgacon(struct pci_dev *pdev)
>         return 0;
>  }
>  static inline int vga_client_register(struct pci_dev *pdev,
> -               unsigned int (*set_decode)(struct pci_dev *pdev, bool state))
> +               unsigned int (*set_decode)(void *data, bool state),
> +               void *data)
>  {
>         return 0;
>  }
> @@ -97,7 +99,7 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev,
>
>  static inline void vga_client_unregister(struct pci_dev *pdev)
>  {
> -       vga_client_register(pdev, NULL);
> +       vga_client_register(pdev, NULL, NULL);
>  }
>
>  #endif /* LINUX_VGA_H */
> --
> 2.54.0
>

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

* Re: [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2)
  2026-09-22  7:18 [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2) Dave Airlie
                   ` (3 preceding siblings ...)
  2026-09-28 19:33 ` Dave Airlie
@ 2026-09-28 20:00 ` Alex Williamson
  2026-10-01  1:08   ` David Airlie
  2026-09-28 20:14 ` Bjorn Helgaas
  5 siblings, 1 reply; 8+ messages in thread
From: Alex Williamson @ 2026-09-28 20:00 UTC (permalink / raw)
  To: Dave Airlie
  Cc: dri-devel, linux-pci, kvm, Jason Gunthorpe, Dave Airlie,
	Bjorn Helgaas, Rodrigo Vivi, Alex Deucher, alex,
	Simon Song (SW-GPU)

On Tue, 22 Sep 2026 17:18:07 +1000
Dave Airlie <airlied@gmail.com> wrote:

> From: Dave Airlie <airlied@redhat.com>
> 
> This changes the vgaarb client API so that the user can pass a
> private data pointer into the register that will get used in
> the decode callback.
> 
> This allows a bunch of pdev conversions in the drivers, and lets
> some future vfio cleanups be nicer.
> 
> I'd like to merge this via the drm next tree but also fine with
> it going via pci.
> 
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> ---
> v2: fix loongson (spotted by sashiko)
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  6 +++---
>  drivers/gpu/drm/i915/display/intel_vga.c   |  7 ++++---
>  drivers/gpu/drm/loongson/lsdc_drv.c        |  4 ++--
>  drivers/gpu/drm/nouveau/nouveau_vga.c      |  6 +++---
>  drivers/gpu/drm/radeon/radeon_device.c     |  7 +++----
>  drivers/pci/vgaarb.c                       | 13 +++++++++----
>  drivers/vfio/pci/vfio_pci_core.c           |  9 +++++----
>  include/linux/vgaarb.h                     |  8 +++++---
>  8 files changed, 34 insertions(+), 26 deletions(-)


Acked-by: Alex Williamson <alex@shazbot.org>

Preemptively, could this get merged via a topic branch that we could
share in case further drvdata cleanup arrives in vfio-pci this cycle?

I'm imagining this might also be a good time to push vgaarb
registration out of vfio-pci-core as well.  Thanks,

Alex

 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 62b5b4a23f17..1344b2b1bd16 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1435,10 +1435,10 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
>   * Enable/disable vga decode (all asics).
>   * Returns VGA resource flags.
>   */
> -static unsigned int amdgpu_device_vga_set_decode(struct pci_dev *pdev,
> +static unsigned int amdgpu_device_vga_set_decode(void *data,
>  		bool state)
>  {
> -	struct amdgpu_device *adev = drm_to_adev(pci_get_drvdata(pdev));
> +	struct amdgpu_device *adev = (struct amdgpu_device *)data;
>  
>  	amdgpu_asic_set_vga_state(adev, state);
>  	if (state)
> @@ -4208,7 +4208,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>  	 * ignore it
>  	 */
>  	if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
> -		vga_client_register(adev->pdev, amdgpu_device_vga_set_decode);
> +		vga_client_register(adev->pdev, amdgpu_device_vga_set_decode, adev);
>  
>  	px = amdgpu_device_supports_px(adev);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c
> index 4966fd7eea92..0889edb36190 100644
> --- a/drivers/gpu/drm/i915/display/intel_vga.c
> +++ b/drivers/gpu/drm/i915/display/intel_vga.c
> @@ -283,9 +283,10 @@ void intel_vga_disable(struct intel_display *display)
>  	intel_de_posting_read(display, vga_reg);
>  }
>  
> -static unsigned int intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
> +static unsigned int intel_vga_set_decode(void *data, bool enable_decode)
>  {
> -	struct intel_display *display = to_intel_display(pdev);
> +	struct intel_display *display = (struct intel_display *)data;
> +	struct pci_dev *pdev = to_pci_dev(display->drm->dev);
>  	unsigned int decodes = VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
>  
>  	drm_dbg_kms(display->drm, "%s VGA decode due to VGA arbitration\n",
> @@ -331,7 +332,7 @@ void intel_vga_register(struct intel_display *display)
>  	 * then we do not take part in VGA arbitration and the
>  	 * vga_client_register() fails with -ENODEV.
>  	 */
> -	ret = vga_client_register(pdev, intel_vga_set_decode);
> +	ret = vga_client_register(pdev, intel_vga_set_decode, display);
>  	drm_WARN_ON(display->drm, ret && ret != -ENODEV);
>  }
>  
> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c
> index 3fd828d23271..5a13df31eb90 100644
> --- a/drivers/gpu/drm/loongson/lsdc_drv.c
> +++ b/drivers/gpu/drm/loongson/lsdc_drv.c
> @@ -254,7 +254,7 @@ lsdc_create_device(struct pci_dev *pdev,
>  
>  /* For multiple GPU driver instance co-exixt in the system */
>  
> -static unsigned int lsdc_vga_set_decode(struct pci_dev *pdev, bool state)
> +static unsigned int lsdc_vga_set_decode(void *data, bool state)
>  {
>  	return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
>  }
> @@ -291,7 +291,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  
>  	pci_set_drvdata(pdev, ddev);
>  
> -	vga_client_register(pdev, lsdc_vga_set_decode);
> +	vga_client_register(pdev, lsdc_vga_set_decode, NULL);
>  
>  	drmm_kms_helper_poll_init(ddev);
>  
> diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c
> index 29a801124e56..6662e30466f2 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_vga.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
> @@ -9,9 +9,9 @@
>  #include "nouveau_vga.h"
>  
>  static unsigned int
> -nouveau_vga_set_decode(struct pci_dev *pdev, bool state)
> +nouveau_vga_set_decode(void *data, bool state)
>  {
> -	struct nouveau_drm *drm = pci_get_drvdata(pdev);
> +	struct nouveau_drm *drm = (struct nouveau_drm *)data;
>  	struct nvif_object *device = &drm->client.device.object;
>  
>  	if (drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE &&
> @@ -103,7 +103,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
>  		return;
>  	pdev = to_pci_dev(dev->dev);
>  
> -	vga_client_register(pdev, nouveau_vga_set_decode);
> +	vga_client_register(pdev, nouveau_vga_set_decode, drm);
>  
>  	/* don't register Thunderbolt eGPU with vga_switcheroo */
>  	if (pci_is_thunderbolt_attached(pdev))
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
> index 9523240110a6..cf8a6bd00c77 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -1076,10 +1076,9 @@ void radeon_combios_fini(struct radeon_device *rdev)
>   * Enable/disable vga decode (all asics).
>   * Returns VGA resource flags.
>   */
> -static unsigned int radeon_vga_set_decode(struct pci_dev *pdev, bool state)
> +static unsigned int radeon_vga_set_decode(void *data, bool state)
>  {
> -	struct drm_device *dev = pci_get_drvdata(pdev);
> -	struct radeon_device *rdev = dev->dev_private;
> +	struct radeon_device *rdev = (struct radeon_device *)data;
>  	radeon_vga_set_state(rdev, state);
>  	if (state)
>  		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
> @@ -1431,7 +1430,7 @@ int radeon_device_init(struct radeon_device *rdev,
>  	/* if we have > 1 VGA cards, then disable the radeon VGA resources */
>  	/* this will fail for cards that aren't VGA class devices, just
>  	 * ignore it */
> -	vga_client_register(rdev->pdev, radeon_vga_set_decode);
> +	vga_client_register(rdev->pdev, radeon_vga_set_decode, rdev);
>  
>  	if (rdev->flags & RADEON_IS_PX)
>  		runtime = true;
> diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
> index 3de05aee7859..3e58b2c05c85 100644
> --- a/drivers/pci/vgaarb.c
> +++ b/drivers/pci/vgaarb.c
> @@ -51,7 +51,8 @@ struct vga_device {
>  	unsigned int mem_norm_cnt;	/* normal MEM count */
>  	bool bridge_has_one_vga;
>  	bool is_firmware_default;	/* device selected by firmware */
> -	unsigned int (*set_decode)(struct pci_dev *pdev, bool decode);
> +	unsigned int (*set_decode)(void *data, bool decode);
> +	void *set_decode_data;
>  };
>  
>  static LIST_HEAD(vga_list);
> @@ -935,6 +936,7 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
>   * vga_client_register - register or unregister a VGA arbitration client
>   * @pdev: PCI device of the VGA client
>   * @set_decode: VGA decode change callback
> + * @data: private data to pass to callback
>   *
>   * Clients have two callback mechanisms they can use.
>   *
> @@ -956,15 +958,18 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
>   * Returns: 0 on success, -ENODEV on failure
>   */
>  int vga_client_register(struct pci_dev *pdev,
> -		unsigned int (*set_decode)(struct pci_dev *pdev, bool decode))
> +		unsigned int (*set_decode)(void *data, bool decode),
> +		void *data)
>  {
>  	unsigned long flags;
>  	struct vga_device *vgadev;
>  
>  	spin_lock_irqsave(&vga_lock, flags);
>  	vgadev = vgadev_find(pdev);
> -	if (vgadev)
> +	if (vgadev) {
>  		vgadev->set_decode = set_decode;
> +		vgadev->set_decode_data = data;
> +	}
>  	spin_unlock_irqrestore(&vga_lock, flags);
>  	if (!vgadev)
>  		return -ENODEV;
> @@ -1464,7 +1469,7 @@ static void vga_arbiter_notify_clients(void)
>  	spin_lock_irqsave(&vga_lock, flags);
>  	list_for_each_entry(vgadev, &vga_list, list) {
>  		if (vgadev->set_decode) {
> -			new_decodes = vgadev->set_decode(vgadev->pdev,
> +			new_decodes = vgadev->set_decode(vgadev->set_decode_data,
>  							 new_state);
>  			vga_update_device_decodes(vgadev, new_decodes);
>  		}
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 6757054e9d87..b04ce3ded08c 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -162,9 +162,10 @@ static inline void vfio_pci_core_debugfs_init(struct vfio_pci_core_device *vdev)
>   * has no way to get to it and routing can be disabled externally at the
>   * bridge.
>   */
> -static unsigned int vfio_pci_set_decode(struct pci_dev *pdev, bool single_vga)
> +static unsigned int vfio_pci_set_decode(void *data, bool single_vga)
>  {
> -	struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev);
> +	struct vfio_pci_core_device *vdev = data;
> +	struct pci_dev *pdev = vdev->pdev;
>  	struct pci_dev *tmp = NULL;
>  	unsigned char max_busnr;
>  	unsigned int decodes;
> @@ -2159,10 +2160,10 @@ static int vfio_pci_vga_init(struct vfio_pci_core_device *vdev)
>  	if (ret)
>  		return ret;
>  
> -	ret = vga_client_register(pdev, vfio_pci_set_decode);
> +	ret = vga_client_register(pdev, vfio_pci_set_decode, vdev);
>  	if (ret)
>  		return ret;
> -	vga_set_legacy_decoding(pdev, vfio_pci_set_decode(pdev, false));
> +	vga_set_legacy_decoding(pdev, vfio_pci_set_decode(vdev, false));
>  	return 0;
>  }
>  
> diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
> index 97129a1bbb7d..71a364669eaf 100644
> --- a/include/linux/vgaarb.h
> +++ b/include/linux/vgaarb.h
> @@ -33,7 +33,8 @@ struct pci_dev *vga_default_device(void);
>  void vga_set_default_device(struct pci_dev *pdev);
>  int vga_remove_vgacon(struct pci_dev *pdev);
>  int vga_client_register(struct pci_dev *pdev,
> -		unsigned int (*set_decode)(struct pci_dev *pdev, bool state));
> +		unsigned int (*set_decode)(void *data, bool state),
> +		void *data);
>  #else /* CONFIG_VGA_ARB */
>  static inline void vga_set_legacy_decoding(struct pci_dev *pdev,
>  		unsigned int decodes)
> @@ -59,7 +60,8 @@ static inline int vga_remove_vgacon(struct pci_dev *pdev)
>  	return 0;
>  }
>  static inline int vga_client_register(struct pci_dev *pdev,
> -		unsigned int (*set_decode)(struct pci_dev *pdev, bool state))
> +		unsigned int (*set_decode)(void *data, bool state),
> +		void *data)
>  {
>  	return 0;
>  }
> @@ -97,7 +99,7 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev,
>  
>  static inline void vga_client_unregister(struct pci_dev *pdev)
>  {
> -	vga_client_register(pdev, NULL);
> +	vga_client_register(pdev, NULL, NULL);
>  }
>  
>  #endif /* LINUX_VGA_H */


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

* Re: [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2)
  2026-09-22  7:18 [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2) Dave Airlie
                   ` (4 preceding siblings ...)
  2026-09-28 20:00 ` Alex Williamson
@ 2026-09-28 20:14 ` Bjorn Helgaas
  5 siblings, 0 replies; 8+ messages in thread
From: Bjorn Helgaas @ 2026-09-28 20:14 UTC (permalink / raw)
  To: Dave Airlie
  Cc: dri-devel, linux-pci, kvm, Jason Gunthorpe, Dave Airlie,
	Alex Williamson, Bjorn Helgaas, Rodrigo Vivi, Alex Deucher

On Tue, Sep 22, 2026 at 05:18:07PM +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied@redhat.com>
> 
> This changes the vgaarb client API so that the user can pass a
> private data pointer into the register that will get used in
> the decode callback.
> 
> This allows a bunch of pdev conversions in the drivers, and lets
> some future vfio cleanups be nicer.
> 
> I'd like to merge this via the drm next tree but also fine with
> it going via pci.
> 
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Alex Deucher <alexander.deucher@amd.com>

The only diff between v1
(https://lore.kernel.org/all/20260922064111.2468741-1-airlied@gmail.com)
and this is the trivial Loongson change.

It looks like the new kernel-doc warning is still there:
https://lore.kernel.org/all/202609241015.1yXHBzfy-lkp@intel.com/

And it would still be nice to update the subject line as I mentioned:
https://lore.kernel.org/all/20260924191253.GA1994586@bhelgaas

I'm still fine with it being merged via drm.

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

> ---
> v2: fix loongson (spotted by sashiko)
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  6 +++---
>  drivers/gpu/drm/i915/display/intel_vga.c   |  7 ++++---
>  drivers/gpu/drm/loongson/lsdc_drv.c        |  4 ++--
>  drivers/gpu/drm/nouveau/nouveau_vga.c      |  6 +++---
>  drivers/gpu/drm/radeon/radeon_device.c     |  7 +++----
>  drivers/pci/vgaarb.c                       | 13 +++++++++----
>  drivers/vfio/pci/vfio_pci_core.c           |  9 +++++----
>  include/linux/vgaarb.h                     |  8 +++++---
>  8 files changed, 34 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 62b5b4a23f17..1344b2b1bd16 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1435,10 +1435,10 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
>   * Enable/disable vga decode (all asics).
>   * Returns VGA resource flags.
>   */
> -static unsigned int amdgpu_device_vga_set_decode(struct pci_dev *pdev,
> +static unsigned int amdgpu_device_vga_set_decode(void *data,
>  		bool state)
>  {
> -	struct amdgpu_device *adev = drm_to_adev(pci_get_drvdata(pdev));
> +	struct amdgpu_device *adev = (struct amdgpu_device *)data;
>  
>  	amdgpu_asic_set_vga_state(adev, state);
>  	if (state)
> @@ -4208,7 +4208,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>  	 * ignore it
>  	 */
>  	if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
> -		vga_client_register(adev->pdev, amdgpu_device_vga_set_decode);
> +		vga_client_register(adev->pdev, amdgpu_device_vga_set_decode, adev);
>  
>  	px = amdgpu_device_supports_px(adev);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c
> index 4966fd7eea92..0889edb36190 100644
> --- a/drivers/gpu/drm/i915/display/intel_vga.c
> +++ b/drivers/gpu/drm/i915/display/intel_vga.c
> @@ -283,9 +283,10 @@ void intel_vga_disable(struct intel_display *display)
>  	intel_de_posting_read(display, vga_reg);
>  }
>  
> -static unsigned int intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
> +static unsigned int intel_vga_set_decode(void *data, bool enable_decode)
>  {
> -	struct intel_display *display = to_intel_display(pdev);
> +	struct intel_display *display = (struct intel_display *)data;
> +	struct pci_dev *pdev = to_pci_dev(display->drm->dev);
>  	unsigned int decodes = VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
>  
>  	drm_dbg_kms(display->drm, "%s VGA decode due to VGA arbitration\n",
> @@ -331,7 +332,7 @@ void intel_vga_register(struct intel_display *display)
>  	 * then we do not take part in VGA arbitration and the
>  	 * vga_client_register() fails with -ENODEV.
>  	 */
> -	ret = vga_client_register(pdev, intel_vga_set_decode);
> +	ret = vga_client_register(pdev, intel_vga_set_decode, display);
>  	drm_WARN_ON(display->drm, ret && ret != -ENODEV);
>  }
>  
> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c
> index 3fd828d23271..5a13df31eb90 100644
> --- a/drivers/gpu/drm/loongson/lsdc_drv.c
> +++ b/drivers/gpu/drm/loongson/lsdc_drv.c
> @@ -254,7 +254,7 @@ lsdc_create_device(struct pci_dev *pdev,
>  
>  /* For multiple GPU driver instance co-exixt in the system */
>  
> -static unsigned int lsdc_vga_set_decode(struct pci_dev *pdev, bool state)
> +static unsigned int lsdc_vga_set_decode(void *data, bool state)
>  {
>  	return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
>  }
> @@ -291,7 +291,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  
>  	pci_set_drvdata(pdev, ddev);
>  
> -	vga_client_register(pdev, lsdc_vga_set_decode);
> +	vga_client_register(pdev, lsdc_vga_set_decode, NULL);
>  
>  	drmm_kms_helper_poll_init(ddev);
>  
> diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c
> index 29a801124e56..6662e30466f2 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_vga.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
> @@ -9,9 +9,9 @@
>  #include "nouveau_vga.h"
>  
>  static unsigned int
> -nouveau_vga_set_decode(struct pci_dev *pdev, bool state)
> +nouveau_vga_set_decode(void *data, bool state)
>  {
> -	struct nouveau_drm *drm = pci_get_drvdata(pdev);
> +	struct nouveau_drm *drm = (struct nouveau_drm *)data;
>  	struct nvif_object *device = &drm->client.device.object;
>  
>  	if (drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE &&
> @@ -103,7 +103,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
>  		return;
>  	pdev = to_pci_dev(dev->dev);
>  
> -	vga_client_register(pdev, nouveau_vga_set_decode);
> +	vga_client_register(pdev, nouveau_vga_set_decode, drm);
>  
>  	/* don't register Thunderbolt eGPU with vga_switcheroo */
>  	if (pci_is_thunderbolt_attached(pdev))
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
> index 9523240110a6..cf8a6bd00c77 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -1076,10 +1076,9 @@ void radeon_combios_fini(struct radeon_device *rdev)
>   * Enable/disable vga decode (all asics).
>   * Returns VGA resource flags.
>   */
> -static unsigned int radeon_vga_set_decode(struct pci_dev *pdev, bool state)
> +static unsigned int radeon_vga_set_decode(void *data, bool state)
>  {
> -	struct drm_device *dev = pci_get_drvdata(pdev);
> -	struct radeon_device *rdev = dev->dev_private;
> +	struct radeon_device *rdev = (struct radeon_device *)data;
>  	radeon_vga_set_state(rdev, state);
>  	if (state)
>  		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
> @@ -1431,7 +1430,7 @@ int radeon_device_init(struct radeon_device *rdev,
>  	/* if we have > 1 VGA cards, then disable the radeon VGA resources */
>  	/* this will fail for cards that aren't VGA class devices, just
>  	 * ignore it */
> -	vga_client_register(rdev->pdev, radeon_vga_set_decode);
> +	vga_client_register(rdev->pdev, radeon_vga_set_decode, rdev);
>  
>  	if (rdev->flags & RADEON_IS_PX)
>  		runtime = true;
> diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
> index 3de05aee7859..3e58b2c05c85 100644
> --- a/drivers/pci/vgaarb.c
> +++ b/drivers/pci/vgaarb.c
> @@ -51,7 +51,8 @@ struct vga_device {
>  	unsigned int mem_norm_cnt;	/* normal MEM count */
>  	bool bridge_has_one_vga;
>  	bool is_firmware_default;	/* device selected by firmware */
> -	unsigned int (*set_decode)(struct pci_dev *pdev, bool decode);
> +	unsigned int (*set_decode)(void *data, bool decode);
> +	void *set_decode_data;
>  };
>  
>  static LIST_HEAD(vga_list);
> @@ -935,6 +936,7 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
>   * vga_client_register - register or unregister a VGA arbitration client
>   * @pdev: PCI device of the VGA client
>   * @set_decode: VGA decode change callback
> + * @data: private data to pass to callback
>   *
>   * Clients have two callback mechanisms they can use.
>   *
> @@ -956,15 +958,18 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
>   * Returns: 0 on success, -ENODEV on failure
>   */
>  int vga_client_register(struct pci_dev *pdev,
> -		unsigned int (*set_decode)(struct pci_dev *pdev, bool decode))
> +		unsigned int (*set_decode)(void *data, bool decode),
> +		void *data)
>  {
>  	unsigned long flags;
>  	struct vga_device *vgadev;
>  
>  	spin_lock_irqsave(&vga_lock, flags);
>  	vgadev = vgadev_find(pdev);
> -	if (vgadev)
> +	if (vgadev) {
>  		vgadev->set_decode = set_decode;
> +		vgadev->set_decode_data = data;
> +	}
>  	spin_unlock_irqrestore(&vga_lock, flags);
>  	if (!vgadev)
>  		return -ENODEV;
> @@ -1464,7 +1469,7 @@ static void vga_arbiter_notify_clients(void)
>  	spin_lock_irqsave(&vga_lock, flags);
>  	list_for_each_entry(vgadev, &vga_list, list) {
>  		if (vgadev->set_decode) {
> -			new_decodes = vgadev->set_decode(vgadev->pdev,
> +			new_decodes = vgadev->set_decode(vgadev->set_decode_data,
>  							 new_state);
>  			vga_update_device_decodes(vgadev, new_decodes);
>  		}
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 6757054e9d87..b04ce3ded08c 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -162,9 +162,10 @@ static inline void vfio_pci_core_debugfs_init(struct vfio_pci_core_device *vdev)
>   * has no way to get to it and routing can be disabled externally at the
>   * bridge.
>   */
> -static unsigned int vfio_pci_set_decode(struct pci_dev *pdev, bool single_vga)
> +static unsigned int vfio_pci_set_decode(void *data, bool single_vga)
>  {
> -	struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev);
> +	struct vfio_pci_core_device *vdev = data;
> +	struct pci_dev *pdev = vdev->pdev;
>  	struct pci_dev *tmp = NULL;
>  	unsigned char max_busnr;
>  	unsigned int decodes;
> @@ -2159,10 +2160,10 @@ static int vfio_pci_vga_init(struct vfio_pci_core_device *vdev)
>  	if (ret)
>  		return ret;
>  
> -	ret = vga_client_register(pdev, vfio_pci_set_decode);
> +	ret = vga_client_register(pdev, vfio_pci_set_decode, vdev);
>  	if (ret)
>  		return ret;
> -	vga_set_legacy_decoding(pdev, vfio_pci_set_decode(pdev, false));
> +	vga_set_legacy_decoding(pdev, vfio_pci_set_decode(vdev, false));
>  	return 0;
>  }
>  
> diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
> index 97129a1bbb7d..71a364669eaf 100644
> --- a/include/linux/vgaarb.h
> +++ b/include/linux/vgaarb.h
> @@ -33,7 +33,8 @@ struct pci_dev *vga_default_device(void);
>  void vga_set_default_device(struct pci_dev *pdev);
>  int vga_remove_vgacon(struct pci_dev *pdev);
>  int vga_client_register(struct pci_dev *pdev,
> -		unsigned int (*set_decode)(struct pci_dev *pdev, bool state));
> +		unsigned int (*set_decode)(void *data, bool state),
> +		void *data);
>  #else /* CONFIG_VGA_ARB */
>  static inline void vga_set_legacy_decoding(struct pci_dev *pdev,
>  		unsigned int decodes)
> @@ -59,7 +60,8 @@ static inline int vga_remove_vgacon(struct pci_dev *pdev)
>  	return 0;
>  }
>  static inline int vga_client_register(struct pci_dev *pdev,
> -		unsigned int (*set_decode)(struct pci_dev *pdev, bool state))
> +		unsigned int (*set_decode)(void *data, bool state),
> +		void *data)
>  {
>  	return 0;
>  }
> @@ -97,7 +99,7 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev,
>  
>  static inline void vga_client_unregister(struct pci_dev *pdev)
>  {
> -	vga_client_register(pdev, NULL);
> +	vga_client_register(pdev, NULL, NULL);
>  }
>  
>  #endif /* LINUX_VGA_H */
> -- 
> 2.54.0
> 

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

* Re: [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2)
  2026-09-28 20:00 ` Alex Williamson
@ 2026-10-01  1:08   ` David Airlie
  0 siblings, 0 replies; 8+ messages in thread
From: David Airlie @ 2026-10-01  1:08 UTC (permalink / raw)
  To: Alex Williamson
  Cc: Dave Airlie, dri-devel, linux-pci, kvm, Jason Gunthorpe,
	Bjorn Helgaas, Rodrigo Vivi, Alex Deucher, Simon Song (SW-GPU)

On Tue, Sep 29, 2026 at 6:06 AM Alex Williamson <alex@shazbot.org> wrote:
>
> On Tue, 22 Sep 2026 17:18:07 +1000
> Dave Airlie <airlied@gmail.com> wrote:
>
> > From: Dave Airlie <airlied@redhat.com>
> >
> > This changes the vgaarb client API so that the user can pass a
> > private data pointer into the register that will get used in
> > the decode callback.
> >
> > This allows a bunch of pdev conversions in the drivers, and lets
> > some future vfio cleanups be nicer.
> >
> > I'd like to merge this via the drm next tree but also fine with
> > it going via pci.
> >
> > Signed-off-by: Dave Airlie <airlied@redhat.com>
> > Cc: Alex Williamson <alex@shazbot.org>
> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Cc: Alex Deucher <alexander.deucher@amd.com>
> > ---
> > v2: fix loongson (spotted by sashiko)
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  6 +++---
> >  drivers/gpu/drm/i915/display/intel_vga.c   |  7 ++++---
> >  drivers/gpu/drm/loongson/lsdc_drv.c        |  4 ++--
> >  drivers/gpu/drm/nouveau/nouveau_vga.c      |  6 +++---
> >  drivers/gpu/drm/radeon/radeon_device.c     |  7 +++----
> >  drivers/pci/vgaarb.c                       | 13 +++++++++----
> >  drivers/vfio/pci/vfio_pci_core.c           |  9 +++++----
> >  include/linux/vgaarb.h                     |  8 +++++---
> >  8 files changed, 34 insertions(+), 26 deletions(-)
>
>
> Acked-by: Alex Williamson <alex@shazbot.org>
>
> Preemptively, could this get merged via a topic branch that we could
> share in case further drvdata cleanup arrives in vfio-pci this cycle?
>
> I'm imagining this might also be a good time to push vgaarb
> registration out of vfio-pci-core as well.  Thanks,
>

Thanks Alex and Bjorn,

Okay I've cleaned up the last few bits from Bjorn, added lines and
created a drm topic branch

https://gitlab.freedesktop.org/drm/kernel topic/pci-vgaarb-rework

I'll send a PR merge this into drm-next and you can work off it as
well if you need to.

Dave.


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

end of thread, other threads:[~2026-10-01  1:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-22  7:18 [PATCH] pci/vgaarb: pass a data pointer to be used in the decode callback (v2) Dave Airlie
2026-09-22  7:25 ` sashiko-bot
2026-09-22  8:44 ` Jani Nikula
2026-09-22 15:05 ` Alex Deucher
2026-09-28 19:33 ` Dave Airlie
2026-09-28 20:00 ` Alex Williamson
2026-10-01  1:08   ` David Airlie
2026-09-28 20:14 ` Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox