Re: [PATCH 3/5] KVM: nVMX: add enlightened VMCS state

2018-06-15 Thread Vitaly Kuznetsov
Liran Alon  writes:

> - vkuzn...@redhat.com wrote:
>
>> Adds hv_evmcs pointer and implement copy_enlightened_to_vmcs12() and
>> copy_enlightened_to_vmcs12().
>> 
>> prepare_vmcs02()/prepare_vmcs02_full() separation is not valid for
>> Enlightened VMCS, do full sync for now.
>> 
>> Suggested-by: Ladi Prosek 
>> Signed-off-by: Vitaly Kuznetsov 
>> ---
>>  arch/x86/kvm/vmx.c | 431
>> +++--
>>  1 file changed, 417 insertions(+), 14 deletions(-)
>> 
>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>> index 51749207cef1..e7fa9f9c6e36 100644
>> --- a/arch/x86/kvm/vmx.c
>> +++ b/arch/x86/kvm/vmx.c
>> @@ -640,10 +640,10 @@ struct nested_vmx {
>>   */
>>  struct vmcs12 *cached_vmcs12;
>>  /*
>> - * Indicates if the shadow vmcs must be updated with the
>> - * data hold by vmcs12
>> + * Indicates if the shadow vmcs or enlightened vmcs must be updated
>> + * with the data held by struct vmcs12.
>>   */
>> -bool sync_shadow_vmcs;
>> +bool need_vmcs12_sync;
>>  bool dirty_vmcs12;
>>  
>>  bool change_vmcs01_virtual_apic_mode;
>> @@ -689,6 +689,8 @@ struct nested_vmx {
>>  /* in guest mode on SMM entry? */
>>  bool guest_mode;
>>  } smm;
>> +
>> +struct hv_enlightened_vmcs *hv_evmcs;
>>  };
>>  
>>  #define POSTED_INTR_ON  0
>> @@ -8010,7 +8012,7 @@ static inline void nested_release_vmcs12(struct
>> vcpu_vmx *vmx)
>>  /* copy to memory all shadowed fields in case
>> they were modified */
>>  copy_shadow_to_vmcs12(vmx);
>> -vmx->nested.sync_shadow_vmcs = false;
>> +vmx->nested.need_vmcs12_sync = false;
>>  vmx_disable_shadow_vmcs(vmx);
>>  }
>>  vmx->nested.posted_intr_nv = -1;
>> @@ -8187,6 +8189,393 @@ static inline int vmcs12_write_any(struct
>> kvm_vcpu *vcpu,
>>  
>>  }
>>  
>> +static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx, bool
>> full)
>> +{
>> +struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
>> +struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
>> +
>> +/* HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE */
>> +vmcs12->tpr_threshold = evmcs->tpr_threshold;
>> +vmcs12->guest_rip = evmcs->guest_rip;
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC))) {
>> +vmcs12->guest_rsp = evmcs->guest_rsp;
>> +vmcs12->guest_rflags = evmcs->guest_rflags;
>> +vmcs12->guest_interruptibility_info =
>> +evmcs->guest_interruptibility_info;
>> +}
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
>> +vmcs12->cpu_based_vm_exec_control =
>> +evmcs->cpu_based_vm_exec_control;
>> +}
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
>> +vmcs12->exception_bitmap = evmcs->exception_bitmap;
>> +}
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_ENTRY))) {
>> +vmcs12->vm_entry_controls = evmcs->vm_entry_controls;
>> +}
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EVENT))) {
>> +vmcs12->vm_entry_intr_info_field =
>> +evmcs->vm_entry_intr_info_field;
>> +vmcs12->vm_entry_exception_error_code =
>> +evmcs->vm_entry_exception_error_code;
>> +vmcs12->vm_entry_instruction_len =
>> +evmcs->vm_entry_instruction_len;
>> +}
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +  HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1))) {
>> +vmcs12->host_ia32_pat = evmcs->host_ia32_pat;
>> +vmcs12->host_ia32_efer = evmcs->host_ia32_efer;
>> +vmcs12->host_cr0 = evmcs->host_cr0;
>> +vmcs12->host_cr3 = evmcs->host_cr3;
>> +vmcs12->host_cr4 = evmcs->host_cr4;
>> +vmcs12->host_ia32_sysenter_esp = evmcs->host_ia32_sysenter_esp;
>> +vmcs12->host_ia32_sysenter_eip = evmcs->host_ia32_sysenter_eip;
>> +vmcs12->host_rip = evmcs->host_rip;
>> +vmcs12->host_ia32_sysenter_cs = evmcs->host_ia32_sysenter_cs;
>> +vmcs12->host_es_selector = evmcs->host_es_selector;
>> +vmcs12->host_cs_selector = evmcs->host_cs_selector;
>> +vmcs12->host_ss_selector = evmcs->host_ss_selector;
>> +vmcs12->host_ds_selector = evmcs->host_ds_selector;
>> +vmcs12->host_fs_selector = evmcs->host_fs_selector;
>> +vmcs12->host_gs_selector = evmcs->host_gs_selector;
>> +vmcs12->host_tr_selector = 

Re: [PATCH 3/5] KVM: nVMX: add enlightened VMCS state

2018-06-15 Thread Vitaly Kuznetsov
Liran Alon  writes:

> - vkuzn...@redhat.com wrote:
>
>> Adds hv_evmcs pointer and implement copy_enlightened_to_vmcs12() and
>> copy_enlightened_to_vmcs12().
>> 
>> prepare_vmcs02()/prepare_vmcs02_full() separation is not valid for
>> Enlightened VMCS, do full sync for now.
>> 
>> Suggested-by: Ladi Prosek 
>> Signed-off-by: Vitaly Kuznetsov 
>> ---
>>  arch/x86/kvm/vmx.c | 431
>> +++--
>>  1 file changed, 417 insertions(+), 14 deletions(-)
>> 
>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>> index 51749207cef1..e7fa9f9c6e36 100644
>> --- a/arch/x86/kvm/vmx.c
>> +++ b/arch/x86/kvm/vmx.c
>> @@ -640,10 +640,10 @@ struct nested_vmx {
>>   */
>>  struct vmcs12 *cached_vmcs12;
>>  /*
>> - * Indicates if the shadow vmcs must be updated with the
>> - * data hold by vmcs12
>> + * Indicates if the shadow vmcs or enlightened vmcs must be updated
>> + * with the data held by struct vmcs12.
>>   */
>> -bool sync_shadow_vmcs;
>> +bool need_vmcs12_sync;
>>  bool dirty_vmcs12;
>>  
>>  bool change_vmcs01_virtual_apic_mode;
>> @@ -689,6 +689,8 @@ struct nested_vmx {
>>  /* in guest mode on SMM entry? */
>>  bool guest_mode;
>>  } smm;
>> +
>> +struct hv_enlightened_vmcs *hv_evmcs;
>>  };
>>  
>>  #define POSTED_INTR_ON  0
>> @@ -8010,7 +8012,7 @@ static inline void nested_release_vmcs12(struct
>> vcpu_vmx *vmx)
>>  /* copy to memory all shadowed fields in case
>> they were modified */
>>  copy_shadow_to_vmcs12(vmx);
>> -vmx->nested.sync_shadow_vmcs = false;
>> +vmx->nested.need_vmcs12_sync = false;
>>  vmx_disable_shadow_vmcs(vmx);
>>  }
>>  vmx->nested.posted_intr_nv = -1;
>> @@ -8187,6 +8189,393 @@ static inline int vmcs12_write_any(struct
>> kvm_vcpu *vcpu,
>>  
>>  }
>>  
>> +static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx, bool
>> full)
>> +{
>> +struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
>> +struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
>> +
>> +/* HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE */
>> +vmcs12->tpr_threshold = evmcs->tpr_threshold;
>> +vmcs12->guest_rip = evmcs->guest_rip;
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC))) {
>> +vmcs12->guest_rsp = evmcs->guest_rsp;
>> +vmcs12->guest_rflags = evmcs->guest_rflags;
>> +vmcs12->guest_interruptibility_info =
>> +evmcs->guest_interruptibility_info;
>> +}
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
>> +vmcs12->cpu_based_vm_exec_control =
>> +evmcs->cpu_based_vm_exec_control;
>> +}
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
>> +vmcs12->exception_bitmap = evmcs->exception_bitmap;
>> +}
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_ENTRY))) {
>> +vmcs12->vm_entry_controls = evmcs->vm_entry_controls;
>> +}
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EVENT))) {
>> +vmcs12->vm_entry_intr_info_field =
>> +evmcs->vm_entry_intr_info_field;
>> +vmcs12->vm_entry_exception_error_code =
>> +evmcs->vm_entry_exception_error_code;
>> +vmcs12->vm_entry_instruction_len =
>> +evmcs->vm_entry_instruction_len;
>> +}
>> +
>> +if (unlikely(full || !(evmcs->hv_clean_fields &
>> +  HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1))) {
>> +vmcs12->host_ia32_pat = evmcs->host_ia32_pat;
>> +vmcs12->host_ia32_efer = evmcs->host_ia32_efer;
>> +vmcs12->host_cr0 = evmcs->host_cr0;
>> +vmcs12->host_cr3 = evmcs->host_cr3;
>> +vmcs12->host_cr4 = evmcs->host_cr4;
>> +vmcs12->host_ia32_sysenter_esp = evmcs->host_ia32_sysenter_esp;
>> +vmcs12->host_ia32_sysenter_eip = evmcs->host_ia32_sysenter_eip;
>> +vmcs12->host_rip = evmcs->host_rip;
>> +vmcs12->host_ia32_sysenter_cs = evmcs->host_ia32_sysenter_cs;
>> +vmcs12->host_es_selector = evmcs->host_es_selector;
>> +vmcs12->host_cs_selector = evmcs->host_cs_selector;
>> +vmcs12->host_ss_selector = evmcs->host_ss_selector;
>> +vmcs12->host_ds_selector = evmcs->host_ds_selector;
>> +vmcs12->host_fs_selector = evmcs->host_fs_selector;
>> +vmcs12->host_gs_selector = evmcs->host_gs_selector;
>> +vmcs12->host_tr_selector = 

Re: [PATCH 3/5] KVM: nVMX: add enlightened VMCS state

2018-06-14 Thread Liran Alon


- vkuzn...@redhat.com wrote:

> Adds hv_evmcs pointer and implement copy_enlightened_to_vmcs12() and
> copy_enlightened_to_vmcs12().
> 
> prepare_vmcs02()/prepare_vmcs02_full() separation is not valid for
> Enlightened VMCS, do full sync for now.
> 
> Suggested-by: Ladi Prosek 
> Signed-off-by: Vitaly Kuznetsov 
> ---
>  arch/x86/kvm/vmx.c | 431
> +++--
>  1 file changed, 417 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 51749207cef1..e7fa9f9c6e36 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -640,10 +640,10 @@ struct nested_vmx {
>*/
>   struct vmcs12 *cached_vmcs12;
>   /*
> -  * Indicates if the shadow vmcs must be updated with the
> -  * data hold by vmcs12
> +  * Indicates if the shadow vmcs or enlightened vmcs must be updated
> +  * with the data held by struct vmcs12.
>*/
> - bool sync_shadow_vmcs;
> + bool need_vmcs12_sync;
>   bool dirty_vmcs12;
>  
>   bool change_vmcs01_virtual_apic_mode;
> @@ -689,6 +689,8 @@ struct nested_vmx {
>   /* in guest mode on SMM entry? */
>   bool guest_mode;
>   } smm;
> +
> + struct hv_enlightened_vmcs *hv_evmcs;
>  };
>  
>  #define POSTED_INTR_ON  0
> @@ -8010,7 +8012,7 @@ static inline void nested_release_vmcs12(struct
> vcpu_vmx *vmx)
>   /* copy to memory all shadowed fields in case
>  they were modified */
>   copy_shadow_to_vmcs12(vmx);
> - vmx->nested.sync_shadow_vmcs = false;
> + vmx->nested.need_vmcs12_sync = false;
>   vmx_disable_shadow_vmcs(vmx);
>   }
>   vmx->nested.posted_intr_nv = -1;
> @@ -8187,6 +8189,393 @@ static inline int vmcs12_write_any(struct
> kvm_vcpu *vcpu,
>  
>  }
>  
> +static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx, bool
> full)
> +{
> + struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
> + struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
> +
> + /* HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE */
> + vmcs12->tpr_threshold = evmcs->tpr_threshold;
> + vmcs12->guest_rip = evmcs->guest_rip;
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC))) {
> + vmcs12->guest_rsp = evmcs->guest_rsp;
> + vmcs12->guest_rflags = evmcs->guest_rflags;
> + vmcs12->guest_interruptibility_info =
> + evmcs->guest_interruptibility_info;
> + }
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
> + vmcs12->cpu_based_vm_exec_control =
> + evmcs->cpu_based_vm_exec_control;
> + }
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
> + vmcs12->exception_bitmap = evmcs->exception_bitmap;
> + }
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_ENTRY))) {
> + vmcs12->vm_entry_controls = evmcs->vm_entry_controls;
> + }
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EVENT))) {
> + vmcs12->vm_entry_intr_info_field =
> + evmcs->vm_entry_intr_info_field;
> + vmcs12->vm_entry_exception_error_code =
> + evmcs->vm_entry_exception_error_code;
> + vmcs12->vm_entry_instruction_len =
> + evmcs->vm_entry_instruction_len;
> + }
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1))) {
> + vmcs12->host_ia32_pat = evmcs->host_ia32_pat;
> + vmcs12->host_ia32_efer = evmcs->host_ia32_efer;
> + vmcs12->host_cr0 = evmcs->host_cr0;
> + vmcs12->host_cr3 = evmcs->host_cr3;
> + vmcs12->host_cr4 = evmcs->host_cr4;
> + vmcs12->host_ia32_sysenter_esp = evmcs->host_ia32_sysenter_esp;
> + vmcs12->host_ia32_sysenter_eip = evmcs->host_ia32_sysenter_eip;
> + vmcs12->host_rip = evmcs->host_rip;
> + vmcs12->host_ia32_sysenter_cs = evmcs->host_ia32_sysenter_cs;
> + vmcs12->host_es_selector = evmcs->host_es_selector;
> + vmcs12->host_cs_selector = evmcs->host_cs_selector;
> + vmcs12->host_ss_selector = evmcs->host_ss_selector;
> + vmcs12->host_ds_selector = evmcs->host_ds_selector;
> + vmcs12->host_fs_selector = evmcs->host_fs_selector;
> + vmcs12->host_gs_selector = evmcs->host_gs_selector;
> + vmcs12->host_tr_selector = evmcs->host_tr_selector;
> + }
> +
> + if 

