diff options
author | Zhang Xiantao <xiantao.zhang@intel.com> | 2013-01-15 11:11:37 +0100 |
---|---|---|
committer | Zhang Xiantao <xiantao.zhang@intel.com> | 2013-01-15 11:11:37 +0100 |
commit | 31c1595f59a3099739f60338623900f5f0130f69 (patch) | |
tree | 9bd7d5fe8760b05b6fcfeb4e104014c139a78852 /xen/arch/x86/hvm/svm | |
parent | 199707892b20ba62578338ddf5b33e21aea89a3c (diff) | |
download | xen-31c1595f59a3099739f60338623900f5f0130f69.tar.gz xen-31c1595f59a3099739f60338623900f5f0130f69.tar.bz2 xen-31c1595f59a3099739f60338623900f5f0130f69.zip |
nestedhap: Change nested p2m's walker to vendor-specific
EPT and NPT adopts differnt formats for each-level entry,
so change the walker functions to vendor-specific.
Signed-off-by: Zhang Xiantao <xiantao.zhang@intel.com>
Acked-by: Tim Deegan <tim@xen.org>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
Committed-by: Jan Beulich <jbeulich@suse.com>
Diffstat (limited to 'xen/arch/x86/hvm/svm')
-rw-r--r-- | xen/arch/x86/hvm/svm/nestedsvm.c | 30 | ||||
-rw-r--r-- | xen/arch/x86/hvm/svm/svm.c | 1 |
2 files changed, 31 insertions, 0 deletions
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c index ed0faa640f..0a7da95b86 100644 --- a/xen/arch/x86/hvm/svm/nestedsvm.c +++ b/xen/arch/x86/hvm/svm/nestedsvm.c @@ -1171,6 +1171,36 @@ nsvm_vmcb_hap_enabled(struct vcpu *v) return vcpu_nestedsvm(v).ns_hap_enabled; } +/* This function uses L2_gpa to walk the P2M page table in L1. If the + * walk is successful, the translated value is returned in + * L1_gpa. The result value tells what to do next. + */ +int +nsvm_hap_walk_L1_p2m(struct vcpu *v, paddr_t L2_gpa, paddr_t *L1_gpa, + unsigned int *page_order, + bool_t access_r, bool_t access_w, bool_t access_x) +{ + uint32_t pfec; + unsigned long nested_cr3, gfn; + + nested_cr3 = nhvm_vcpu_p2m_base(v); + + pfec = PFEC_user_mode | PFEC_page_present; + if ( access_w ) + pfec |= PFEC_write_access; + if ( access_x ) + pfec |= PFEC_insn_fetch; + + /* Walk the guest-supplied NPT table, just as if it were a pagetable */ + gfn = paging_ga_to_gfn_cr3(v, nested_cr3, L2_gpa, &pfec, page_order); + + if ( gfn == INVALID_GFN ) + return NESTEDHVM_PAGEFAULT_INJECT; + + *L1_gpa = (gfn << PAGE_SHIFT) + (L2_gpa & ~PAGE_MASK); + return NESTEDHVM_PAGEFAULT_DONE; +} + enum hvm_intblk nsvm_intr_blocked(struct vcpu *v) { struct nestedsvm *svm = &vcpu_nestedsvm(v); diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 2c8504a881..acd2d4953e 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2008,6 +2008,7 @@ static struct hvm_function_table __read_mostly svm_function_table = { .nhvm_vmcx_guest_intercepts_trap = nsvm_vmcb_guest_intercepts_trap, .nhvm_vmcx_hap_enabled = nsvm_vmcb_hap_enabled, .nhvm_intr_blocked = nsvm_intr_blocked, + .nhvm_hap_walk_L1_p2m = nsvm_hap_walk_L1_p2m, }; void svm_vmexit_handler(struct cpu_user_regs *regs) |