Message ID | 20230120031522.2304439-5-david.e.box@linux.intel.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Lorenzo Pieralisi |
Headers | show |
Series | Enable PCIe ASPM and LTR on select hardware | expand |
On Thu, Jan 19, 2023 at 07:15:22PM -0800, David E. Box wrote: > +/* > + * Enable ASPM and LTR settings on devices that aren't configured by BIOS. > + */ > +static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata) > +{ > + unsigned long features = *(unsigned long *)userdata; > + u16 ltr = VMD_BIOS_PM_QUIRK_LTR; > + u32 ltr_reg; > + int pos; > + > + if (!(features & VMD_FEAT_BIOS_PM_QUIRK)) > + return 0; > + > + pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL); Hi, This is tripping lockdep on one our CI ADL machines. https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12814/bat-adlp-6/boot0.txt <4>[ 13.815380] ============================================ <4>[ 13.815382] WARNING: possible recursive locking detected <4>[ 13.815384] 6.3.0-rc1-CI_DRM_12814-g4753bbc2a817+ #1 Not tainted <4>[ 13.815386] -------------------------------------------- <4>[ 13.815387] swapper/0/1 is trying to acquire lock: <4>[ 13.815389] ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: pci_enable_link_state+0x69/0x1d0 <4>[ 13.815396] but task is already holding lock: <4>[ 13.815398] ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: pci_walk_bus+0x24/0x90 <4>[ 13.815403] other info that might help us debug this: <4>[ 13.815404] Possible unsafe locking scenario: <4>[ 13.815406] CPU0 <4>[ 13.815407] ---- <4>[ 13.815408] lock(pci_bus_sem); <4>[ 13.815410] lock(pci_bus_sem); <4>[ 13.815411] *** DEADLOCK *** <4>[ 13.815413] May be due to missing lock nesting notation <4>[ 13.815414] 2 locks held by swapper/0/1: <4>[ 13.815416] #0: ffff8881029511b8 (&dev->mutex){....}-{3:3}, at: __driver_attach+0xab/0x180 <4>[ 13.815422] #1: ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: pci_walk_bus+0x24/0x90 <4>[ 13.815426] stack backtrace: <4>[ 13.815428] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.3.0-rc1-CI_DRM_12814-g4753bbc2a817+ #1 <4>[ 13.815431] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS ADLPFWI1.R00.3135.A00.2203251419 03/25/2022 <4>[ 13.815434] Call Trace: <4>[ 13.815436] <TASK> <4>[ 13.815437] dump_stack_lvl+0x64/0xb0 <4>[ 13.815443] __lock_acquire+0x9b5/0x2550 <4>[ 13.815461] lock_acquire+0xd7/0x330 <4>[ 13.815463] ? pci_enable_link_state+0x69/0x1d0 <4>[ 13.815466] down_read+0x3d/0x180 <4>[ 13.815480] ? pci_enable_link_state+0x69/0x1d0 <4>[ 13.815482] pci_enable_link_state+0x69/0x1d0 <4>[ 13.815485] ? __pfx_vmd_pm_enable_quirk+0x10/0x10 <4>[ 13.815488] vmd_pm_enable_quirk+0x49/0xb0 <4>[ 13.815490] pci_walk_bus+0x6d/0x90 <4>[ 13.815492] vmd_probe+0x75f/0x9d0 <4>[ 13.815495] pci_device_probe+0x95/0x120 <4>[ 13.815498] really_probe+0x164/0x3c0 <4>[ 13.815500] ? __pfx___driver_attach+0x10/0x10 <4>[ 13.815503] __driver_probe_device+0x73/0x170 <4>[ 13.815506] driver_probe_device+0x19/0xa0 <4>[ 13.815508] __driver_attach+0xb6/0x180 <4>[ 13.815511] ? __pfx___driver_attach+0x10/0x10 <4>[ 13.815513] bus_for_each_dev+0x77/0xd0 <4>[ 13.815516] bus_add_driver+0x114/0x210 <4>[ 13.815518] driver_register+0x5b/0x110 <4>[ 13.815520] ? __pfx_vmd_drv_init+0x10/0x10 <4>[ 13.815523] do_one_initcall+0x57/0x330 <4>[ 13.815527] kernel_init_freeable+0x181/0x3a0 <4>[ 13.815529] ? __pfx_kernel_init+0x10/0x10 <4>[ 13.815532] kernel_init+0x15/0x120 <4>[ 13.815534] ret_from_fork+0x29/0x50 <4>[ 13.815537] </TASK>
Hi, On Tue, 2023-03-21 at 00:56 +0200, Ville Syrjälä wrote: > On Thu, Jan 19, 2023 at 07:15:22PM -0800, David E. Box wrote: > > +/* > > + * Enable ASPM and LTR settings on devices that aren't configured by BIOS. > > + */ > > +static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata) > > +{ > > + unsigned long features = *(unsigned long *)userdata; > > + u16 ltr = VMD_BIOS_PM_QUIRK_LTR; > > + u32 ltr_reg; > > + int pos; > > + > > + if (!(features & VMD_FEAT_BIOS_PM_QUIRK)) > > + return 0; > > + > > + pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL); We call pci_enable_link_state from a callback that's run during pci_walk_bus() which I see already acquires the semaphore. We've had this patch for well over a year and I haven't seen this issue before. Is there a particular config needed to reproduce it? As far as a solution I think we can copy what __pci_disable_link_state() does and add a bool argument so that we only do down/up on the semaphore when set to true. Since we know we will in be the lock during the bus walk we can set it to false. David > > Hi, > > This is tripping lockdep on one our CI ADL machines. > > https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12814/bat-adlp-6/boot0.txt > > <4>[ 13.815380] ============================================ > <4>[ 13.815382] WARNING: possible recursive locking detected > <4>[ 13.815384] 6.3.0-rc1-CI_DRM_12814-g4753bbc2a817+ #1 Not tainted > <4>[ 13.815386] -------------------------------------------- > <4>[ 13.815387] swapper/0/1 is trying to acquire lock: > <4>[ 13.815389] ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: > pci_enable_link_state+0x69/0x1d0 > <4>[ 13.815396] > but task is already holding lock: > <4>[ 13.815398] ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: > pci_walk_bus+0x24/0x90 > <4>[ 13.815403] > other info that might help us debug this: > <4>[ 13.815404] Possible unsafe locking scenario: > > <4>[ 13.815406] CPU0 > <4>[ 13.815407] ---- > <4>[ 13.815408] lock(pci_bus_sem); > <4>[ 13.815410] lock(pci_bus_sem); > <4>[ 13.815411] > *** DEADLOCK *** > > <4>[ 13.815413] May be due to missing lock nesting notation > > <4>[ 13.815414] 2 locks held by swapper/0/1: > <4>[ 13.815416] #0: ffff8881029511b8 (&dev->mutex){....}-{3:3}, at: > __driver_attach+0xab/0x180 > <4>[ 13.815422] #1: ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: > pci_walk_bus+0x24/0x90 > <4>[ 13.815426] > stack backtrace: > <4>[ 13.815428] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.3.0-rc1- > CI_DRM_12814-g4753bbc2a817+ #1 > <4>[ 13.815431] Hardware name: Intel Corporation Alder Lake Client > Platform/AlderLake-P DDR4 RVP, BIOS ADLPFWI1.R00.3135.A00.2203251419 > 03/25/2022 > <4>[ 13.815434] Call Trace: > <4>[ 13.815436] <TASK> > <4>[ 13.815437] dump_stack_lvl+0x64/0xb0 > <4>[ 13.815443] __lock_acquire+0x9b5/0x2550 > <4>[ 13.815461] lock_acquire+0xd7/0x330 > <4>[ 13.815463] ? pci_enable_link_state+0x69/0x1d0 > <4>[ 13.815466] down_read+0x3d/0x180 > <4>[ 13.815480] ? pci_enable_link_state+0x69/0x1d0 > <4>[ 13.815482] pci_enable_link_state+0x69/0x1d0 > <4>[ 13.815485] ? __pfx_vmd_pm_enable_quirk+0x10/0x10 > <4>[ 13.815488] vmd_pm_enable_quirk+0x49/0xb0 > <4>[ 13.815490] pci_walk_bus+0x6d/0x90 > <4>[ 13.815492] vmd_probe+0x75f/0x9d0 > <4>[ 13.815495] pci_device_probe+0x95/0x120 > <4>[ 13.815498] really_probe+0x164/0x3c0 > <4>[ 13.815500] ? __pfx___driver_attach+0x10/0x10 > <4>[ 13.815503] __driver_probe_device+0x73/0x170 > <4>[ 13.815506] driver_probe_device+0x19/0xa0 > <4>[ 13.815508] __driver_attach+0xb6/0x180 > <4>[ 13.815511] ? __pfx___driver_attach+0x10/0x10 > <4>[ 13.815513] bus_for_each_dev+0x77/0xd0 > <4>[ 13.815516] bus_add_driver+0x114/0x210 > <4>[ 13.815518] driver_register+0x5b/0x110 > <4>[ 13.815520] ? __pfx_vmd_drv_init+0x10/0x10 > <4>[ 13.815523] do_one_initcall+0x57/0x330 > <4>[ 13.815527] kernel_init_freeable+0x181/0x3a0 > <4>[ 13.815529] ? __pfx_kernel_init+0x10/0x10 > <4>[ 13.815532] kernel_init+0x15/0x120 > <4>[ 13.815534] ret_from_fork+0x29/0x50 > <4>[ 13.815537] </TASK> >
On Mon, Mar 20, 2023 at 07:24:16PM -0700, David E. Box wrote: > Hi, > > On Tue, 2023-03-21 at 00:56 +0200, Ville Syrjälä wrote: > > On Thu, Jan 19, 2023 at 07:15:22PM -0800, David E. Box wrote: > > > +/* > > > + * Enable ASPM and LTR settings on devices that aren't configured by BIOS. > > > + */ > > > +static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata) > > > +{ > > > + unsigned long features = *(unsigned long *)userdata; > > > + u16 ltr = VMD_BIOS_PM_QUIRK_LTR; > > > + u32 ltr_reg; > > > + int pos; > > > + > > > + if (!(features & VMD_FEAT_BIOS_PM_QUIRK)) > > > + return 0; > > > + > > > + pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL); > > We call pci_enable_link_state from a callback that's run during pci_walk_bus() > which I see already acquires the semaphore. We've had this patch for well over a > year and I haven't seen this issue before. Is there a particular config needed > to reproduce it? Not sure what would affect it, beyond the normal PROVE_LOCKING=y. This is the .config our CI uses: https://gitlab.freedesktop.org/gfx-ci/i915-infra/-/blob/master/kconfig/debug > > As far as a solution I think we can copy what __pci_disable_link_state() does > and add a bool argument so that we only do down/up on the semaphore when set to > true. Since we know we will in be the lock during the bus walk we can set it to > false. > > David > > > > > Hi, > > > > This is tripping lockdep on one our CI ADL machines. > > > > https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12814/bat-adlp-6/boot0.txt > > > > <4>[ 13.815380] ============================================ > > <4>[ 13.815382] WARNING: possible recursive locking detected > > <4>[ 13.815384] 6.3.0-rc1-CI_DRM_12814-g4753bbc2a817+ #1 Not tainted > > <4>[ 13.815386] -------------------------------------------- > > <4>[ 13.815387] swapper/0/1 is trying to acquire lock: > > <4>[ 13.815389] ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: > > pci_enable_link_state+0x69/0x1d0 > > <4>[ 13.815396] > > but task is already holding lock: > > <4>[ 13.815398] ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: > > pci_walk_bus+0x24/0x90 > > <4>[ 13.815403] > > other info that might help us debug this: > > <4>[ 13.815404] Possible unsafe locking scenario: > > > > <4>[ 13.815406] CPU0 > > <4>[ 13.815407] ---- > > <4>[ 13.815408] lock(pci_bus_sem); > > <4>[ 13.815410] lock(pci_bus_sem); > > <4>[ 13.815411] > > *** DEADLOCK *** > > > > <4>[ 13.815413] May be due to missing lock nesting notation > > > > <4>[ 13.815414] 2 locks held by swapper/0/1: > > <4>[ 13.815416] #0: ffff8881029511b8 (&dev->mutex){....}-{3:3}, at: > > __driver_attach+0xab/0x180 > > <4>[ 13.815422] #1: ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: > > pci_walk_bus+0x24/0x90 > > <4>[ 13.815426] > > stack backtrace: > > <4>[ 13.815428] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.3.0-rc1- > > CI_DRM_12814-g4753bbc2a817+ #1 > > <4>[ 13.815431] Hardware name: Intel Corporation Alder Lake Client > > Platform/AlderLake-P DDR4 RVP, BIOS ADLPFWI1.R00.3135.A00.2203251419 > > 03/25/2022 > > <4>[ 13.815434] Call Trace: > > <4>[ 13.815436] <TASK> > > <4>[ 13.815437] dump_stack_lvl+0x64/0xb0 > > <4>[ 13.815443] __lock_acquire+0x9b5/0x2550 > > <4>[ 13.815461] lock_acquire+0xd7/0x330 > > <4>[ 13.815463] ? pci_enable_link_state+0x69/0x1d0 > > <4>[ 13.815466] down_read+0x3d/0x180 > > <4>[ 13.815480] ? pci_enable_link_state+0x69/0x1d0 > > <4>[ 13.815482] pci_enable_link_state+0x69/0x1d0 > > <4>[ 13.815485] ? __pfx_vmd_pm_enable_quirk+0x10/0x10 > > <4>[ 13.815488] vmd_pm_enable_quirk+0x49/0xb0 > > <4>[ 13.815490] pci_walk_bus+0x6d/0x90 > > <4>[ 13.815492] vmd_probe+0x75f/0x9d0 > > <4>[ 13.815495] pci_device_probe+0x95/0x120 > > <4>[ 13.815498] really_probe+0x164/0x3c0 > > <4>[ 13.815500] ? __pfx___driver_attach+0x10/0x10 > > <4>[ 13.815503] __driver_probe_device+0x73/0x170 > > <4>[ 13.815506] driver_probe_device+0x19/0xa0 > > <4>[ 13.815508] __driver_attach+0xb6/0x180 > > <4>[ 13.815511] ? __pfx___driver_attach+0x10/0x10 > > <4>[ 13.815513] bus_for_each_dev+0x77/0xd0 > > <4>[ 13.815516] bus_add_driver+0x114/0x210 > > <4>[ 13.815518] driver_register+0x5b/0x110 > > <4>[ 13.815520] ? __pfx_vmd_drv_init+0x10/0x10 > > <4>[ 13.815523] do_one_initcall+0x57/0x330 > > <4>[ 13.815527] kernel_init_freeable+0x181/0x3a0 > > <4>[ 13.815529] ? __pfx_kernel_init+0x10/0x10 > > <4>[ 13.815532] kernel_init+0x15/0x120 > > <4>[ 13.815534] ret_from_fork+0x29/0x50 > > <4>[ 13.815537] </TASK> > >
On Tue, 2023-03-21 at 14:38 +0200, Ville Syrjälä wrote: > On Mon, Mar 20, 2023 at 07:24:16PM -0700, David E. Box wrote: > > Hi, > > > > On Tue, 2023-03-21 at 00:56 +0200, Ville Syrjälä wrote: > > > On Thu, Jan 19, 2023 at 07:15:22PM -0800, David E. Box wrote: > > > > +/* > > > > + * Enable ASPM and LTR settings on devices that aren't configured by > > > > BIOS. > > > > + */ > > > > +static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata) > > > > +{ > > > > + unsigned long features = *(unsigned long *)userdata; > > > > + u16 ltr = VMD_BIOS_PM_QUIRK_LTR; > > > > + u32 ltr_reg; > > > > + int pos; > > > > + > > > > + if (!(features & VMD_FEAT_BIOS_PM_QUIRK)) > > > > + return 0; > > > > + > > > > + pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL); > > > > We call pci_enable_link_state from a callback that's run during > > pci_walk_bus() > > which I see already acquires the semaphore. We've had this patch for well > > over a > > year and I haven't seen this issue before. Is there a particular config > > needed > > to reproduce it? > > Not sure what would affect it, beyond the normal PROVE_LOCKING=y. Thanks. Did not have this set. I reproduced the issue and have sent a fix. David > > This is the .config our CI uses: > https://gitlab.freedesktop.org/gfx-ci/i915-infra/-/blob/master/kconfig/debug > > > > > As far as a solution I think we can copy what __pci_disable_link_state() > > does > > and add a bool argument so that we only do down/up on the semaphore when set > > to > > true. Since we know we will in be the lock during the bus walk we can set it > > to > > false. > > > > David > > > > > > > > Hi, > > > > > > This is tripping lockdep on one our CI ADL machines. > > > > > > https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12814/bat-adlp-6/boot0.txt > > > > > > <4>[ 13.815380] ============================================ > > > <4>[ 13.815382] WARNING: possible recursive locking detected > > > <4>[ 13.815384] 6.3.0-rc1-CI_DRM_12814-g4753bbc2a817+ #1 Not tainted > > > <4>[ 13.815386] -------------------------------------------- > > > <4>[ 13.815387] swapper/0/1 is trying to acquire lock: > > > <4>[ 13.815389] ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: > > > pci_enable_link_state+0x69/0x1d0 > > > <4>[ 13.815396] > > > but task is already holding lock: > > > <4>[ 13.815398] ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: > > > pci_walk_bus+0x24/0x90 > > > <4>[ 13.815403] > > > other info that might help us debug this: > > > <4>[ 13.815404] Possible unsafe locking scenario: > > > > > > <4>[ 13.815406] CPU0 > > > <4>[ 13.815407] ---- > > > <4>[ 13.815408] lock(pci_bus_sem); > > > <4>[ 13.815410] lock(pci_bus_sem); > > > <4>[ 13.815411] > > > *** DEADLOCK *** > > > > > > <4>[ 13.815413] May be due to missing lock nesting notation > > > > > > <4>[ 13.815414] 2 locks held by swapper/0/1: > > > <4>[ 13.815416] #0: ffff8881029511b8 (&dev->mutex){....}-{3:3}, at: > > > __driver_attach+0xab/0x180 > > > <4>[ 13.815422] #1: ffffffff827ab0b0 (pci_bus_sem){++++}-{3:3}, at: > > > pci_walk_bus+0x24/0x90 > > > <4>[ 13.815426] > > > stack backtrace: > > > <4>[ 13.815428] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.3.0-rc1- > > > CI_DRM_12814-g4753bbc2a817+ #1 > > > <4>[ 13.815431] Hardware name: Intel Corporation Alder Lake Client > > > Platform/AlderLake-P DDR4 RVP, BIOS ADLPFWI1.R00.3135.A00.2203251419 > > > 03/25/2022 > > > <4>[ 13.815434] Call Trace: > > > <4>[ 13.815436] <TASK> > > > <4>[ 13.815437] dump_stack_lvl+0x64/0xb0 > > > <4>[ 13.815443] __lock_acquire+0x9b5/0x2550 > > > <4>[ 13.815461] lock_acquire+0xd7/0x330 > > > <4>[ 13.815463] ? pci_enable_link_state+0x69/0x1d0 > > > <4>[ 13.815466] down_read+0x3d/0x180 > > > <4>[ 13.815480] ? pci_enable_link_state+0x69/0x1d0 > > > <4>[ 13.815482] pci_enable_link_state+0x69/0x1d0 > > > <4>[ 13.815485] ? __pfx_vmd_pm_enable_quirk+0x10/0x10 > > > <4>[ 13.815488] vmd_pm_enable_quirk+0x49/0xb0 > > > <4>[ 13.815490] pci_walk_bus+0x6d/0x90 > > > <4>[ 13.815492] vmd_probe+0x75f/0x9d0 > > > <4>[ 13.815495] pci_device_probe+0x95/0x120 > > > <4>[ 13.815498] really_probe+0x164/0x3c0 > > > <4>[ 13.815500] ? __pfx___driver_attach+0x10/0x10 > > > <4>[ 13.815503] __driver_probe_device+0x73/0x170 > > > <4>[ 13.815506] driver_probe_device+0x19/0xa0 > > > <4>[ 13.815508] __driver_attach+0xb6/0x180 > > > <4>[ 13.815511] ? __pfx___driver_attach+0x10/0x10 > > > <4>[ 13.815513] bus_for_each_dev+0x77/0xd0 > > > <4>[ 13.815516] bus_add_driver+0x114/0x210 > > > <4>[ 13.815518] driver_register+0x5b/0x110 > > > <4>[ 13.815520] ? __pfx_vmd_drv_init+0x10/0x10 > > > <4>[ 13.815523] do_one_initcall+0x57/0x330 > > > <4>[ 13.815527] kernel_init_freeable+0x181/0x3a0 > > > <4>[ 13.815529] ? __pfx_kernel_init+0x10/0x10 > > > <4>[ 13.815532] kernel_init+0x15/0x120 > > > <4>[ 13.815534] ret_from_fork+0x29/0x50 > > > <4>[ 13.815537] </TASK> > > > >
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index 47fa3e5f2dc5..990630ec57c6 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -66,11 +66,22 @@ enum vmd_features { * interrupt handling. */ VMD_FEAT_CAN_BYPASS_MSI_REMAP = (1 << 4), + + /* + * Enable ASPM on the PCIE root ports and set the default LTR of the + * storage devices on platforms where these values are not configured by + * BIOS. This is needed for laptops, which require these settings for + * proper power management of the SoC. + */ + VMD_FEAT_BIOS_PM_QUIRK = (1 << 5), }; +#define VMD_BIOS_PM_QUIRK_LTR 0x1003 /* 3145728 ns */ + #define VMD_FEATS_CLIENT (VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | \ VMD_FEAT_HAS_BUS_RESTRICTIONS | \ - VMD_FEAT_OFFSET_FIRST_VECTOR) + VMD_FEAT_OFFSET_FIRST_VECTOR | \ + VMD_FEAT_BIOS_PM_QUIRK) static DEFINE_IDA(vmd_instance_ida); @@ -713,6 +724,46 @@ static void vmd_copy_host_bridge_flags(struct pci_host_bridge *root_bridge, vmd_bridge->native_dpc = root_bridge->native_dpc; } +/* + * Enable ASPM and LTR settings on devices that aren't configured by BIOS. + */ +static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata) +{ + unsigned long features = *(unsigned long *)userdata; + u16 ltr = VMD_BIOS_PM_QUIRK_LTR; + u32 ltr_reg; + int pos; + + if (!(features & VMD_FEAT_BIOS_PM_QUIRK)) + return 0; + + pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL); + + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_LTR); + if (!pos) + return 0; + + /* + * Skip if the max snoop LTR is non-zero, indicating BIOS has set it + * so the LTR quirk is not needed. + */ + pci_read_config_dword(pdev, pos + PCI_LTR_MAX_SNOOP_LAT, <r_reg); + if (!!(ltr_reg & (PCI_LTR_VALUE_MASK | PCI_LTR_SCALE_MASK))) + return 0; + + /* + * Set the default values to the maximum required by the platform to + * allow the deepest power management savings. Write as a DWORD where + * the lower word is the max snoop latency and the upper word is the + * max non-snoop latency. + */ + ltr_reg = (ltr << 16) | ltr; + pci_write_config_dword(pdev, pos + PCI_LTR_MAX_SNOOP_LAT, ltr_reg); + pci_info(pdev, "VMD: Default LTR value set by driver\n"); + + return 0; +} + static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) { struct pci_sysdata *sd = &vmd->sysdata; @@ -885,6 +936,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) pci_assign_unassigned_bus_resources(vmd->bus); + pci_walk_bus(vmd->bus, vmd_pm_enable_quirk, &features); + /* * VMD root buses are virtual and don't return true on pci_is_pcie() * and will fail pcie_bus_configure_settings() early. It can instead be