Re: [PATCH 3/5] KVM: nVMX: add enlightened VMCS state

2018-06-14 Thread Liran Alon


- vkuzn...@redhat.com wrote:

> Adds hv_evmcs pointer and implement copy_enlightened_to_vmcs12() and
> copy_enlightened_to_vmcs12().
> 
> prepare_vmcs02()/prepare_vmcs02_full() separation is not valid for
> Enlightened VMCS, do full sync for now.
> 
> Suggested-by: Ladi Prosek 
> Signed-off-by: Vitaly Kuznetsov 
> ---
>  arch/x86/kvm/vmx.c | 431
> +++--
>  1 file changed, 417 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 51749207cef1..e7fa9f9c6e36 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -640,10 +640,10 @@ struct nested_vmx {
>*/
>   struct vmcs12 *cached_vmcs12;
>   /*
> -  * Indicates if the shadow vmcs must be updated with the
> -  * data hold by vmcs12
> +  * Indicates if the shadow vmcs or enlightened vmcs must be updated
> +  * with the data held by struct vmcs12.
>*/
> - bool sync_shadow_vmcs;
> + bool need_vmcs12_sync;
>   bool dirty_vmcs12;
>  
>   bool change_vmcs01_virtual_apic_mode;
> @@ -689,6 +689,8 @@ struct nested_vmx {
>   /* in guest mode on SMM entry? */
>   bool guest_mode;
>   } smm;
> +
> + struct hv_enlightened_vmcs *hv_evmcs;
>  };
>  
>  #define POSTED_INTR_ON  0
> @@ -8010,7 +8012,7 @@ static inline void nested_release_vmcs12(struct
> vcpu_vmx *vmx)
>   /* copy to memory all shadowed fields in case
>  they were modified */
>   copy_shadow_to_vmcs12(vmx);
> - vmx->nested.sync_shadow_vmcs = false;
> + vmx->nested.need_vmcs12_sync = false;
>   vmx_disable_shadow_vmcs(vmx);
>   }
>   vmx->nested.posted_intr_nv = -1;
> @@ -8187,6 +8189,393 @@ static inline int vmcs12_write_any(struct
> kvm_vcpu *vcpu,
>  
>  }
>  
> +static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx, bool
> full)
> +{
> + struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
> + struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
> +
> + /* HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE */
> + vmcs12->tpr_threshold = evmcs->tpr_threshold;
> + vmcs12->guest_rip = evmcs->guest_rip;
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC))) {
> + vmcs12->guest_rsp = evmcs->guest_rsp;
> + vmcs12->guest_rflags = evmcs->guest_rflags;
> + vmcs12->guest_interruptibility_info =
> + evmcs->guest_interruptibility_info;
> + }
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
> + vmcs12->cpu_based_vm_exec_control =
> + evmcs->cpu_based_vm_exec_control;
> + }
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
> + vmcs12->exception_bitmap = evmcs->exception_bitmap;
> + }
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_ENTRY))) {
> + vmcs12->vm_entry_controls = evmcs->vm_entry_controls;
> + }
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EVENT))) {
> + vmcs12->vm_entry_intr_info_field =
> + evmcs->vm_entry_intr_info_field;
> + vmcs12->vm_entry_exception_error_code =
> + evmcs->vm_entry_exception_error_code;
> + vmcs12->vm_entry_instruction_len =
> + evmcs->vm_entry_instruction_len;
> + }
> +
> + if (unlikely(full || !(evmcs->hv_clean_fields &
> +   HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1))) {
> + vmcs12->host_ia32_pat = evmcs->host_ia32_pat;
> + vmcs12->host_ia32_efer = evmcs->host_ia32_efer;
> + vmcs12->host_cr0 = evmcs->host_cr0;
> + vmcs12->host_cr3 = evmcs->host_cr3;
> + vmcs12->host_cr4 = evmcs->host_cr4;
> + vmcs12->host_ia32_sysenter_esp = evmcs->host_ia32_sysenter_esp;
> + vmcs12->host_ia32_sysenter_eip = evmcs->host_ia32_sysenter_eip;
> + vmcs12->host_rip = evmcs->host_rip;
> + vmcs12->host_ia32_sysenter_cs = evmcs->host_ia32_sysenter_cs;
> + vmcs12->host_es_selector = evmcs->host_es_selector;
> + vmcs12->host_cs_selector = evmcs->host_cs_selector;
> + vmcs12->host_ss_selector = evmcs->host_ss_selector;
> + vmcs12->host_ds_selector = evmcs->host_ds_selector;
> + vmcs12->host_fs_selector = evmcs->host_fs_selector;
> + vmcs12->host_gs_selector = evmcs->host_gs_selector;
> + vmcs12->host_tr_selector = evmcs->host_tr_selector;
> + }
> +
> + if 

