Skip to content

Commit 2e3f280

Browse files
committed
Merge tag 'pci-v6.7-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
Pull pci fixes from Bjorn Helgaas: - Limit Max_Read_Request_Size (MRRS) on some MIPS Loongson systems because they don't all support MRRS > 256, and firmware doesn't always initialize it correctly, which meant some PCIe devices didn't work (Jiaxun Yang) - Add and use pci_enable_link_state_locked() to prevent potential deadlocks in vmd and qcom drivers (Johan Hovold) - Revert recent (v6.5) acpiphp resource assignment changes that fixed issues with hot-adding devices on a root bus or with large BARs, but introduced new issues with GPU initialization and hot-adding SCSI disks in QEMU VMs and (Bjorn Helgaas) * tag 'pci-v6.7-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: Revert "PCI: acpiphp: Reassign resources on bridge if necessary" PCI/ASPM: Add pci_disable_link_state_locked() lockdep assert PCI/ASPM: Clean up __pci_disable_link_state() 'sem' parameter PCI: qcom: Clean up ASPM comment PCI: qcom: Fix potential deadlock when enabling ASPM PCI: vmd: Fix potential deadlock when enabling ASPM PCI/ASPM: Add pci_enable_link_state_locked() PCI: loongson: Limit MRRS to 256
2 parents ae19141 + 5df1274 commit 2e3f280

6 files changed

Lines changed: 100 additions & 32 deletions

File tree

drivers/pci/controller/dwc/pcie-qcom.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -968,9 +968,12 @@ static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie)
968968

969969
static int qcom_pcie_enable_aspm(struct pci_dev *pdev, void *userdata)
970970
{
971-
/* Downstream devices need to be in D0 state before enabling PCI PM substates */
971+
/*
972+
* Downstream devices need to be in D0 state before enabling PCI PM
973+
* substates.
974+
*/
972975
pci_set_power_state(pdev, PCI_D0);
973-
pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL);
976+
pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL);
974977

975978
return 0;
976979
}

drivers/pci/controller/pci-loongson.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,49 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
8080
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
8181
DEV_LS7A_LPC, system_bus_quirk);
8282

83+
/*
84+
* Some Loongson PCIe ports have hardware limitations on their Maximum Read
85+
* Request Size. They can't handle anything larger than this. Sane
86+
* firmware will set proper MRRS at boot, so we only need no_inc_mrrs for
87+
* bridges. However, some MIPS Loongson firmware doesn't set MRRS properly,
88+
* so we have to enforce maximum safe MRRS, which is 256 bytes.
89+
*/
90+
#ifdef CONFIG_MIPS
91+
static void loongson_set_min_mrrs_quirk(struct pci_dev *pdev)
92+
{
93+
struct pci_bus *bus = pdev->bus;
94+
struct pci_dev *bridge;
95+
static const struct pci_device_id bridge_devids[] = {
96+
{ PCI_VDEVICE(LOONGSON, DEV_LS2K_PCIE_PORT0) },
97+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT0) },
98+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT1) },
99+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT2) },
100+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT3) },
101+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT4) },
102+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT5) },
103+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT6) },
104+
{ 0, },
105+
};
106+
107+
/* look for the matching bridge */
108+
while (!pci_is_root_bus(bus)) {
109+
bridge = bus->self;
110+
bus = bus->parent;
111+
112+
if (pci_match_id(bridge_devids, bridge)) {
113+
if (pcie_get_readrq(pdev) > 256) {
114+
pci_info(pdev, "limiting MRRS to 256\n");
115+
pcie_set_readrq(pdev, 256);
116+
}
117+
break;
118+
}
119+
}
120+
}
121+
DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, loongson_set_min_mrrs_quirk);
122+
#endif
123+
83124
static void loongson_mrrs_quirk(struct pci_dev *pdev)
84125
{
85-
/*
86-
* Some Loongson PCIe ports have h/w limitations of maximum read
87-
* request size. They can't handle anything larger than this. So
88-
* force this limit on any devices attached under these ports.
89-
*/
90126
struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);
91127

