hap_gva_to_gfn paging support. Return PFEC_page_paged when a paged
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 17 Dec 2009 06:27:55 +0000 (06:27 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 17 Dec 2009 06:27:55 +0000 (06:27 +0000)
out page is found. Ensure top-level page table page and l1 entry
are paged in. If an intermediary page table page is paged out,
propogate error to caller.

Signed-off-by: Patrick Colp <Patrick.Colp@citrix.com>
xen/arch/x86/mm/hap/guest_walk.c
xen/include/asm-x86/processor.h

index 3ec97d492a4d81d53efea019d3bd453504a39dff..be8a85e071301d5396200035c2c2481636b522c5 100644 (file)
@@ -46,6 +46,14 @@ unsigned long hap_gva_to_gfn(GUEST_PAGING_LEVELS)(
     /* Get the top-level table's MFN */
     cr3 = v->arch.hvm_vcpu.guest_cr[3];
     top_mfn = gfn_to_mfn(v->domain, _gfn(cr3 >> PAGE_SHIFT), &p2mt);
+    if ( p2m_is_paging(p2mt) )
+    {
+//        if ( p2m_is_paged(p2mt) )
+            p2m_mem_paging_populate(v->domain, cr3 >> PAGE_SHIFT);
+
+        pfec[0] = PFEC_page_paged;
+        return INVALID_GFN;
+    }
     if ( !p2m_is_ram(p2mt) )
     {
         pfec[0] &= ~PFEC_page_present;
@@ -62,12 +70,28 @@ unsigned long hap_gva_to_gfn(GUEST_PAGING_LEVELS)(
     unmap_domain_page(top_map);
 
     /* Interpret the answer */
-    if ( missing == 0 ) 
-        return gfn_x(guest_l1e_get_gfn(gw.l1e));
-    
+    if ( missing == 0 )
+    {
+        gfn_t gfn = guest_l1e_get_gfn(gw.l1e);
+        gfn_to_mfn(v->domain, gfn, &p2mt);
+        if ( p2m_is_paging(p2mt) )
+        {
+//            if ( p2m_is_paged(p2mt) )
+                p2m_mem_paging_populate(v->domain, gfn_x(gfn));
+
+            pfec[0] = PFEC_page_paged;
+            return INVALID_GFN;
+        }
+
+        return gfn_x(gfn);
+    }
+
     if ( missing & _PAGE_PRESENT )
         pfec[0] &= ~PFEC_page_present;
-    
+
+    if ( missing & _PAGE_PAGED )
+        pfec[0] = PFEC_page_paged;
+
     return INVALID_GFN;
 }
 
index 628965ae3eda91eeae105e8506c2efa938c95ffd..fc4b531022a7d9a01ac91b9000587afa0a7ed73b 100644 (file)
 #define PFEC_user_mode      (1U<<2)
 #define PFEC_reserved_bit   (1U<<3)
 #define PFEC_insn_fetch     (1U<<4)
+#define PFEC_page_paged     (1U<<5)
 
 #ifndef __ASSEMBLY__