[PATCH 3/5] KVM: nVMX: add enlightened VMCS state

2018-06-14 Thread Vitaly Kuznetsov
Adds hv_evmcs pointer and implement copy_enlightened_to_vmcs12() and
copy_enlightened_to_vmcs12().

prepare_vmcs02()/prepare_vmcs02_full() separation is not valid for
Enlightened VMCS, do full sync for now.

Suggested-by: Ladi Prosek 
Signed-off-by: Vitaly Kuznetsov 
---
 arch/x86/kvm/vmx.c | 431 +++--
 1 file changed, 417 insertions(+), 14 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 51749207cef1..e7fa9f9c6e36 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -640,10 +640,10 @@ struct nested_vmx {
 */
struct vmcs12 *cached_vmcs12;
/*
-* Indicates if the shadow vmcs must be updated with the
-* data hold by vmcs12
+* Indicates if the shadow vmcs or enlightened vmcs must be updated
+* with the data held by struct vmcs12.
 */
-   bool sync_shadow_vmcs;
+   bool need_vmcs12_sync;
bool dirty_vmcs12;
 
bool change_vmcs01_virtual_apic_mode;
@@ -689,6 +689,8 @@ struct nested_vmx {
/* in guest mode on SMM entry? */
bool guest_mode;
} smm;
+
+   struct hv_enlightened_vmcs *hv_evmcs;
 };
 
 #define POSTED_INTR_ON  0
