diff -r ae0e96e156f3 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Thu Jul 19 12:12:12 2012 +0200 +++ b/xen/arch/x86/hvm/hvm.c Thu Jul 19 15:30:04 2012 +0200 @@ -1291,6 +1291,8 @@ int hvm_hap_nested_page_fault(unsigned l if ( !handle_mmio() ) hvm_inject_hw_exception(TRAP_gp_fault, 0); return 1; + case NESTEDHVM_PAGEFAULT_READONLY: + break; } } diff -r ae0e96e156f3 xen/arch/x86/mm/hap/nested_hap.c --- a/xen/arch/x86/mm/hap/nested_hap.c Thu Jul 19 12:12:12 2012 +0200 +++ b/xen/arch/x86/mm/hap/nested_hap.c Thu Jul 19 15:30:04 2012 +0200 @@ -141,23 +141,28 @@ nestedhap_fix_p2m(struct vcpu *v, struct */ static int nestedhap_walk_L0_p2m(struct p2m_domain *p2m, paddr_t L1_gpa, paddr_t *L0_gpa, - unsigned int *page_order) + p2m_type_t *p2mt, + unsigned int *page_order, + bool_t access_r, bool_t access_w, bool_t access_x) { mfn_t mfn; - p2m_type_t p2mt; p2m_access_t p2ma; int rc; /* walk L0 P2M table */ - mfn = get_gfn_type_access(p2m, L1_gpa >> PAGE_SHIFT, &p2mt, &p2ma, + mfn = get_gfn_type_access(p2m, L1_gpa >> PAGE_SHIFT, p2mt, &p2ma, 0, page_order); rc = NESTEDHVM_PAGEFAULT_MMIO; - if ( p2m_is_mmio(p2mt) ) + if ( p2m_is_mmio(*p2mt) ) + goto out; + + rc = NESTEDHVM_PAGEFAULT_READONLY; + if ( access_w && p2m_is_readonly(*p2mt) ) goto out; rc = NESTEDHVM_PAGEFAULT_ERROR; - if ( p2m_is_paging(p2mt) || p2m_is_shared(p2mt) || !p2m_is_ram(p2mt) ) + if ( p2m_is_paging(*p2mt) || p2m_is_shared(*p2mt) || !p2m_is_ram(*p2mt) ) goto out; rc = NESTEDHVM_PAGEFAULT_ERROR; @@ -215,6 +220,7 @@ nestedhvm_hap_nested_page_fault(struct v struct domain *d = v->domain; struct p2m_domain *p2m, *nested_p2m; unsigned int page_order_21, page_order_10, page_order_20; + p2m_type_t p2mt_10; p2m = p2m_get_hostp2m(d); /* L0 p2m */ nested_p2m = p2m_get_nestedp2m(v, nhvm_vcpu_hostcr3(v)); @@ -237,7 +243,9 @@ nestedhvm_hap_nested_page_fault(struct v } /* ==> we have to walk L0 P2M */ - rv = nestedhap_walk_L0_p2m(p2m, L1_gpa, &L0_gpa, &page_order_10); + rv = nestedhap_walk_L0_p2m(p2m, L1_gpa, &L0_gpa, + &p2mt_10, &page_order_10, + access_r, access_w, access_x); /* let upper level caller to handle these two cases */ switch (rv) { @@ -249,6 +257,8 @@ nestedhvm_hap_nested_page_fault(struct v break; case NESTEDHVM_PAGEFAULT_MMIO: return rv; + case NESTEDHVM_PAGEFAULT_READONLY: + return rv; default: BUG(); break; @@ -258,8 +268,8 @@ nestedhvm_hap_nested_page_fault(struct v /* fix p2m_get_pagetable(nested_p2m) */ nestedhap_fix_p2m(v, nested_p2m, L2_gpa, L0_gpa, page_order_20, - p2m_ram_rw, - p2m_access_rwx /* FIXME: Should use same permission as l1 guest */); + p2mt_10, + p2m_access_rwx /* FIXME: Should use minimum permission. */); return NESTEDHVM_PAGEFAULT_DONE; } diff -r ae0e96e156f3 xen/include/asm-x86/hvm/nestedhvm.h --- a/xen/include/asm-x86/hvm/nestedhvm.h Thu Jul 19 12:12:12 2012 +0200 +++ b/xen/include/asm-x86/hvm/nestedhvm.h Thu Jul 19 15:30:04 2012 +0200 @@ -47,10 +47,11 @@ bool_t nestedhvm_vcpu_in_guestmode(struc vcpu_nestedhvm(v).nv_guestmode = 0 /* Nested paging */ -#define NESTEDHVM_PAGEFAULT_DONE 0 -#define NESTEDHVM_PAGEFAULT_INJECT 1 -#define NESTEDHVM_PAGEFAULT_ERROR 2 -#define NESTEDHVM_PAGEFAULT_MMIO 3 +#define NESTEDHVM_PAGEFAULT_DONE 0 +#define NESTEDHVM_PAGEFAULT_INJECT 1 +#define NESTEDHVM_PAGEFAULT_ERROR 2 +#define NESTEDHVM_PAGEFAULT_MMIO 3 +#define NESTEDHVM_PAGEFAULT_READONLY 4 int nestedhvm_hap_nested_page_fault(struct vcpu *v, paddr_t L2_gpa, bool_t access_r, bool_t access_w, bool_t access_x);