All that needs to be done is moving the GMET bit from vmcs12 to vmcs02. The only new thing is that __nested_copy_vmcb_control_to_cache now ensures that ignored-if-unavailable bits are zero in svm->nested.ctl. Tested-by: David Riley Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/nested.c | 7 +++++++ arch/x86/kvm/svm/svm.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index a28c5e8d017b..1d791918efb3 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -508,6 +508,12 @@ void __nested_copy_vmcb_control_to_cache(struct kvm_vcpu *vcpu, to->exit_int_info = from->exit_int_info; to->exit_int_info_err = from->exit_int_info_err; to->event_inj = from->event_inj & ~SVM_EVTINJ_RESERVED_BITS; + + to->misc_ctl = from->misc_ctl; + if (!gmet_enabled || !guest_cpu_cap_has(vcpu, X86_FEATURE_GMET)) + to->misc_ctl &= ~SVM_MISC_ENABLE_GMET; + + to->event_inj = from->event_inj; to->event_inj_err = from->event_inj_err; to->next_rip = from->next_rip; to->nested_cr3 = from->nested_cr3; @@ -898,6 +904,7 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm) /* Use vmcb01 MMU and format if guest does not use nNPT */ if (nested_npt_enabled(svm)) { vmcb02->control.misc_ctl &= ~SVM_MISC_ENABLE_GMET; + vmcb02->control.misc_ctl |= (svm->nested.ctl.misc_ctl & SVM_MISC_ENABLE_GMET); nested_svm_init_mmu_context(vcpu); } diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index fd79874c5f4b..a82471a6d3ea 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -5504,6 +5504,9 @@ static __init void svm_set_cpu_caps(void) if (boot_cpu_has(X86_FEATURE_PFTHRESHOLD)) kvm_cpu_cap_set(X86_FEATURE_PFTHRESHOLD); + if (gmet_enabled) + kvm_cpu_cap_set(X86_FEATURE_GMET); + if (vgif) kvm_cpu_cap_set(X86_FEATURE_VGIF); -- 2.52.0