Re: [PATCH 2/2] Nested VMX patch 4 implements vmread and vmwrite
Avi Kivity a...@redhat.com wrote on 02/09/2009 23:15:40: From: Avi Kivity a...@redhat.com 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_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
[PATCH 2/2] Nested VMX patch 4 implements vmread and vmwrite
From: Orit Wasserman or...@il.ibm.com --- 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); +
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); +