Re: [PATCH 2/2] Nested VMX patch 4 implements vmread and vmwrite

2009-09-03 Thread Orit Wasserman


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

2009-09-02 Thread Avi Kivity

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

2009-09-02 Thread oritw
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