diff options
author | cegger <none@none> | 2011-03-09 12:36:05 +0100 |
---|---|---|
committer | cegger <none@none> | 2011-03-09 12:36:05 +0100 |
commit | 9a779e4fc1619a61c407d4db8934c8732a6c2d02 (patch) | |
tree | 7f5f51e5b821fa90d1c2c01f4aa0eaad5f27c3f5 /xen/include/asm-x86/hvm | |
parent | 5120a76fad77858d2ac2cbcce8a3dd3500d25e87 (diff) | |
download | xen-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/hvm')
-rw-r--r-- | xen/include/asm-x86/hvm/svm/emulate.h | 5 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/svm/nestedsvm.h | 129 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/svm/svm.h | 6 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/svm/svmdebug.h | 30 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/svm/vmcb.h | 3 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/vcpu.h | 2 |
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 */ |