# HG changeset patch # User cegger # Date 1280925496 -7200 Data structures for Nested Virtualization diff -r e75662c48917 -r 79a75ef7b7d0 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 e75662c48917 -r 79a75ef7b7d0 xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -52,7 +52,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. */ @@ -180,6 +181,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)) #define hvm_hap_has_1gb(d) \ (hvm_funcs.hap_capabilities & HVM_HAP_SUPERPAGE_1GB) diff -r e75662c48917 -r 79a75ef7b7d0 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 e75662c48917 -r 79a75ef7b7d0 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,57 @@ enum hvm_io_state { HVMIO_completed }; +struct nestedhvm { + bool_t nh_gif; /* vcpu's GIF, always true on VMX */ + bool_t nh_guestmode; /* vcpu in guestmode? */ + void *nh_vm; /* VMCB/VMCS */ + size_t nh_vmsize; /* size of VMCB/VMCS */ + + /* guest vm address of 1st level guest, needed for VMEXIT */ + uint64_t nh_vmaddr; + uint64_t nh_vmmaxaddr; /* Maximum supported address */ + void *nh_hostsave; + + void *nh_arch; /* SVM/VMX specific data */ + size_t nh_arch_size; + + /* Cached real MSR permission bitmaps of the nested guest */ + unsigned long *nh_cached_msrpm; + size_t nh_cached_msrpm_size; + /* Merged MSR permission bitmap */ + unsigned long *nh_merged_msrpm; + size_t nh_merged_msrpm_size; + + /* 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; + bool_t nh_flushp2m; + struct p2m_domain *nh_p2m; /* used p2m table for this vcpu */ + + /* Only meaningful when forcevmexit flag is set */ + struct { + uint64_t exitcode; /* generic exitcode */ + uint64_t exitinfo1; /* additional information to the exitcode */ + uint64_t exitinfo2; /* additional information to the exitcode */ + } nh_forcevmexit; + union { + uint32_t bytes; + struct { + uint32_t rflagsif : 1; + uint32_t vintrmask : 1; /* always cleared on VMX */ + uint32_t forcevmexit : 1; + uint32_t vmentry : 1; /* true during vmentry/vmexit emulation */ + 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 +137,8 @@ struct hvm_vcpu { struct tasklet assert_evtchn_irq_tasklet; + struct nestedhvm nestedhvm; + struct mtrr_state mtrr; u64 pat_cr;