diff mbox

[6/7] KVM: nVMX: Implement support for EFER saving on VM-exit

Message ID a3d79d60eb1ed8c15b69f351a6ffd5addd62a3a1.1375638539.git.jan.kiszka@web.de (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Kiszka Aug. 4, 2013, 5:49 p.m. UTC
From: Jan Kiszka <jan.kiszka@siemens.com>

Implement and advertise VM_EXIT_SAVE_IA32_EFER. L0 traps EFER writes
unconditionally, so we always find the current L2 value in the
architectural state.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 arch/x86/kvm/vmx.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

Comments

Arthur Chunqi Li Aug. 5, 2013, 7:21 a.m. UTC | #1
On Mon, Aug 5, 2013 at 1:49 AM, Jan Kiszka <jan.kiszka@web.de> wrote:
> From: Jan Kiszka <jan.kiszka@siemens.com>
>
> Implement and advertise VM_EXIT_SAVE_IA32_EFER. L0 traps EFER writes
> unconditionally, so we always find the current L2 value in the
> architectural state.
>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  arch/x86/kvm/vmx.c |    4 +++-
>  1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 84a05b4..7208d0b 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -2203,7 +2203,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)
>         nested_vmx_exit_ctls_high = 0;
>  #endif
>         nested_vmx_exit_ctls_high |= (VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR |
> -                                     VM_EXIT_LOAD_IA32_EFER);
> +               VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER);
Here you may need to access MSR_IA32_VMX_EXIT_CTLS first to check if
host support these two features. The codes for "entry controls"
following it can achieve goals like this.

Arthur
>
>         /* entry controls */
>         rdmsr(MSR_IA32_VMX_ENTRY_CTLS,
> @@ -8113,6 +8113,8 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
>         vmcs12->guest_ia32_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL);
>         if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_PAT)
>                 vmcs12->guest_ia32_pat = vmcs_read64(GUEST_IA32_PAT);
> +       if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_EFER)
> +               vmcs12->guest_ia32_efer = vcpu->arch.efer;
>         vmcs12->guest_sysenter_cs = vmcs_read32(GUEST_SYSENTER_CS);
>         vmcs12->guest_sysenter_esp = vmcs_readl(GUEST_SYSENTER_ESP);
>         vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP);
> --
> 1.7.3.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jan Kiszka Aug. 5, 2013, 7:35 a.m. UTC | #2
On 2013-08-05 09:21, Arthur Chunqi Li wrote:
> On Mon, Aug 5, 2013 at 1:49 AM, Jan Kiszka <jan.kiszka@web.de> wrote:
>> From: Jan Kiszka <jan.kiszka@siemens.com>
>>
>> Implement and advertise VM_EXIT_SAVE_IA32_EFER. L0 traps EFER writes
>> unconditionally, so we always find the current L2 value in the
>> architectural state.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>  arch/x86/kvm/vmx.c |    4 +++-
>>  1 files changed, 3 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>> index 84a05b4..7208d0b 100644
>> --- a/arch/x86/kvm/vmx.c
>> +++ b/arch/x86/kvm/vmx.c
>> @@ -2203,7 +2203,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)
>>         nested_vmx_exit_ctls_high = 0;
>>  #endif
>>         nested_vmx_exit_ctls_high |= (VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR |
>> -                                     VM_EXIT_LOAD_IA32_EFER);
>> +               VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER);
> Here you may need to access MSR_IA32_VMX_EXIT_CTLS first to check if
> host support these two features. The codes for "entry controls"
> following it can achieve goals like this.

We are providing this feature independently of the host's support. Every
write to EFER is trapped by L0, so we can emulate saving by reading what
L0 recorded.

Jan
diff mbox

Patch

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 84a05b4..7208d0b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2203,7 +2203,7 @@  static __init void nested_vmx_setup_ctls_msrs(void)
 	nested_vmx_exit_ctls_high = 0;
 #endif
 	nested_vmx_exit_ctls_high |= (VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR |
-				      VM_EXIT_LOAD_IA32_EFER);
+		VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER);
 
 	/* entry controls */
 	rdmsr(MSR_IA32_VMX_ENTRY_CTLS,
@@ -8113,6 +8113,8 @@  static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
 	vmcs12->guest_ia32_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL);
 	if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_PAT)
 		vmcs12->guest_ia32_pat = vmcs_read64(GUEST_IA32_PAT);
+	if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_EFER)
+		vmcs12->guest_ia32_efer = vcpu->arch.efer;
 	vmcs12->guest_sysenter_cs = vmcs_read32(GUEST_SYSENTER_CS);
 	vmcs12->guest_sysenter_esp = vmcs_readl(GUEST_SYSENTER_ESP);
 	vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP);