diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-12-17 06:27:55 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-12-17 06:27:55 +0000 |
commit | 8992ab0adfe9b708574759383f3798121fdf977c (patch) | |
tree | 57796ea889db64945f0f7aff3a8573823bfe41e4 | |
parent | 35387f6582edb099b6feceb528d7f98ac0a99efc (diff) | |
download | xen-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.c | 32 | ||||
-rw-r--r-- | xen/include/asm-x86/processor.h | 1 |
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__ |