92128
bridge->no_inc_mrrs = 1;

drivers/pci/controller/vmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata)
751751
if (!(features & VMD_FEAT_BIOS_PM_QUIRK))
752752
return 0;
753753

754-
pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL);
754+
pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL);
755755

756756
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_LTR);
757757
if (!pos)

drivers/pci/hotplug/acpiphp_glue.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -512,15 +512,12 @@ static void enable_slot(struct acpiphp_slot *slot, bool bridge)
512512
if (pass && dev->subordinate) {
513513
check_hotplug_bridge(slot, dev);
514514
pcibios_resource_survey_bus(dev->subordinate);
515-
if (pci_is_root_bus(bus))
516-
__pci_bus_size_bridges(dev->subordinate, &add_list);
515+
__pci_bus_size_bridges(dev->subordinate,
516+
&add_list);
517517
}
518518
}
519519
}
520-
if (pci_is_root_bus(bus))
521-
__pci_bus_assign_resources(bus, &add_list, NULL);
522-
else
523-
pci_assign_unassigned_bridge_resources(bus->self);
520+
__pci_bus_assign_resources(bus, &add_list, NULL);
524521
}
525522

526523
acpiphp_sanitize_bus(bus);

drivers/pci/pcie/aspm.c

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ static struct pcie_link_state *pcie_aspm_get_link(struct pci_dev *pdev)
10411041
return bridge->link_state;
10421042
}
10431043

1044-
static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
1044+
static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool locked)
10451045
{
10461046
struct pcie_link_state *link = pcie_aspm_get_link(pdev);
10471047

@@ -1060,7 +1060,7 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
10601060
return -EPERM;
10611061
}
10621062

1063-
if (sem)
1063+
if (!locked)
10641064
down_read(&pci_bus_sem);
10651065
mutex_lock(&aspm_lock);
10661066
if (state & PCIE_LINK_STATE_L0S)
@@ -1082,15 +1082,17 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
10821082
link->clkpm_disable = 1;
10831083
pcie_set_clkpm(link, policy_to_clkpm_state(link));
10841084
mutex_unlock(&aspm_lock);
1085-
if (sem)
1085+
if (!locked)
10861086
up_read(&pci_bus_sem);
10871087

10881088
return 0;
10891089
}
10901090

10911091
int pci_disable_link_state_locked(struct pci_dev *pdev, int state)
10921092
{
1093-
return __pci_disable_link_state(pdev, state, false);
1093+
lockdep_assert_held_read(&pci_bus_sem);
1094+
1095+
return __pci_disable_link_state(pdev, state, true);
10941096
}
10951097
EXPORT_SYMBOL(pci_disable_link_state_locked);
10961098

@@ -1105,21 +1107,11 @@ EXPORT_SYMBOL(pci_disable_link_state_locked);
11051107
*/
11061108
int pci_disable_link_state(struct pci_dev *pdev, int state)
11071109
{
1108-
return __pci_disable_link_state(pdev, state, true);
1110+
return __pci_disable_link_state(pdev, state, false);
11091111
}
11101112
EXPORT_SYMBOL(pci_disable_link_state);
11111113

1112-
/**
1113-
* pci_enable_link_state - Clear and set the default device link state so that
1114-
* the link may be allowed to enter the specified states. Note that if the
1115-
* BIOS didn't grant ASPM control to the OS, this does nothing because we can't
1116-
* touch the LNKCTL register. Also note that this does not enable states
1117-
* disabled by pci_disable_link_state(). Return 0 or a negative errno.
1118-
*
1119-
* @pdev: PCI device
1120-
* @state: Mask of ASPM link states to enable
1121-
*/
1122-
int pci_enable_link_state(struct pci_dev *pdev, int state)
1114+
static int __pci_enable_link_state(struct pci_dev *pdev, int state, bool locked)
11231115
{
11241116
struct pcie_link_state *link = pcie_aspm_get_link(pdev);
11251117

@@ -1136,7 +1128,8 @@ int pci_enable_link_state(struct pci_dev *pdev, int state)
11361128
return -EPERM;
11371129
}
11381130