@@ -8010,7 +8012,7 @@ static inline void nested_release_vmcs12(struct vcpu_vmx 
*vmx)
/* copy to memory all shadowed fields in case
   they were modified */
copy_shadow_to_vmcs12(vmx);
-   vmx->nested.sync_shadow_vmcs = false;
+   vmx->nested.need_vmcs12_sync = false;
vmx_disable_shadow_vmcs(vmx);
}
vmx->nested.posted_intr_nv = -1;
@@ -8187,6 +8189,393 @@ static inline int vmcs12_write_any(struct kvm_vcpu 
*vcpu,
 
 }
 
+static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx, bool full)
+{
+   struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
+   struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
+
+   /* HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE */
+   vmcs12->tpr_threshold = evmcs->tpr_threshold;
+   vmcs12->guest_rip = evmcs->guest_rip;
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC))) {
+   vmcs12->guest_rsp = evmcs->guest_rsp;
+   vmcs12->guest_rflags = evmcs->guest_rflags;
+   vmcs12->guest_interruptibility_info =
+   evmcs->guest_interruptibility_info;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
+   vmcs12->cpu_based_vm_exec_control =
+   evmcs->cpu_based_vm_exec_control;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
+   vmcs12->exception_bitmap = evmcs->exception_bitmap;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_ENTRY))) {
+   vmcs12->vm_entry_controls = evmcs->vm_entry_controls;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EVENT))) {
+   vmcs12->vm_entry_intr_info_field =
+   evmcs->vm_entry_intr_info_field;
+   vmcs12->vm_entry_exception_error_code =
+   evmcs->vm_entry_exception_error_code;
+   vmcs12->vm_entry_instruction_len =
+   evmcs->vm_entry_instruction_len;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+ HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1))) {
+   vmcs12->host_ia32_pat = evmcs->host_ia32_pat;
+   vmcs12->host_ia32_efer = evmcs->host_ia32_efer;
+   vmcs12->host_cr0 = evmcs->host_cr0;
+   vmcs12->host_cr3 = evmcs->host_cr3;
+   vmcs12->host_cr4 = evmcs->host_cr4;
+   vmcs12->host_ia32_sysenter_esp = evmcs->host_ia32_sysenter_esp;
+   vmcs12->host_ia32_sysenter_eip = evmcs->host_ia32_sysenter_eip;
+   vmcs12->host_rip = evmcs->host_rip;
+   vmcs12->host_ia32_sysenter_cs = evmcs->host_ia32_sysenter_cs;
+   vmcs12->host_es_selector = evmcs->host_es_selector;
+   vmcs12->host_cs_selector = evmcs->host_cs_selector;
+   vmcs12->host_ss_selector = evmcs->host_ss_selector;
+   vmcs12->host_ds_selector = evmcs->host_ds_selector;
+   vmcs12->host_fs_selector = evmcs->host_fs_selector;
+   vmcs12->host_gs_selector = evmcs->host_gs_selector;
+   vmcs12->host_tr_selector = evmcs->host_tr_selector;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1))) {
+ 

[PATCH 3/5] KVM: nVMX: add enlightened VMCS state

2018-06-14 Thread Vitaly Kuznetsov
Adds hv_evmcs pointer and implement copy_enlightened_to_vmcs12() and
copy_enlightened_to_vmcs12().

prepare_vmcs02()/prepare_vmcs02_full() separation is not valid for
Enlightened VMCS, do full sync for now.

Suggested-by: Ladi Prosek 
Signed-off-by: Vitaly Kuznetsov 
---
 arch/x86/kvm/vmx.c | 431 +++--
 1 file changed, 417 insertions(+), 14 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 51749207cef1..e7fa9f9c6e36 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -640,10 +640,10 @@ struct nested_vmx {
 */
struct vmcs12 *cached_vmcs12;
/*
-* Indicates if the shadow vmcs must be updated with the
-* data hold by vmcs12
+* Indicates if the shadow vmcs or enlightened vmcs must be updated
+* with the data held by struct vmcs12.
 */
-   bool sync_shadow_vmcs;
+   bool need_vmcs12_sync;
bool dirty_vmcs12;
 
bool change_vmcs01_virtual_apic_mode;
@@ -689,6 +689,8 @@ struct nested_vmx {
/* in guest mode on SMM entry? */
bool guest_mode;
} smm;
+
+   struct hv_enlightened_vmcs *hv_evmcs;
 };
 
 #define POSTED_INTR_ON  0
@@ -8010,7 +8012,7 @@ static inline void nested_release_vmcs12(struct vcpu_vmx 
*vmx)
/* copy to memory all shadowed fields in case
   they were modified */
copy_shadow_to_vmcs12(vmx);
-   vmx->nested.sync_shadow_vmcs = false;
+   vmx->nested.need_vmcs12_sync = false;
vmx_disable_shadow_vmcs(vmx);
}
vmx->nested.posted_intr_nv = -1;
@@ -8187,6 +8189,393 @@ static inline int vmcs12_write_any(struct kvm_vcpu 
*vcpu,
 
 }
 
