Re: [PATCH 2/2] Nested VMX patch 4 implements vmread and vmwrite
Avi Kivity wrote on 02/09/2009 23:15:40: > From: > > Avi Kivity > > To: > > Orit Wasserman/Haifa/i...@ibmil > > Cc: > > kvm@vger.kernel.org, Ben-Ami Yassour1/Haifa/i...@ibmil, Muli Ben- > Yehuda/Haifa/i...@ibmil, Abel Gordon/Haifa/i...@ibmil, > aligu...@us.ibm.com, mm...@us.ibm.com > > Date: > > 02/09/2009 23:15 > > Subject: > > Re: [PATCH 2/2] Nested VMX patch 4 implements vmread and vmwrite > > On 09/02/2009 06:38 PM, or...@il.ibm.com wrote: > > + > > +static void init_vmcs_field_to_offset_table(void) > > +{ > > + memset(vmcs_field_to_offset_table,0xff, > > + sizeof(vmcs_field_to_offset_table)); > > + > > + vmcs_field_to_offset_table[VIRTUAL_PROCESSOR_ID] = > > + offsetof(struct shadow_vmcs, virtual_processor_id); > > + vmcs_field_to_offset_table[GUEST_ES_SELECTOR] = > > + offsetof(struct shadow_vmcs, guest_es_selector); > > + vmcs_field_to_offset_table[GUEST_CS_SELECTOR] = > > + offsetof(struct shadow_vmcs, guest_cs_selector); > > + vmcs_field_to_offset_table[GUEST_SS_SELECTOR] = > > + offsetof(struct shadow_vmcs, guest_ss_selector); > > + vmcs_field_to_offset_table[GUEST_DS_SELECTOR] = > > + offsetof(struct shadow_vmcs, guest_ds_selector); > > + vmcs_field_to_offset_table[GUEST_FS_SELECTOR] = > > + offsetof(struct shadow_vmcs, guest_fs_selector); > > + vmcs_field_to_offset_table[GUEST_GS_SELECTOR] = > > + offsetof(struct shadow_vmcs, guest_gs_selector); > > + vmcs_field_to_offset_table[GUEST_LDTR_SELECTOR] = > > + offsetof(struct shadow_vmcs, guest_ldtr_selector); > > + vmcs_field_to_offset_table[GUEST_TR_SELECTOR] = > > + offsetof(struct shadow_vmcs, guest_tr_selector); > > + vmcs_field_to_offset_table[HOST_ES_SELECTOR] = > > + offsetof(struct shadow_vmcs, host_es_selector); > > + vmcs_field_to_offset_table[HOST_CS_SELECTOR] = > > + offsetof(struct shadow_vmcs, host_cs_selector); > > + vmcs_field_to_offset_table[HOST_SS_SELECTOR] = > > + offsetof(struct shadow_vmcs, host_ss_selector); > > + vmcs_field_to_offset_table[HOST_DS_SELECTOR] = > > + offsetof(struct shadow_vmcs, host_ds_selector); > > + vmcs_field_to_offset_table[HOST_FS_SELECTOR] = > > + offsetof(struct shadow_vmcs, host_fs_selector); > > + vmcs_field_to_offset_table[HOST_GS_SELECTOR] = > > + offsetof(struct shadow_vmcs, host_gs_selector); > > + vmcs_field_to_offset_table[HOST_TR_SELECTOR] = > > + offsetof(struct shadow_vmcs, host_tr_selector); > > + vmcs_field_to_offset_table[IO_BITMAP_A] = > > + offsetof(struct shadow_vmcs, io_bitmap_a); > > + vmcs_field_to_offset_table[IO_BITMAP_A_HIGH] = > > + offsetof(struct shadow_vmcs, io_bitmap_a)+4; > > + vmcs_field_to_offset_table[IO_BITMAP_B] = > > + offsetof(struct shadow_vmcs, io_bitmap_b); > > + vmcs_field_to_offset_table[IO_BITMAP_B_HIGH] = > > + offsetof(struct shadow_vmcs, io_bitmap_b)+4; > > + vmcs_field_to_offset_table[MSR_BITMAP] = > > + offsetof(struct shadow_vmcs, msr_bitmap); > > + vmcs_field_to_offset_table[MSR_BITMAP_HIGH] = > > + offsetof(struct shadow_vmcs, msr_bitmap)+4; > > + vmcs_field_to_offset_table[VM_EXIT_MSR_STORE_ADDR] = > > + offsetof(struct shadow_vmcs, vm_exit_msr_store_addr); > > + vmcs_field_to_offset_table[VM_EXIT_MSR_STORE_ADDR_HIGH] = > > + offsetof(struct shadow_vmcs, vm_exit_msr_store_addr)+4; > > + vmcs_field_to_offset_table[VM_EXIT_MSR_LOAD_ADDR] = > > + offsetof(struct shadow_vmcs, vm_exit_msr_load_addr); > > + vmcs_field_to_offset_table[VM_EXIT_MSR_LOAD_ADDR_HIGH] = > > + offsetof(struct shadow_vmcs, vm_exit_msr_load_addr)+4; > > + vmcs_field_to_offset_table[VM_ENTRY_MSR_LOAD_ADDR] = > > + offsetof(struct shadow_vmcs, vm_entry_msr_load_addr); > > + vmcs_field_to_offset_table[VM_ENTRY_MSR_LOAD_ADDR_HIGH] = > > + offsetof(struct shadow_vmcs, vm_entry_msr_load_addr)+4; > > + vmcs_field_to_offset_table[TSC_OFFSET] = > > + offsetof(struct shadow_vmcs, tsc_offset); > > + vmcs_field_to_offset_table[TSC_OFFSET_HIGH] = > > + offsetof(struct shadow_vmcs, tsc_offset)+4; > > + vmcs_field_to_offset_table[VIRTUAL_APIC_PAGE_ADDR] = > > + offsetof(struct shadow_vmcs, virtual_apic_page_addr); > > + vmcs_field_to_offset_table[VIRTUAL_APIC_PAGE_ADDR_HIGH] = > > + offsetof(struct shadow_vmcs, virtual_apic_page_addr)+4; > > + vmcs_field_to_offset_table[APIC_ACCESS_ADDR] = > > + offsetof(struct shadow_vmcs, apic_access_ad
Re: [PATCH 2/2] Nested VMX patch 4 implements vmread and vmwrite
On 09/02/2009 06:38 PM, or...@il.ibm.com wrote: + +static void init_vmcs_field_to_offset_table(void) +{ + memset(vmcs_field_to_offset_table,0xff, + sizeof(vmcs_field_to_offset_table)); + + vmcs_field_to_offset_table[VIRTUAL_PROCESSOR_ID] = + offsetof(struct shadow_vmcs, virtual_processor_id); + vmcs_field_to_offset_table[GUEST_ES_SELECTOR] = + offsetof(struct shadow_vmcs, guest_es_selector); + vmcs_field_to_offset_table[GUEST_CS_SELECTOR] = + offsetof(struct shadow_vmcs, guest_cs_selector); + vmcs_field_to_offset_table[GUEST_SS_SELECTOR] = + offsetof(struct shadow_vmcs, guest_ss_selector); + vmcs_field_to_offset_table[GUEST_DS_SELECTOR] = + offsetof(struct shadow_vmcs, guest_ds_selector); + vmcs_field_to_offset_table[GUEST_FS_SELECTOR] = + offsetof(struct shadow_vmcs, guest_fs_selector); + vmcs_field_to_offset_table[GUEST_GS_SELECTOR] = + offsetof(struct shadow_vmcs, guest_gs_selector); + vmcs_field_to_offset_table[GUEST_LDTR_SELECTOR] = + offsetof(struct shadow_vmcs, guest_ldtr_selector); + vmcs_field_to_offset_table[GUEST_TR_SELECTOR] = + offsetof(struct shadow_vmcs, guest_tr_selector); + vmcs_field_to_offset_table[HOST_ES_SELECTOR] = + offsetof(struct shadow_vmcs, host_es_selector); + vmcs_field_to_offset_table[HOST_CS_SELECTOR] = + offsetof(struct shadow_vmcs, host_cs_selector); + vmcs_field_to_offset_table[HOST_SS_SELECTOR] = + offsetof(struct shadow_vmcs, host_ss_selector); + vmcs_field_to_offset_table[HOST_DS_SELECTOR] = + offsetof(struct shadow_vmcs, host_ds_selector); + vmcs_field_to_offset_table[HOST_FS_SELECTOR] = + offsetof(struct shadow_vmcs, host_fs_selector); + vmcs_field_to_offset_table[HOST_GS_SELECTOR] = + offsetof(struct shadow_vmcs, host_gs_selector); + vmcs_field_to_offset_table[HOST_TR_SELECTOR] = + offsetof(struct shadow_vmcs, host_tr_selector); + vmcs_field_to_offset_table[IO_BITMAP_A] = + offsetof(struct shadow_vmcs, io_bitmap_a); + vmcs_field_to_offset_table[IO_BITMAP_A_HIGH] = + offsetof(struct shadow_vmcs, io_bitmap_a)+4; + vmcs_field_to_offset_table[IO_BITMAP_B] = + offsetof(struct shadow_vmcs, io_bitmap_b); + vmcs_field_to_offset_table[IO_BITMAP_B_HIGH] = + offsetof(struct shadow_vmcs, io_bitmap_b)+4; + vmcs_field_to_offset_table[MSR_BITMAP] = + offsetof(struct shadow_vmcs, msr_bitmap); + vmcs_field_to_offset_table[MSR_BITMAP_HIGH] = + offsetof(struct shadow_vmcs, msr_bitmap)+4; + vmcs_field_to_offset_table[VM_EXIT_MSR_STORE_ADDR] = + offsetof(struct shadow_vmcs, vm_exit_msr_store_addr); + vmcs_field_to_offset_table[VM_EXIT_MSR_STORE_ADDR_HIGH] = + offsetof(struct shadow_vmcs, vm_exit_msr_store_addr)+4; + vmcs_field_to_offset_table[VM_EXIT_MSR_LOAD_ADDR] = + offsetof(struct shadow_vmcs, vm_exit_msr_load_addr); + vmcs_field_to_offset_table[VM_EXIT_MSR_LOAD_ADDR_HIGH] = + offsetof(struct shadow_vmcs, vm_exit_msr_load_addr)+4; + vmcs_field_to_offset_table[VM_ENTRY_MSR_LOAD_ADDR] = + offsetof(struct shadow_vmcs, vm_entry_msr_load_addr); + vmcs_field_to_offset_table[VM_ENTRY_MSR_LOAD_ADDR_HIGH] = + offsetof(struct shadow_vmcs, vm_entry_msr_load_addr)+4; + vmcs_field_to_offset_table[TSC_OFFSET] = + offsetof(struct shadow_vmcs, tsc_offset); + vmcs_field_to_offset_table[TSC_OFFSET_HIGH] = + offsetof(struct shadow_vmcs, tsc_offset)+4; + vmcs_field_to_offset_table[VIRTUAL_APIC_PAGE_ADDR] = + offsetof(struct shadow_vmcs, virtual_apic_page_addr); + vmcs_field_to_offset_table[VIRTUAL_APIC_PAGE_ADDR_HIGH] = + offsetof(struct shadow_vmcs, virtual_apic_page_addr)+4; + vmcs_field_to_offset_table[APIC_ACCESS_ADDR] = + offsetof(struct shadow_vmcs, apic_access_addr); + vmcs_field_to_offset_table[APIC_ACCESS_ADDR_HIGH] = + offsetof(struct shadow_vmcs, apic_access_addr)+4; + vmcs_field_to_offset_table[EPT_POINTER] = + offsetof(struct shadow_vmcs, ept_pointer); + vmcs_field_to_offset_table[EPT_POINTER_HIGH] = + offsetof(struct shadow_vmcs, ept_pointer)+4; + vmcs_field_to_offset_table[GUEST_PHYSICAL_ADDRESS] = + offsetof(struct shadow_vmcs, guest_physical_address); + vmcs_field_to_offset_table[GUEST_PHYSICAL_ADDRESS_HIGH] = + offsetof(struct shadow_vmcs, guest_physical_address)+4; + vmcs_field_to_offset_table[VMCS_LINK_POINTER] = + offsetof(struct shadow_vmcs, vmcs_link_pointer); + vmcs_field_to_offset_table[
[PATCH 2/2] Nested VMX patch 4 implements vmread and vmwrite
From: Orit Wasserman --- arch/x86/kvm/vmx.c | 556 +++- 1 files changed, 554 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 5ab07a0..2453c67 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -206,6 +206,21 @@ struct __attribute__ ((__packed__)) level_state { int launched; }; +enum vmcs_field_type { + VMCS_FIELD_TYPE_U16 = 0, + VMCS_FIELD_TYPE_U64 = 1, + VMCS_FIELD_TYPE_U32 = 2, + VMCS_FIELD_TYPE_ULONG = 3 +}; + +#define VMCS_FIELD_LENGTH_OFFSET 13 +#define VMCS_FIELD_LENGTH_MASK 0x6000 + +static inline int vmcs_field_length(unsigned long field) +{ + return (VMCS_FIELD_LENGTH_MASK & field) >> 13; +} + struct vmcs { u32 revision_id; u32 abort; @@ -287,6 +302,411 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) return container_of(vcpu, struct vcpu_vmx, vcpu); } +static unsigned short vmcs_field_to_offset_table[HOST_RIP+1]; + +static void init_vmcs_field_to_offset_table(void) +{ + memset(vmcs_field_to_offset_table,0xff, + sizeof(vmcs_field_to_offset_table)); + + vmcs_field_to_offset_table[VIRTUAL_PROCESSOR_ID] = + offsetof(struct shadow_vmcs, virtual_processor_id); + vmcs_field_to_offset_table[GUEST_ES_SELECTOR] = + offsetof(struct shadow_vmcs, guest_es_selector); + vmcs_field_to_offset_table[GUEST_CS_SELECTOR] = + offsetof(struct shadow_vmcs, guest_cs_selector); + vmcs_field_to_offset_table[GUEST_SS_SELECTOR] = + offsetof(struct shadow_vmcs, guest_ss_selector); + vmcs_field_to_offset_table[GUEST_DS_SELECTOR] = + offsetof(struct shadow_vmcs, guest_ds_selector); + vmcs_field_to_offset_table[GUEST_FS_SELECTOR] = + offsetof(struct shadow_vmcs, guest_fs_selector); + vmcs_field_to_offset_table[GUEST_GS_SELECTOR] = + offsetof(struct shadow_vmcs, guest_gs_selector); + vmcs_field_to_offset_table[GUEST_LDTR_SELECTOR] = + offsetof(struct shadow_vmcs, guest_ldtr_selector); + vmcs_field_to_offset_table[GUEST_TR_SELECTOR] = + offsetof(struct shadow_vmcs, guest_tr_selector); + vmcs_field_to_offset_table[HOST_ES_SELECTOR] = + offsetof(struct shadow_vmcs, host_es_selector); + vmcs_field_to_offset_table[HOST_CS_SELECTOR] = + offsetof(struct shadow_vmcs, host_cs_selector); + vmcs_field_to_offset_table[HOST_SS_SELECTOR] = + offsetof(struct shadow_vmcs, host_ss_selector); + vmcs_field_to_offset_table[HOST_DS_SELECTOR] = + offsetof(struct shadow_vmcs, host_ds_selector); + vmcs_field_to_offset_table[HOST_FS_SELECTOR] = + offsetof(struct shadow_vmcs, host_fs_selector); + vmcs_field_to_offset_table[HOST_GS_SELECTOR] = + offsetof(struct shadow_vmcs, host_gs_selector); + vmcs_field_to_offset_table[HOST_TR_SELECTOR] = + offsetof(struct shadow_vmcs, host_tr_selector); + vmcs_field_to_offset_table[IO_BITMAP_A] = + offsetof(struct shadow_vmcs, io_bitmap_a); + vmcs_field_to_offset_table[IO_BITMAP_A_HIGH] = + offsetof(struct shadow_vmcs, io_bitmap_a)+4; + vmcs_field_to_offset_table[IO_BITMAP_B] = + offsetof(struct shadow_vmcs, io_bitmap_b); + vmcs_field_to_offset_table[IO_BITMAP_B_HIGH] = + offsetof(struct shadow_vmcs, io_bitmap_b)+4; + vmcs_field_to_offset_table[MSR_BITMAP] = + offsetof(struct shadow_vmcs, msr_bitmap); + vmcs_field_to_offset_table[MSR_BITMAP_HIGH] = + offsetof(struct shadow_vmcs, msr_bitmap)+4; + vmcs_field_to_offset_table[VM_EXIT_MSR_STORE_ADDR] = + offsetof(struct shadow_vmcs, vm_exit_msr_store_addr); + vmcs_field_to_offset_table[VM_EXIT_MSR_STORE_ADDR_HIGH] = + offsetof(struct shadow_vmcs, vm_exit_msr_store_addr)+4; + vmcs_field_to_offset_table[VM_EXIT_MSR_LOAD_ADDR] = + offsetof(struct shadow_vmcs, vm_exit_msr_load_addr); + vmcs_field_to_offset_table[VM_EXIT_MSR_LOAD_ADDR_HIGH] = + offsetof(struct shadow_vmcs, vm_exit_msr_load_addr)+4; + vmcs_field_to_offset_table[VM_ENTRY_MSR_LOAD_ADDR] = + offsetof(struct shadow_vmcs, vm_entry_msr_load_addr); + vmcs_field_to_offset_table[VM_ENTRY_MSR_LOAD_ADDR_HIGH] = + offsetof(struct shadow_vmcs, vm_entry_msr_load_addr)+4; + vmcs_field_to_offset_table[TSC_OFFSET] = + offsetof(struct shadow_vmcs, tsc_offset); + vmcs_field_to_offset_table[TSC_OFFSET_HIGH] = + offsetof(struct shadow_vmcs, tsc_offset)+4; + vmcs_field_to_offset_table[VIRTUAL_APIC_PAGE_ADDR] = + offsetof(struct shadow_vmcs, virtual_apic_page_addr); + vmcs_field_to_offset_table[VIRTUAL_APIC_PAGE_ADDR_HI