aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-12-17 06:27:55 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-12-17 06:27:55 +0000
commit8992ab0adfe9b708574759383f3798121fdf977c (patch)
tree57796ea889db64945f0f7aff3a8573823bfe41e4
parent35387f6582edb099b6feceb528d7f98ac0a99efc (diff)
downloadxen-8992ab0adfe9b708574759383f3798121fdf977c.tar.gz
xen-8992ab0adfe9b708574759383f3798121fdf977c.tar.bz2
xen-8992ab0adfe9b708574759383f3798121fdf977c.zip
hap_gva_to_gfn paging support. Return PFEC_page_paged when a paged
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>
-rw-r--r--xen/arch/x86/mm/hap/guest_walk.c32
-rw-r--r--xen/include/asm-x86/processor.h1
2 files changed, 29 insertions, 4 deletions
diff --git a/xen/arch/x86/mm/hap/guest_walk.c b/xen/arch/x86/mm/hap/guest_walk.c
index 3ec97d492a..be8a85e071 100644
--- a/xen/arch/x86/mm/hap/guest_walk.c
+++ b/xen/arch/x86/mm/hap/guest_walk.c
@@ -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;
}
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index 628965ae3e..fc4b531022 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -132,6 +132,7 @@
#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__