Support for GUEST_SMBASE vmcs field for nested virtualization
PATCH 1/1 Support for GUEST_SMBASE vmcs field for nested virtualization
Hi,
the following patch adds support for the GUEST_SMBASE field in the VMCS for the case of nested virtualization. There are hypervisors that try to access that mandatory field. The patch avoids returning a "unsupported vmcs field" error to the L1 hypervisor by adding the GUEST_SMBASE field into the vmcs12 struct.
Regards,
Matthias.
--- arch/x86/include/asm/vmx.h | 1 + arch/x86/kvm/vmx.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-)
arch/x86/include/asm/vmx.h +1 -0
@@ -194,6 +194,7 @@ enum vmcs_field {GUEST_TR_AR_BYTES =0x00004822 ,GUEST_INTERRUPTIBILITY_INFO =0x00004824 ,GUEST_ACTIVITY_STATE =0X00004826 , +GUEST_SMBASE =0x00004828 ,GUEST_SYSENTER_CS =0x0000482A ,HOST_IA32_SYSENTER_CS =0x00004c00 , CR0_GUEST_HOST_MASK = 0x00006000,
arch/x86/kvm/vmx.c +5 -1
@@ -294,7 +294,8 @@ struct __packed vmcs12 {u32 guest_activity_state;u32 guest_sysenter_cs;u32 host_ia32_sysenter_cs; -u32 padding32[8 ];/* room for future expansion */ +u32 guest_smbase; +u32 padding32[7 ];/* room for future expansion */ u16 virtual_processor_id;u16 guest_es_selector;u16 guest_cs_selector;
@@ -556,6 +557,7 @@ static unsigned short vmcs_field_to_offset_table[] = {FIELD (GUEST_TR_BASE , guest_tr_base),FIELD (GUEST_GDTR_BASE , guest_gdtr_base),FIELD (GUEST_IDTR_BASE , guest_idtr_base), +FIELD (GUEST_SMBASE , guest_smbase),FIELD (GUEST_DR7 , guest_dr7),FIELD (GUEST_RSP , guest_rsp), FIELD(GUEST_RIP, guest_rip),
@@ -6536,6 +6538,7 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)vmcs_write32 (GUEST_INTERRUPTIBILITY_INFO , vmcs12->guest_interruptibility_info);vmcs_write32 (GUEST_ACTIVITY_STATE , vmcs12->guest_activity_state); +vmcs_write32 (GUEST_SMBASE , vmcs12->guest_smbase);vmcs_write32 (GUEST_SYSENTER_CS , vmcs12->guest_sysenter_cs);vmcs_writel (GUEST_DR7 , vmcs12->guest_dr7);vmcs_writel (GUEST_RFLAGS , vmcs12->guest_rflags);
@@ -6937,6 +6940,7 @@ void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) vmcs12->guest_idtr_base =vmcs_readl (GUEST_IDTR_BASE ); vmcs12->guest_activity_state =vmcs_read32 (GUEST_ACTIVITY_STATE ); + vmcs12->guest_smbase =vmcs_read32 (GUEST_SMBASE ); vmcs12->guest_interruptibility_info =vmcs_read32 (GUEST_INTERRUPTIBILITY_INFO ); vmcs12->guest_pending_dbg_exceptions =
Signature · 11 lines
1.7.9.5 -- Dipl.-Inf. Matthias Lange <[email protected]> Security in Telecommunications TU Berlin / Telekom Innovation Laboratories Ernst-Reuter-Platz 7, 10587 Berlin Phone: +49 - 30 - 8353 58 553 Mobile: +49 - 160 - 587 28 07 Web: http://www.t-labs.tu-berlin.de/sect
Quoted 26 lines · Matthias Lange
Hi,
the following patch adds support for the
GUEST_SMBASEfield in the VMCS for the case of nested virtualization. There are hypervisors that try to access that mandatory field. The patch avoids returning a "unsupported vmcs field" error to the L1 hypervisor by adding theGUEST_SMBASEfield into the vmcs12 struct.arch/x86/include/asm/vmx.h +1
-0@@ -194,6 +194,7 @@ enum vmcs_field {GUEST_TR_AR_BYTES =0x00004822 ,GUEST_INTERRUPTIBILITY_INFO =0x00004824 ,GUEST_ACTIVITY_STATE =0X00004826 , +GUEST_SMBASE =0x00004828 ,GUEST_SYSENTER_CS =0x0000482A ,HOST_IA32_SYSENTER_CS =0x00004c00 , CR0_GUEST_HOST_MASK = 0x00006000,arch/x86/kvm/vmx.c +0
-0
arch/x86/kvm/vmx.c struct __packed vmcs12 { · line 301
Quoted 9 lines
arch/x86/kvm/vmx.c +2
-1@@ -294,7 +294,8 @@ struct __packed vmcs12 {u32 guest_activity_state;u32 guest_sysenter_cs;u32 host_ia32_sysenter_cs; -u32 padding32[8 ];/* room for future expansion */ +u32 guest_smbase; +u32 padding32[7 ];/* room for future expansion */ u16 virtual_processor_id;u16 guest_es_selector;u16 guest_cs_selector;
This is okay now.
Quoted 9 lines
arch/x86/kvm/vmx.c +1
-0@@ -6536,6 +6538,7 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)vmcs_write32 (GUEST_INTERRUPTIBILITY_INFO , vmcs12->guest_interruptibility_info);vmcs_write32 (GUEST_ACTIVITY_STATE , vmcs12->guest_activity_state); +vmcs_write32 (GUEST_SMBASE , vmcs12->guest_smbase);vmcs_write32 (GUEST_SYSENTER_CS , vmcs12->guest_sysenter_cs);vmcs_writel (GUEST_DR7 , vmcs12->guest_dr7);vmcs_writel (GUEST_RFLAGS , vmcs12->guest_rflags);
arch/x86/kvm/vmx.c void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) · line 6946
Quoted 7 lines
arch/x86/kvm/vmx.c +1
-0@@ -6937,6 +6940,7 @@ void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) vmcs12->guest_idtr_base =vmcs_readl (GUEST_IDTR_BASE ); vmcs12->guest_activity_state =vmcs_read32 (GUEST_ACTIVITY_STATE ); + vmcs12->guest_smbase =vmcs_read32 (GUEST_SMBASE ); vmcs12->guest_interruptibility_info =vmcs_read32 (GUEST_INTERRUPTIBILITY_INFO ); vmcs12->guest_pending_dbg_exceptions =
I missed this earlier: I don't think we need this. If we do implement SMM, anything touching SMBASE (SMI delivery and RSM) will be emulated, so we don't need anything in vmcs02 (just vmcs12, which is handled by the code above).
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 12 lines · Avi Kivity
Quoted 11 lines · Matthias Lange
(quoted diff) +1
-0@@ -6536,6 +6538,7 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, vmcs12->guest_interruptibility_info); vmcs_write32(GUEST_ACTIVITY_STATE, vmcs12->guest_activity_state); + vmcs_write32(GUEST_SMBASE, vmcs12->guest_smbase); vmcs_write32(GUEST_SYSENTER_CS, vmcs12->guest_sysenter_cs); vmcs_writel(GUEST_DR7, vmcs12->guest_dr7); vmcs_writel(GUEST_RFLAGS, vmcs12->guest_rflags);@@ -6937,6 +6940,7 @@ void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) vmcs12->guest_idtr_base = vmcs_readl(GUEST_IDTR_BASE);
Quoted 11 lines
Review void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) · line 6946
Quoted 5 lines
(quoted diff) +1
-0vmcs12->guest_activity_state = vmcs_read32(GUEST_ACTIVITY_STATE); + vmcs12->guest_smbase = vmcs_read32(GUEST_SMBASE); vmcs12->guest_interruptibility_info = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); vmcs12->guest_pending_dbg_exceptions =I missed this earlier: I don't think we need this. If we do implement SMM, anything touching SMBASE (SMI delivery and RSM) will be emulated, so we don't need anything in vmcs02 (just vmcs12, which is handled by the code above).
I updated the patch according to your comments.
Matthias.
Signature · 7 lines
Dipl.-Inf. Matthias Lange <[email protected]> Security in Telecommunications TU Berlin / Telekom Innovation Laboratories Ernst-Reuter-Platz 7, 10587 Berlin Phone: +49 - 30 - 8353 58 553 Mobile: +49 - 160 - 587 28 07 Web: http://www.t-labs.tu-berlin.de/sect
Quoted 1 line
From
bdcb7c52a5f4202d9322cc85a88a83af596cf11dMon Sep 17 00:00:00 2001
From: Matthias Lange <[email protected]>
Date: Fri, 18 May 2012 10:58:00 +0200
Subject: [PATCH] Add support for the GUEST_SMBASE VMCS field for Intel VT-x
in the case of nested virtualization. - I take a slot from
the padding32 area to insert the field into the vmcs12
struct
--- arch/x86/include/asm/vmx.h | 1 + arch/x86/kvm/vmx.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-)
arch/x86/include/asm/vmx.h +1 -0
@@ -194,6 +194,7 @@ enum vmcs_field {GUEST_TR_AR_BYTES =0x00004822 ,GUEST_INTERRUPTIBILITY_INFO =0x00004824 ,GUEST_ACTIVITY_STATE =0X00004826 , +GUEST_SMBASE =0x00004828 ,GUEST_SYSENTER_CS =0x0000482A ,HOST_IA32_SYSENTER_CS =0x00004c00 , CR0_GUEST_HOST_MASK = 0x00006000,
arch/x86/kvm/vmx.c +4 -1
@@ -294,7 +294,8 @@ struct __packed vmcs12 {u32 guest_activity_state;u32 guest_sysenter_cs;u32 host_ia32_sysenter_cs; -u32 padding32[8 ];/* room for future expansion */ +u32 guest_smbase; +u32 padding32[7 ];/* room for future expansion */ u16 virtual_processor_id;u16 guest_es_selector;u16 guest_cs_selector;
@@ -556,6 +557,7 @@ static unsigned short vmcs_field_to_offset_table[] = {FIELD (GUEST_TR_BASE , guest_tr_base),FIELD (GUEST_GDTR_BASE , guest_gdtr_base),FIELD (GUEST_IDTR_BASE , guest_idtr_base), +FIELD (GUEST_SMBASE , guest_smbase),FIELD (GUEST_DR7 , guest_dr7),FIELD (GUEST_RSP , guest_rsp), FIELD(GUEST_RIP, guest_rip),
@@ -6937,6 +6939,7 @@ void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) vmcs12->guest_idtr_base =vmcs_readl (GUEST_IDTR_BASE ); vmcs12->guest_activity_state =vmcs_read32 (GUEST_ACTIVITY_STATE ); + vmcs12->guest_smbase =vmcs_read32 (GUEST_SMBASE ); vmcs12->guest_interruptibility_info =vmcs_read32 (GUEST_INTERRUPTIBILITY_INFO ); vmcs12->guest_pending_dbg_exceptions =
Signature · 1 line
1.7.9.5