From: Og Subject: Linux 2.6.27.19 Upstream 2.6.27.19 release from kernel.org Signed-off-by: Greg Kroah-Hartman Automatically created from "patches.kernel.org/patch-2.6.27.18-19" by xen-port-patches.py --- sle11-2009-03-16.orig/arch/x86/mm/hypervisor.c 2009-03-16 16:38:16.000000000 +0100 +++ sle11-2009-03-16/arch/x86/mm/hypervisor.c 2009-03-16 16:38:38.000000000 +0100 @@ -79,12 +79,12 @@ static void multicall_failed(const multi BUG(); } -int xen_multicall_flush(bool ret_last) { +static int _xen_multicall_flush(bool ret_last) { struct lazy_mmu *lazy = &__get_cpu_var(lazy_mmu); multicall_entry_t *mc = lazy->mc; unsigned int count = lazy->nr_mc; - if (!count || !use_lazy_mmu_mode()) + if (!count) return 0; lazy->nr_mc = 0; @@ -112,6 +112,11 @@ int xen_multicall_flush(bool ret_last) { return 0; } + +void xen_multicall_flush(bool force) { + if (force || use_lazy_mmu_mode()) + _xen_multicall_flush(false); +} EXPORT_SYMBOL(xen_multicall_flush); int xen_multi_update_va_mapping(unsigned long va, pte_t pte, @@ -130,7 +135,7 @@ int xen_multi_update_va_mapping(unsigned #endif if (unlikely(lazy->nr_mc == NR_MC)) - xen_multicall_flush(false); + _xen_multicall_flush(false); mc = lazy->mc + lazy->nr_mc++; mc->op = __HYPERVISOR_update_va_mapping; @@ -169,7 +174,7 @@ int xen_multi_mmu_update(mmu_update_t *s merge = lazy->nr_mc && !commit && mmu_may_merge(mc - 1, __HYPERVISOR_mmu_update, domid); if (unlikely(lazy->nr_mc == NR_MC) && !merge) { - xen_multicall_flush(false); + _xen_multicall_flush(false); mc = lazy->mc; commit = count > NR_MMU || success_count; } @@ -207,7 +212,7 @@ int xen_multi_mmu_update(mmu_update_t *s break; } - return commit ? xen_multicall_flush(true) : 0; + return commit ? _xen_multicall_flush(true) : 0; } int xen_multi_mmuext_op(struct mmuext_op *src, unsigned int count, @@ -291,7 +296,7 @@ int xen_multi_mmuext_op(struct mmuext_op merge = lazy->nr_mc && !commit && mmu_may_merge(mc - 1, __HYPERVISOR_mmuext_op, domid); if (unlikely(lazy->nr_mc == NR_MC) && !merge) { - xen_multicall_flush(false); + _xen_multicall_flush(false); mc = lazy->mc; commit = count > NR_MMUEXT || success_count; } @@ -338,7 +343,7 @@ int xen_multi_mmuext_op(struct mmuext_op break; } - return commit ? xen_multicall_flush(true) : 0; + return commit ? _xen_multicall_flush(true) : 0; } void xen_l1_entry_update(pte_t *ptr, pte_t val) --- sle11-2009-03-16.orig/arch/x86/mm/pageattr-xen.c 2009-03-16 16:38:34.000000000 +0100 +++ sle11-2009-03-16/arch/x86/mm/pageattr-xen.c 2009-03-16 16:38:38.000000000 +0100 @@ -639,6 +639,15 @@ static int __change_page_attr(struct cpa unsigned int level; pte_t *kpte, old_pte; + /* + * If we're called with lazy mmu updates enabled, the + * in-memory pte state may be stale. Flush pending updates to + * bring them up to date. + * + arch_flush_lazy_mmu_mode();*/ + if (arch_use_lazy_mmu_mode()) + xen_multicall_flush(true); + repeat: kpte = lookup_address(address, &level); if (!kpte) @@ -857,6 +866,14 @@ static int change_page_attr_set_clr(unsi else cpa_flush_all(cache); + /* + * If we've been called with lazy mmu updates enabled, then + * make sure that everything gets flushed out before we + * return. + * + arch_flush_lazy_mmu_mode();*/ + WARN_ON_ONCE(arch_use_lazy_mmu_mode() && !irq_count()); + out: cpa_fill_pool(NULL); --- sle11-2009-03-16.orig/include/asm-x86/mach-xen/asm/hypervisor.h 2009-03-16 16:38:16.000000000 +0100 +++ sle11-2009-03-16/include/asm-x86/mach-xen/asm/hypervisor.h 2009-03-16 16:38:38.000000000 +0100 @@ -132,7 +132,7 @@ void scrub_pages(void *, unsigned int); DECLARE_PER_CPU(bool, xen_lazy_mmu); -int xen_multicall_flush(bool); +void xen_multicall_flush(bool); int __must_check xen_multi_update_va_mapping(unsigned long va, pte_t, unsigned long flags);