aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2009-02-11 12:32:19 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-12 02:27:26 -0500
commit4f06b0436b2ddbd3b67b10e77098a6862787b3eb (patch)
treefc1ec5bcd2f7ed2c77121d87ffe5839ec7bdaeaa
parent9f339e7028e2855717af3193c938f9960ad13b38 (diff)
x86/cpa: make sure cpa is safe to call in lazy mmu mode
Impact: fix race leading to crash under KVM and Xen The CPA code may be called while we're in lazy mmu update mode - for example, when using DEBUG_PAGE_ALLOC and doing a slab allocation in an interrupt handler which interrupted a lazy mmu update. In this case, the in-memory pagetable state may be out of date due to pending queued updates. We need to flush any pending updates before inspecting the page table. Similarly, we must explicitly flush any modifications CPA may have made (which comes down to flushing queued operations when flushing the TLB). Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Acked-by: Marcelo Tosatti <mtosatti@redhat.com> Cc: Stable Kernel <stable@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/mm/pageattr.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 84ba74820ad6..f664bc1c4093 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -576,6 +576,13 @@ static int __change_page_attr(struct cpa_data *cpa, int primary)
576 else 576 else
577 address = *cpa->vaddr; 577 address = *cpa->vaddr;
578 578
579 /*
580 * If we're called with lazy mmu updates enabled, the
581 * in-memory pte state may be stale. Flush pending updates to
582 * bring them up to date.
583 */
584 arch_flush_lazy_mmu_mode();
585
579repeat: 586repeat:
580 kpte = lookup_address(address, &level); 587 kpte = lookup_address(address, &level);
581 if (!kpte) 588 if (!kpte)
@@ -854,6 +861,13 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
854 } else 861 } else
855 cpa_flush_all(cache); 862 cpa_flush_all(cache);
856 863
864 /*
865 * If we've been called with lazy mmu updates enabled, then
866 * make sure that everything gets flushed out before we
867 * return.
868 */
869 arch_flush_lazy_mmu_mode();
870
857out: 871out:
858 return ret; 872 return ret;
859} 873}