aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/mmconfig_32.c
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@huawei.com>2012-06-22 14:55:12 +0800
committerBjorn Helgaas <bhelgaas@google.com>2012-06-22 15:16:23 -0600
commit376f70acfe4bd97493299cdfc00a8d235279d267 (patch)
treed01d16dd08be5216c3186e69bcd5f9f0ada415ce /arch/x86/pci/mmconfig_32.c
parentx86/PCI: split out pci_mmconfig_alloc() for code reuse (diff)
downloadlinux-dev-376f70acfe4bd97493299cdfc00a8d235279d267.tar.xz
linux-dev-376f70acfe4bd97493299cdfc00a8d235279d267.zip
x86/PCI: use RCU list to protect mmconfig list
Use RCU list to protect mmconfig list from dynamic change when supporting PCI host bridge hotplug. Reviewed-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Jiang Liu <liuj97@gmail.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'arch/x86/pci/mmconfig_32.c')
-rw-r--r--arch/x86/pci/mmconfig_32.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 5372e86834c0..5dad04aa6b37 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -11,6 +11,7 @@
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/rcupdate.h>
#include <asm/e820.h>
#include <asm/pci_x86.h>
#include <acpi/acpi.h>
@@ -60,9 +61,12 @@ err: *value = -1;
return -EINVAL;
}
+ rcu_read_lock();
base = get_base_addr(seg, bus, devfn);
- if (!base)
+ if (!base) {
+ rcu_read_unlock();
goto err;
+ }
raw_spin_lock_irqsave(&pci_config_lock, flags);
@@ -80,6 +84,7 @@ err: *value = -1;
break;
}
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+ rcu_read_unlock();
return 0;
}
@@ -93,9 +98,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
if ((bus > 255) || (devfn > 255) || (reg > 4095))
return -EINVAL;
+ rcu_read_lock();
base = get_base_addr(seg, bus, devfn);
- if (!base)
+ if (!base) {
+ rcu_read_unlock();
return -EINVAL;
+ }
raw_spin_lock_irqsave(&pci_config_lock, flags);
@@ -113,6 +121,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
break;
}
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+ rcu_read_unlock();
return 0;
}