aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/svm
diff options
context:
space:
mode:
authorZhang Xiantao <xiantao.zhang@intel.com>2013-01-15 11:11:37 +0100
committerZhang Xiantao <xiantao.zhang@intel.com>2013-01-15 11:11:37 +0100
commit31c1595f59a3099739f60338623900f5f0130f69 (patch)
tree9bd7d5fe8760b05b6fcfeb4e104014c139a78852 /xen/arch/x86/hvm/svm
parent199707892b20ba62578338ddf5b33e21aea89a3c (diff)
downloadxen-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.c30
-rw-r--r--xen/arch/x86/hvm/svm/svm.c1
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)