Commit:     8d1c481960ba833362aa78245fdff12e3804f8b5
Parent:     e1d9fd2e3d33b2fec3207171ec8ca6e71d5c81c7
Author:     OGAWA Hirofumi <[EMAIL PROTECTED]>
AuthorDate: Sat Dec 23 10:00:43 2006 +0900
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Sat Dec 23 14:06:33 2006 -0800

    [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
                /* 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
    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 <[EMAIL PROTECTED]>
    Signed-off-by: OGAWA Hirofumi <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
 arch/i386/pci/mmconfig.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index c6b6d9b..e2616a2 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -26,6 +26,7 @@
 /* The base address of the last MMCONFIG device accessed */
 static u32 mmcfg_last_accessed_device;
+static int mmcfg_last_accessed_cpu;
 static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32);
@@ -73,8 +74,11 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned 
 static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
        u32 dev_base = base | (bus << 20) | (devfn << 12);
-       if (dev_base != mmcfg_last_accessed_device) {
+       int cpu = smp_processor_id();
+       if (dev_base != mmcfg_last_accessed_device ||
+           cpu != mmcfg_last_accessed_cpu) {
                mmcfg_last_accessed_device = dev_base;
+               mmcfg_last_accessed_cpu = cpu;
                set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at

Reply via email to