# HG changeset patch # User cegger # Date 1274774456 -7200 Data structures for Nested Virtualization diff -r 8dd8474427c6 -r 9dd987bc025b xen/arch/x86/hvm/svm/vmcb.c --- a/xen/arch/x86/hvm/svm/vmcb.c +++ b/xen/arch/x86/hvm/svm/vmcb.c @@ -40,9 +40,6 @@ extern int svm_dbg_on; -#define IOPM_SIZE (12 * 1024) -#define MSRPM_SIZE (8 * 1024) - struct vmcb_struct *alloc_vmcb(void) { struct vmcb_struct *vmcb; diff -r 8dd8474427c6 -r 9dd987bc025b xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -49,7 +49,8 @@ enum hvm_intblk { hvm_intblk_shadow, /* MOV-SS or STI shadow */ hvm_intblk_rflags_ie, /* RFLAGS.IE == 0 */ hvm_intblk_tpr, /* LAPIC TPR too high */ - hvm_intblk_nmi_iret /* NMI blocked until IRET */ + hvm_intblk_nmi_iret, /* NMI blocked until IRET */ + hvm_intblk_gif, /* GIF cleared */ }; /* These happen to be the same as the VMX interrupt shadow definitions. */ @@ -169,6 +170,8 @@ int hvm_girq_dest_2_vcpu_id(struct domai (hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PAE)) #define hvm_nx_enabled(v) \ (!!((v)->arch.hvm_vcpu.guest_efer & EFER_NX)) +#define hvm_svm_enabled(v) \ + (!!((v)->arch.hvm_vcpu.guest_efer & EFER_SVME)) #ifdef __x86_64__ #define hvm_long_mode_enabled(v) \ diff -r 8dd8474427c6 -r 9dd987bc025b xen/include/asm-x86/hvm/svm/vmcb.h --- a/xen/include/asm-x86/hvm/svm/vmcb.h +++ b/xen/include/asm-x86/hvm/svm/vmcb.h @@ -364,6 +364,9 @@ typedef union } fields; } __attribute__ ((packed)) lbrctrl_t; +#define IOPM_SIZE (12 * 1024) +#define MSRPM_SIZE (8 * 1024) + struct vmcb_struct { u32 cr_intercepts; /* offset 0x00 */ u32 dr_intercepts; /* offset 0x04 */ diff -r 8dd8474427c6 -r 9dd987bc025b xen/include/asm-x86/hvm/vcpu.h --- a/xen/include/asm-x86/hvm/vcpu.h +++ b/xen/include/asm-x86/hvm/vcpu.h @@ -35,6 +35,60 @@ enum hvm_io_state { HVMIO_completed }; +struct nestedhvm { + bool_t nh_guestmode; /* vcpu in guestmode? */ + bool_t nh_gif; /* vcpu's GIF */ + struct vmcb_struct *nh_vmcb; + /* vmcb address of 1st level guest, needed for VMEXIT */ + uint64_t nh_vmcbaddr; + void *nh_hostsave; + uint64_t nh_msr_hsavepa; /* MSR HSAVE_PA value */ + + /* Cached real intercepts of the nested guest */ + uint32_t nh_cr_intercepts; + uint32_t nh_dr_intercepts; + uint32_t nh_exception_intercepts; + uint32_t nh_general1_intercepts; + uint32_t nh_general2_intercepts; + + /* Cached real lbr of the nested guest */ + lbrctrl_t nh_lbr_control; + + /* Cached real MSR permission bitmaps of the nested guest */ + unsigned long *nh_msrpm; + + /* Cached cr3/hcr3 the guest sets up for the nested guest. + * Used by Shadow-on-Shadow and Nested-on-Nested. */ + uint64_t nh_vmcb_cr3, nh_vmcb_hcr3; + uint32_t nh_guest_asid, nh_old_guest_asid; + bool_t nh_tlb_control; + struct p2m_domain *nh_p2m; /* used p2m table for this vcpu */ + + /* Emulate cr0/4 for mov-from/to-cr0/4 instructions. + * Emulate cr for hypervisor's which don't + * intercept cr read/writes (Hyper-V). + */ + uint64_t nh_cr[5]; + + /* Only meaningful when forcevmexit flag is set */ + uint64_t nh_forcevmexit_exitcode; + union { + uint32_t bytes; + struct { + uint32_t rflagsif : 1; + uint32_t vintrmask : 1; + uint32_t forcevmexit : 1; + uint32_t vmrun : 1; + uint32_t reserved : 28; + } fields; + } nh_hostflags; + + bool_t nh_hap_enabled; +}; + +#define VCPU_HVM(v) ((v)->arch.hvm_vcpu) +#define VCPU_NESTEDHVM(v) (VCPU_HVM((v)).nestedhvm) + struct hvm_vcpu { /* Guest control-register and EFER values, just as the guest sees them. */ unsigned long guest_cr[5]; @@ -86,6 +140,8 @@ struct hvm_vcpu { struct tasklet assert_evtchn_irq_tasklet; + struct nestedhvm nestedhvm; + struct mtrr_state mtrr; u64 pat_cr;