OpenCloudOS-Kernel/arch/i386/pci
OGAWA Hirofumi 8d1c481960 [PATCH] arch/i386/pci/mmconfig.c tlb flush fix
We use the fixmap for accessing pci config space in pci_mmcfg_read/write().
The problem is in pci_exp_set_dev_base(). It is caching a last
accessed address to avoid calling set_fixmap_nocache() whenever
pci_mmcfg_read/write() is used.

  static inline void pci_exp_set_dev_base(int bus, int devfn)
  {
	u32 dev_base = base | (bus << 20) | (devfn << 12);
	if (dev_base != mmcfg_last_accessed_device) {
		mmcfg_last_accessed_device = dev_base;
		set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
	}
  }

            cpu0                                        cpu1
  ---------------------------------------------------------------------------
    pci_mmcfg_read("device-A")
        pci_exp_set_dev_base()
            set_fixmap_nocache()
                                              pci_mmcfg_read("device-B")
                                                  pci_exp_set_dev_base()
                                                      set_fixmap_nocache()
    pci_mmcfg_read("device-B")
        pci_exp_set_dev_base()
            /* doesn't flush tlb */

But if cpus accessed the above order, the second pci_mmcfg_read() on
cpu0 doesn't flush the TLB, because "mmcfg_last_accessed_device" is
device-B.  So, second pci_mmcfg_read() on cpu0 accesses a device-A via
a previous TLB cache. This problem became the cause of several strange
behavior.

This patches fixes this situation by adds "mmcfg_last_accessed_cpu" check.

[ Alternatively, we could make a per-cpu mapping area or something. Not
  that it's probably worth it, but if we wanted to avoid all locking and
  instead just disable preemption, that would be the way to go. --Linus ]

Signed-off-by: OGAWA Hirofumi <hogawa@miraclelinux.com>
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-23 14:06:33 -08:00
..
Makefile [PATCH] x86: Move direct PCI scanning functions out of line 2006-09-26 10:52:41 +02:00
acpi.c [PATCH] PCI: arch/i386/pci/acpi.c: use for_each_pci_dev 2006-01-09 12:13:15 -08:00
common.c PCI: make arch/i386/pci/common.c:pci_bf_sort static 2006-12-01 14:37:00 -08:00
direct.c [PATCH] i386: Fix PCI BIOS config space access 2006-10-05 18:47:22 +02:00
early.c [PATCH] x86: add write_pci_config_byte() to direct PCI access routines 2006-12-07 02:14:10 +01:00
fixup.c PCI: Fix multiple problems with VIA hardware 2006-12-20 10:54:43 -08:00
i386.c pci/i386: style cleanups 2006-12-01 14:36:58 -08:00
init.c [PATCH] i386: Fix PCI BIOS config space access 2006-10-05 18:47:22 +02:00
irq.c [PATCH] x86: remove last two pci_find offenders in the core code 2006-12-07 02:14:03 +01:00
legacy.c [PATCH] acpi bridge hotadd: ACPI based root bridge hot-add 2005-06-27 21:52:39 -07:00
mmconfig.c [PATCH] arch/i386/pci/mmconfig.c tlb flush fix 2006-12-23 14:06:33 -08:00
numa.c [PATCH] acpi bridge hotadd: ACPI based root bridge hot-add 2005-06-27 21:52:39 -07:00
pcbios.c [PATCH] paravirt: Be careful about touching BIOS address space 2006-12-07 02:14:08 +01:00
pci.h PCI: Revert "PCI: i386/x86_84: disable PCI resource decode on device disable" 2006-11-02 23:02:24 -08:00
visws.c Remove obsolete #include <linux/config.h> 2006-06-30 19:25:36 +02:00