+static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx, bool full)
+{
+   struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
+   struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
+
+   /* HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE */
+   vmcs12->tpr_threshold = evmcs->tpr_threshold;
+   vmcs12->guest_rip = evmcs->guest_rip;
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC))) {
+   vmcs12->guest_rsp = evmcs->guest_rsp;
+   vmcs12->guest_rflags = evmcs->guest_rflags;
+   vmcs12->guest_interruptibility_info =
+   evmcs->guest_interruptibility_info;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
+   vmcs12->cpu_based_vm_exec_control =
+   evmcs->cpu_based_vm_exec_control;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) {
+   vmcs12->exception_bitmap = evmcs->exception_bitmap;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_ENTRY))) {
+   vmcs12->vm_entry_controls = evmcs->vm_entry_controls;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EVENT))) {
+   vmcs12->vm_entry_intr_info_field =
+   evmcs->vm_entry_intr_info_field;
+   vmcs12->vm_entry_exception_error_code =
+   evmcs->vm_entry_exception_error_code;
+   vmcs12->vm_entry_instruction_len =
+   evmcs->vm_entry_instruction_len;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+ HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1))) {
+   vmcs12->host_ia32_pat = evmcs->host_ia32_pat;
+   vmcs12->host_ia32_efer = evmcs->host_ia32_efer;
+   vmcs12->host_cr0 = evmcs->host_cr0;
+   vmcs12->host_cr3 = evmcs->host_cr3;
+   vmcs12->host_cr4 = evmcs->host_cr4;
+   vmcs12->host_ia32_sysenter_esp = evmcs->host_ia32_sysenter_esp;
+   vmcs12->host_ia32_sysenter_eip = evmcs->host_ia32_sysenter_eip;
+   vmcs12->host_rip = evmcs->host_rip;
+   vmcs12->host_ia32_sysenter_cs = evmcs->host_ia32_sysenter_cs;
+   vmcs12->host_es_selector = evmcs->host_es_selector;
+   vmcs12->host_cs_selector = evmcs->host_cs_selector;
+   vmcs12->host_ss_selector = evmcs->host_ss_selector;
+   vmcs12->host_ds_selector = evmcs->host_ds_selector;
+   vmcs12->host_fs_selector = evmcs->host_fs_selector;
+   vmcs12->host_gs_selector = evmcs->host_gs_selector;
+   vmcs12->host_tr_selector = evmcs->host_tr_selector;
+   }
+
+   if (unlikely(full || !(evmcs->hv_clean_fields &
+  HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1))) {
+