aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/asm-x86
diff options
context:
space:
mode:
authorcegger <none@none>2011-03-09 12:36:05 +0100
committercegger <none@none>2011-03-09 12:36:05 +0100
commit9a779e4fc1619a61c407d4db8934c8732a6c2d02 (patch)
tree7f5f51e5b821fa90d1c2c01f4aa0eaad5f27c3f5 /xen/include/asm-x86
parent5120a76fad77858d2ac2cbcce8a3dd3500d25e87 (diff)
downloadxen-9a779e4fc1619a61c407d4db8934c8732a6c2d02.tar.gz
xen-9a779e4fc1619a61c407d4db8934c8732a6c2d02.tar.bz2
xen-9a779e4fc1619a61c407d4db8934c8732a6c2d02.zip
Implement SVM specific part for Nested Virtualization
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com> Acked-by: Tim Deegan <Tim.Deegan@citrix.com> Committed-by: Tim Deegan <Tim.Deegan@citrix.com>
Diffstat (limited to 'xen/include/asm-x86')
-rw-r--r--xen/include/asm-x86/hvm/svm/emulate.h5
-rw-r--r--xen/include/asm-x86/hvm/svm/nestedsvm.h129
-rw-r--r--xen/include/asm-x86/hvm/svm/svm.h6
-rw-r--r--xen/include/asm-x86/hvm/svm/svmdebug.h30
-rw-r--r--xen/include/asm-x86/hvm/svm/vmcb.h3
-rw-r--r--xen/include/asm-x86/hvm/vcpu.h2
6 files changed, 173 insertions, 2 deletions
diff --git a/xen/include/asm-x86/hvm/svm/emulate.h b/xen/include/asm-x86/hvm/svm/emulate.h
index 68d6d4972c..78e9dd0a68 100644
--- a/xen/include/asm-x86/hvm/svm/emulate.h
+++ b/xen/include/asm-x86/hvm/svm/emulate.h
@@ -33,6 +33,11 @@ enum instruction_index {
INSTR_RDTSC,
INSTR_PAUSE,
INSTR_XSETBV,
+ INSTR_VMRUN,
+ INSTR_VMLOAD,
+ INSTR_VMSAVE,
+ INSTR_STGI,
+ INSTR_CLGI,
INSTR_MAX_COUNT /* Must be last - Number of instructions supported */
};
diff --git a/xen/include/asm-x86/hvm/svm/nestedsvm.h b/xen/include/asm-x86/hvm/svm/nestedsvm.h
new file mode 100644
index 0000000000..5f6fd6cfd2
--- /dev/null
+++ b/xen/include/asm-x86/hvm/svm/nestedsvm.h
@@ -0,0 +1,129 @@
+/*
+ * nestedsvm.h: Nested Virtualization
+ * Copyright (c) 2011, Advanced Micro Devices, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+#ifndef __ASM_X86_HVM_SVM_NESTEDSVM_H__
+#define __ASM_X86_HVM_SVM_NESTEDSVM_H__
+
+#include <asm/config.h>
+#include <asm/hvm/hvm.h>
+#include <asm/hvm/svm/vmcb.h>
+
+struct nestedsvm {
+ uint64_t ns_msr_hsavepa; /* MSR HSAVE_PA value */
+
+ /* l1 guest physical address of virtual vmcb used by prior VMRUN.
+ * Needed for VMCB Cleanbit emulation.
+ */
+ uint64_t ns_ovvmcb_pa;
+
+ /* Cached real intercepts of the l2 guest */
+ uint32_t ns_cr_intercepts;
+ uint32_t ns_dr_intercepts;
+ uint32_t ns_exception_intercepts;
+ uint32_t ns_general1_intercepts;
+ uint32_t ns_general2_intercepts;
+
+ /* Cached real lbr of the l2 guest */
+ lbrctrl_t ns_lbr_control;
+
+ /* Cached real MSR permission bitmaps of the l2 guest */
+ unsigned long *ns_cached_msrpm;
+ /* Merged MSR permission bitmap */
+ unsigned long *ns_merged_msrpm;
+
+ /* guest physical address of virtual io permission map */
+ paddr_t ns_iomap_pa, ns_oiomap_pa;
+ /* Shadow io permission map */
+ unsigned long *ns_iomap;
+
+ /* Cache guest cr3/host cr3 the guest sets up for the l2 guest.
+ * Used by Shadow-on-Shadow and Nested-on-Nested.
+ * ns_vmcb_guestcr3: in l2 guest physical address space and points to
+ * the l2 guest page table
+ * ns_vmcb_hostcr3: in l1 guest physical address space and points to
+ * the l1 guest nested page table
+ */
+ uint64_t ns_vmcb_guestcr3, ns_vmcb_hostcr3;
+ uint32_t ns_guest_asid;
+
+ bool_t ns_hap_enabled;
+
+ /* Only meaningful when vmexit_pending flag is set */
+ struct {
+ uint64_t exitcode; /* native exitcode to inject into l1 guest */
+ uint64_t exitinfo1; /* additional information to the exitcode */
+ uint64_t exitinfo2; /* additional information to the exitcode */
+ } ns_vmexit;
+ union {
+ uint32_t bytes;
+ struct {
+ uint32_t rflagsif: 1;
+ uint32_t vintrmask: 1;
+ uint32_t reserved: 30;
+ } fields;
+ } ns_hostflags;
+};
+
+#define vcpu_nestedsvm(v) (vcpu_nestedhvm(v).u.nsvm)
+
+/* True when l1 guest enabled SVM in EFER */
+#define hvm_svm_enabled(v) \
+ (!!((v)->arch.hvm_vcpu.guest_efer & EFER_SVME))
+
+int nestedsvm_vmcb_map(struct vcpu *v, uint64_t vmcbaddr);
+void nestedsvm_vmexit_defer(struct vcpu *v,
+ uint64_t exitcode, uint64_t exitinfo1, uint64_t exitinfo2);
+enum nestedhvm_vmexits
+nestedsvm_vmexit_n2n1(struct vcpu *v, struct cpu_user_regs *regs);
+enum nestedhvm_vmexits
+nestedsvm_check_intercepts(struct vcpu *v, struct cpu_user_regs *regs,
+ uint64_t exitcode);
+
+/* Interface methods */
+int nsvm_vcpu_destroy(struct vcpu *v);
+int nsvm_vcpu_initialise(struct vcpu *v);
+int nsvm_vcpu_reset(struct vcpu *v);
+int nsvm_vcpu_hostrestore(struct vcpu *v, struct cpu_user_regs *regs);
+int nsvm_vcpu_vmrun(struct vcpu *v, struct cpu_user_regs *regs);
+int nsvm_vcpu_vmexit_inject(struct vcpu *v, struct cpu_user_regs *regs,
+ uint64_t exitcode);
+int nsvm_vcpu_vmexit_trap(struct vcpu *v, unsigned int trapnr,
+ int errcode, unsigned long cr2);
+uint64_t nsvm_vcpu_guestcr3(struct vcpu *v);
+uint64_t nsvm_vcpu_hostcr3(struct vcpu *v);
+uint32_t nsvm_vcpu_asid(struct vcpu *v);
+int nsvm_vmcb_guest_intercepts_exitcode(struct vcpu *v,
+ struct cpu_user_regs *regs, uint64_t exitcode);
+int nsvm_vmcb_guest_intercepts_trap(struct vcpu *v, unsigned int trapnr);
+bool_t nsvm_vmcb_hap_enabled(struct vcpu *v);
+
+/* MSRs */
+int nsvm_rdmsr(struct vcpu *v, unsigned int msr, uint64_t *msr_content);
+int nsvm_wrmsr(struct vcpu *v, unsigned int msr, uint64_t msr_content);
+
+#endif /* ASM_X86_HVM_SVM_NESTEDSVM_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-x86/hvm/svm/svm.h b/xen/include/asm-x86/hvm/svm/svm.h
index 8cd87dfcfe..eb3b01f1cd 100644
--- a/xen/include/asm-x86/hvm/svm/svm.h
+++ b/xen/include/asm-x86/hvm/svm/svm.h
@@ -29,8 +29,6 @@
#include <asm/i387.h>
#include <asm/hvm/vpmu.h>
-void svm_dump_vmcb(const char *from, struct vmcb_struct *vmcb);
-
#define SVM_REG_EAX (0)
#define SVM_REG_ECX (1)
#define SVM_REG_EDX (2)
@@ -62,6 +60,8 @@ static inline void svm_vmsave(void *vmcb)
: : "a" (__pa(vmcb)) : "memory" );
}
+unsigned long *svm_msrbit(unsigned long *msr_bitmap, uint32_t msr);
+
extern u32 svm_feature_flags;
#define SVM_FEATURE_NPT 0 /* Nested page table support */
@@ -82,4 +82,6 @@ extern u32 svm_feature_flags;
#define cpu_has_svm_cleanbits cpu_has_svm_feature(SVM_FEATURE_VMCBCLEAN)
#define cpu_has_pause_filter cpu_has_svm_feature(SVM_FEATURE_PAUSEFILTER)
+#define SVM_PAUSEFILTER_INIT 3000
+
#endif /* __ASM_X86_HVM_SVM_H__ */
diff --git a/xen/include/asm-x86/hvm/svm/svmdebug.h b/xen/include/asm-x86/hvm/svm/svmdebug.h
new file mode 100644
index 0000000000..7df17fe77b
--- /dev/null
+++ b/xen/include/asm-x86/hvm/svm/svmdebug.h
@@ -0,0 +1,30 @@
+/*
+ * svmdebug.h: SVM related debug defintions
+ * Copyright (c) 2011, AMD Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#ifndef __ASM_X86_HVM_SVM_SVMDEBUG_H__
+#define __ASM_X86_HVM_SVM_SVMDEBUG_H__
+
+#include <asm/types.h>
+#include <asm/hvm/svm/vmcb.h>
+
+void svm_vmcb_dump(const char *from, struct vmcb_struct *vmcb);
+bool_t svm_vmcb_isvalid(const char *from, struct vmcb_struct *vmcb,
+ bool_t verbose);
+
+#endif /* __ASM_X86_HVM_SVM_SVMDEBUG_H__ */
diff --git a/xen/include/asm-x86/hvm/svm/vmcb.h b/xen/include/asm-x86/hvm/svm/vmcb.h
index 5995de3017..d832216409 100644
--- a/xen/include/asm-x86/hvm/svm/vmcb.h
+++ b/xen/include/asm-x86/hvm/svm/vmcb.h
@@ -398,6 +398,9 @@ typedef union
} fields;
} __attribute__ ((packed)) vmcbcleanbits_t;
+#define IOPM_SIZE (12 * 1024)
+#define MSRPM_SIZE (8 * 1024)
+
struct vmcb_struct {
u32 _cr_intercepts; /* offset 0x00 - cleanbit 0 */
u32 _dr_intercepts; /* offset 0x04 - cleanbit 0 */
diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h
index e5d26c9f22..a5e3401fe0 100644
--- a/xen/include/asm-x86/hvm/vcpu.h
+++ b/xen/include/asm-x86/hvm/vcpu.h
@@ -25,6 +25,7 @@
#include <asm/hvm/vlapic.h>
#include <asm/hvm/vmx/vmcs.h>
#include <asm/hvm/svm/vmcb.h>
+#include <asm/hvm/svm/nestedsvm.h>
#include <asm/mtrr.h>
enum hvm_io_state {
@@ -50,6 +51,7 @@ struct nestedvcpu {
/* SVM/VMX arch specific */
union {
+ struct nestedsvm nsvm;
} u;
bool_t nv_flushp2m; /* True, when p2m table must be flushed */