summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2009-03-31 01:55:02 +0000
committerChris Wright <chrisw@sous-sol.org>2009-04-02 13:55:19 -0700
commitab624168973480d92c844cc6c46f97d85bedd91c (patch)
treea1982d4d915b61927e1be9016202d02534f2ca26
parent73dffc3a1e9678facba4cd762aa9a3692c7b4a72 (diff)
lguest: wire up pte_update/pte_update_defer
upstream commit: b7ff99ea53cd16de8f6166c0e98f19a7c6ca67ee Impact: intermittent guest segv/crash fix I've been seeing random guest bad address crashes and segmentation faults: bisect led to 4f98a2fee8 (vmscan: split LRU lists into anon & file sets), but that's a red herring. It turns out that lguest never hooked up the pte_update/pte_update_defer calls, so our ptes were not always in sync. After the vmscan commit, the bug became reproducible; now a fsck in a 64MB guest causes reproducible pagetable corruption. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Cc: jeremy@xensource.com Cc: virtualization@lists.osdl.org Cc: stable@kernel.org Signed-off-by: Chris Wright <chrisw@sous-sol.org>
-rw-r--r--arch/x86/lguest/boot.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 960a8d9c049c..4175cb446d0d 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -485,11 +485,17 @@ static void lguest_write_cr4(unsigned long val)
* into a process' address space. We set the entry then tell the Host the
* toplevel and address this corresponds to. The Guest uses one pagetable per
* process, so we need to tell the Host which one we're changing (mm->pgd). */
+static void lguest_pte_update(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ lazy_hcall(LHCALL_SET_PTE, __pa(mm->pgd), addr, ptep->pte_low);
+}
+
static void lguest_set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
*ptep = pteval;
- lazy_hcall(LHCALL_SET_PTE, __pa(mm->pgd), addr, pteval.pte_low);
+ lguest_pte_update(mm, addr, ptep);
}
/* The Guest calls this to set a top-level entry. Again, we set the entry then
@@ -1034,6 +1040,8 @@ __init void lguest_init(void)
pv_mmu_ops.read_cr3 = lguest_read_cr3;
pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu;
pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mode;
+ pv_mmu_ops.pte_update = lguest_pte_update;
+ pv_mmu_ops.pte_update_defer = lguest_pte_update;
#ifdef CONFIG_X86_LOCAL_APIC
/* apic read/write intercepts */