diff options
author | Jiang Liu <jiang.liu@huawei.com> | 2012-06-22 14:55:12 +0800 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-06-22 15:16:23 -0600 |
commit | 376f70acfe4bd97493299cdfc00a8d235279d267 (patch) | |
tree | d01d16dd08be5216c3186e69bcd5f9f0ada415ce /arch/x86/pci/mmconfig_64.c | |
parent | 846e402300ffa2131239dcf82265b5366cd755f4 (diff) | |
download | blackbird-op-linux-376f70acfe4bd97493299cdfc00a8d235279d267.tar.gz blackbird-op-linux-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_64.c')
-rw-r--r-- | arch/x86/pci/mmconfig_64.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index 915a493502cb..acc48c5b6863 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c @@ -9,6 +9,7 @@ #include <linux/init.h> #include <linux/acpi.h> #include <linux/bitmap.h> +#include <linux/rcupdate.h> #include <asm/e820.h> #include <asm/pci_x86.h> @@ -34,9 +35,12 @@ err: *value = -1; return -EINVAL; } + rcu_read_lock(); addr = pci_dev_base(seg, bus, devfn); - if (!addr) + if (!addr) { + rcu_read_unlock(); goto err; + } switch (len) { case 1: @@ -49,6 +53,7 @@ err: *value = -1; *value = mmio_config_readl(addr + reg); break; } + rcu_read_unlock(); return 0; } @@ -62,9 +67,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; + rcu_read_lock(); addr = pci_dev_base(seg, bus, devfn); - if (!addr) + if (!addr) { + rcu_read_unlock(); return -EINVAL; + } switch (len) { case 1: @@ -77,6 +85,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, mmio_config_writel(addr + reg, value); break; } + rcu_read_unlock(); return 0; } |