Re: [PATCH 3/5] KVM: nVMX: add enlightened VMCS state
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
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
- 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
- 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
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
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))) { +