diff options
author | Peter Zijlstra <peterz@infradead.org> | 2018-09-19 04:50:18 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2018-09-27 14:39:40 -0400 |
commit | c0a759abf5a686a37b9204c13b7e281fe516c8f0 (patch) | |
tree | 8dfc4de4e0afd4098adcaaf9b709b37707acdb37 | |
parent | c6185b1f21a47af94617fde3af7e803817b522a9 (diff) |
x86/mm/cpa: Move flush_tlb_all()
There is an atom errata, where we do a local TLB invalidate right
before we return and then do a global TLB invalidate.
Move the global invalidate up a little bit and avoid the local
invalidate entirely.
This does put the global invalidate under pgd_lock, but that shouldn't
matter.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Dave Hansen <dave.hansen@intel.com>
Cc: Bin Yang <bin.yang@intel.com>
Cc: Mark Gross <mark.gross@intel.com>
Link: https://lkml.kernel.org/r/20180919085947.882287392@infradead.org
-rw-r--r-- | arch/x86/mm/pageattr.c | 44 |
1 files changed, 17 insertions, 27 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index a22f6b71a308..b6a4c638f086 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -999,14 +999,24 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address, | |||
999 | __set_pmd_pte(kpte, address, mk_pte(base, __pgprot(_KERNPG_TABLE))); | 999 | __set_pmd_pte(kpte, address, mk_pte(base, __pgprot(_KERNPG_TABLE))); |
1000 | 1000 | ||
1001 | /* | 1001 | /* |
1002 | * Intel Atom errata AAH41 workaround. | 1002 | * Do a global flush tlb after splitting the large page |
1003 | * and before we do the actual change page attribute in the PTE. | ||
1003 | * | 1004 | * |
1004 | * The real fix should be in hw or in a microcode update, but | 1005 | * Without this, we violate the TLB application note, that says: |
1005 | * we also probabilistically try to reduce the window of having | 1006 | * "The TLBs may contain both ordinary and large-page |
1006 | * a large TLB mixed with 4K TLBs while instruction fetches are | 1007 | * translations for a 4-KByte range of linear addresses. This |
1007 | * going on. | 1008 | * may occur if software modifies the paging structures so that |
1009 | * the page size used for the address range changes. If the two | ||
1010 | * translations differ with respect to page frame or attributes | ||
1011 | * (e.g., permissions), processor behavior is undefined and may | ||
1012 | * be implementation-specific." | ||
1013 | * | ||
1014 | * We do this global tlb flush inside the cpa_lock, so that we | ||
1015 | * don't allow any other cpu, with stale tlb entries change the | ||
1016 | * page attribute in parallel, that also falls into the | ||
1017 | * just split large page entry. | ||
1008 | */ | 1018 | */ |
1009 | __flush_tlb_all(); | 1019 | flush_tlb_all(); |
1010 | spin_unlock(&pgd_lock); | 1020 | spin_unlock(&pgd_lock); |
1011 | 1021 | ||
1012 | return 0; | 1022 | return 0; |
@@ -1531,28 +1541,8 @@ repeat: | |||
1531 | * We have to split the large page: | 1541 | * We have to split the large page: |
1532 | */ | 1542 | */ |
1533 | err = split_large_page(cpa, kpte, address); | 1543 | err = split_large_page(cpa, kpte, address); |
1534 | if (!err) { | 1544 | if (!err) |
1535 | /* | ||
1536 | * Do a global flush tlb after splitting the large page | ||
1537 | * and before we do the actual change page attribute in the PTE. | ||
1538 | * | ||
1539 | * With out this, we violate the TLB application note, that says | ||
1540 | * "The TLBs may contain both ordinary and large-page | ||
1541 | * translations for a 4-KByte range of linear addresses. This | ||
1542 | * may occur if software modifies the paging structures so that | ||
1543 | * the page size used for the address range changes. If the two | ||
1544 | * translations differ with respect to page frame or attributes | ||
1545 | * (e.g., permissions), processor behavior is undefined and may | ||
1546 | * be implementation-specific." | ||
1547 | * | ||
1548 | * We do this global tlb flush inside the cpa_lock, so that we | ||
1549 | * don't allow any other cpu, with stale tlb entries change the | ||
1550 | * page attribute in parallel, that also falls into the | ||
1551 | * just split large page entry. | ||
1552 | */ | ||
1553 | flush_tlb_all(); | ||
1554 | goto repeat; | 1545 | goto repeat; |
1555 | } | ||
1556 | 1546 | ||
1557 | return err; | 1547 | return err; |
1558 | } | 1548 | } |