]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
x86/mm: Fix two PAE+paging bugs
authorAndres Lagar-Cavilla <andres@lagarcavilla.org>
Thu, 16 Feb 2012 15:43:02 +0000 (15:43 +0000)
committerAndres Lagar-Cavilla <andres@lagarcavilla.org>
Thu, 16 Feb 2012 15:43:02 +0000 (15:43 +0000)
In hap_paging_update_modes, we were getting the gpa of the cr3, rather
than the gfn.

Vmx_load_pdptrs was crashing the host if the cr3 is paged out. Now it
will only crash the guest.

Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.org>
Signed-off-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/mm/hap/hap.c

index 0f65334bbdc46b9ec550fb6f9d1d98dbae3b2840..61d1fda54d7f07707a1e57489e8066f507c4f3a6 100644 (file)
@@ -1010,12 +1010,22 @@ static void vmx_load_pdptrs(struct vcpu *v)
     if ( (cr3 & 0x1fUL) && !hvm_pcid_enabled(v) )
         goto crash;
 
-    mfn = mfn_x(get_gfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt));
-    if ( !p2m_is_ram(p2mt) )
+    mfn = mfn_x(get_gfn_unshare(v->domain, cr3 >> PAGE_SHIFT, &p2mt));
+    if ( !p2m_is_ram(p2mt) || !mfn_valid(mfn) || 
+         /* If we didn't succeed in unsharing, get_page will fail
+          * (page still belongs to dom_cow) */
+         !get_page(mfn_to_page(mfn), v->domain) )
     {
+        /* Ideally you don't want to crash but rather go into a wait 
+         * queue, but this is the wrong place. We're holding at least
+         * the paging lock */
+        gdprintk(XENLOG_ERR,
+                 "Bad cr3 on load pdptrs gfn %lx mfn %lx type %d\n",
+                 cr3 >> PAGE_SHIFT, mfn, (int) p2mt);
         put_gfn(v->domain, cr3 >> PAGE_SHIFT);
         goto crash;
     }
+    put_gfn(v->domain, cr3 >> PAGE_SHIFT);
 
     p = map_domain_page(mfn);
 
@@ -1043,7 +1053,7 @@ static void vmx_load_pdptrs(struct vcpu *v)
     vmx_vmcs_exit(v);
 
     unmap_domain_page(p);
-    put_gfn(v->domain, cr3 >> PAGE_SHIFT);
+    put_page(mfn_to_page(mfn));
     return;
 
  crash:
index debaba4f9e8a6241e31c6d365a009fc533398075..9efb801ae8f4d6756ae801f4d2a17bd77c7cba67 100644 (file)
@@ -786,7 +786,7 @@ hap_paging_get_mode(struct vcpu *v)
 static void hap_update_paging_modes(struct vcpu *v)
 {
     struct domain *d = v->domain;
-    unsigned long cr3_gfn = v->arch.hvm_vcpu.guest_cr[3];
+    unsigned long cr3_gfn = v->arch.hvm_vcpu.guest_cr[3] >> PAGE_SHIFT;
     p2m_type_t t;
 
     /* We hold onto the cr3 as it may be modified later, and