1139-
down_read(&pci_bus_sem);
1131+
if (!locked)
1132+
down_read(&pci_bus_sem);
11401133
mutex_lock(&aspm_lock);
11411134
link->aspm_default = 0;
11421135
if (state & PCIE_LINK_STATE_L0S)
@@ -1157,12 +1150,48 @@ int pci_enable_link_state(struct pci_dev *pdev, int state)
11571150
link->clkpm_default = (state & PCIE_LINK_STATE_CLKPM) ? 1 : 0;
11581151
pcie_set_clkpm(link, policy_to_clkpm_state(link));
11591152
mutex_unlock(&aspm_lock);
1160-
up_read(&pci_bus_sem);
1153+
if (!locked)
1154+
up_read(&pci_bus_sem);
11611155

11621156
return 0;
11631157
}
1158+
1159+
/**
1160+
* pci_enable_link_state - Clear and set the default device link state so that
1161+
* the link may be allowed to enter the specified states. Note that if the
1162+
* BIOS didn't grant ASPM control to the OS, this does nothing because we can't
1163+
* touch the LNKCTL register. Also note that this does not enable states
1164+
* disabled by pci_disable_link_state(). Return 0 or a negative errno.
1165+
*
1166+
* @pdev: PCI device
1167+
* @state: Mask of ASPM link states to enable
1168+
*/
1169+
int pci_enable_link_state(struct pci_dev *pdev, int state)
1170+
{
1171+
return __pci_enable_link_state(pdev, state, false);
1172+
}
11641173
EXPORT_SYMBOL(pci_enable_link_state);
11651174

1175+
/**
1176+
* pci_enable_link_state_locked - Clear and set the default device link state
1177+
* so that the link may be allowed to enter the specified states. Note that if
1178+
* the BIOS didn't grant ASPM control to the OS, this does nothing because we
1179+
* can't touch the LNKCTL register. Also note that this does not enable states
1180+
* disabled by pci_disable_link_state(). Return 0 or a negative errno.
1181+
*
1182+
* @pdev: PCI device
1183+
* @state: Mask of ASPM link states to enable
1184+
*
1185+
* Context: Caller holds pci_bus_sem read lock.
1186+
*/
1187+
int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
1188+
{
1189+
lockdep_assert_held_read(&pci_bus_sem);
1190+
1191+
return __pci_enable_link_state(pdev, state, true);
1192+
}
1193+
EXPORT_SYMBOL(pci_enable_link_state_locked);
1194+
11661195
static int pcie_aspm_set_policy(const char *val,
11671196
const struct kernel_param *kp)
11681197
{

include/linux/pci.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,6 +1829,7 @@ extern bool pcie_ports_native;
18291829
int pci_disable_link_state(struct pci_dev *pdev, int state);
18301830
int pci_disable_link_state_locked(struct pci_dev *pdev, int state);
18311831
int pci_enable_link_state(struct pci_dev *pdev, int state);
1832+
int pci_enable_link_state_locked(struct pci_dev *pdev, int state);
18321833
void pcie_no_aspm(void);
18331834
bool pcie_aspm_support_enabled(void);
18341835
bool pcie_aspm_enabled(struct pci_dev *pdev);
@@ -1839,6 +1840,8 @@ static inline int pci_disable_link_state_locked(struct pci_dev *pdev, int state)
18391840
{ return 0; }
18401841
static inline int pci_enable_link_state(struct pci_dev *pdev, int state)
18411842
{ return 0; }
1843+
static inline int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
1844+
{ return 0; }
18421845
static inline void pcie_no_aspm(void) { }
18431846
static inline bool pcie_aspm_support_enabled(void) { return false; }
18441847
static inline bool pcie_aspm_enabled(struct pci_dev *pdev) { return false; }

0 commit comments

Comments
 (0)