In preparation for using svm_copy_lbrs() with instances of both 'struct vmcb_save_area' and 'struct vmcb_save_area_cached', make it a macro instead. Pull the call to vmcb_mark_dirty() out to the callers. Macros are generally not preferred compared to functions, mainly due to type-safety. However, in this case it seems like having a simple macro copying a few fields is better than copy-pasting the same 5 lines of code in 6 different places (soon to be 7), or creating 3 different variants of the function. On the bright side, pulling vmcb_mark_dirty() calls to the callers makes it clear that in one case, vmcb_mark_dirty() was being called on VMCB12. It is not architecturally defined for the CPU to clear arbitrary clean bits, and it is not needed, so drop that one call. Signed-off-by: Yosry Ahmed --- arch/x86/kvm/svm/nested.c | 11 +++++++---- arch/x86/kvm/svm/svm.c | 23 ++++++++--------------- arch/x86/kvm/svm/svm.h | 10 +++++++++- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 986e6382dc4fa..81d7a0ed71392 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -726,12 +726,14 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm *svm, struct vmcb *vmcb12 * Reserved bits of DEBUGCTL are ignored. Be consistent with * svm_set_msr's definition of reserved bits. */ - svm_copy_lbrs(vmcb02, vmcb12); + svm_copy_lbrs(&vmcb02->save, &vmcb12->save); + vmcb_mark_dirty(vmcb02, VMCB_LBR); vmcb02->save.dbgctl &= ~DEBUGCTL_RESERVED_BITS; svm_update_lbrv(&svm->vcpu); } else if (unlikely(vmcb01->control.misc_ctl2 & SVM_MISC_CTL2_LBR_CTL_ENABLE)) { - svm_copy_lbrs(vmcb02, vmcb01); + svm_copy_lbrs(&vmcb02->save, &vmcb01->save); + vmcb_mark_dirty(vmcb02, VMCB_LBR); } } @@ -1242,10 +1244,11 @@ int nested_svm_vmexit(struct vcpu_svm *svm) if (unlikely(guest_cpu_cap_has(vcpu, X86_FEATURE_LBRV) && (svm->nested.ctl.misc_ctl2 & SVM_MISC_CTL2_LBR_CTL_ENABLE))) { - svm_copy_lbrs(vmcb12, vmcb02); + svm_copy_lbrs(&vmcb12->save, &vmcb02->save); svm_update_lbrv(vcpu); } else if (unlikely(vmcb01->control.misc_ctl2 & SVM_MISC_CTL2_LBR_CTL_ENABLE)) { - svm_copy_lbrs(vmcb01, vmcb02); + svm_copy_lbrs(&vmcb01->save, &vmcb02->save); + vmcb_mark_dirty(vmcb01, VMCB_LBR); svm_update_lbrv(vcpu); } diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 185f17ff2170b..07958dc7c62ba 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -795,17 +795,6 @@ static void svm_recalc_msr_intercepts(struct kvm_vcpu *vcpu) */ } -void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb) -{ - to_vmcb->save.dbgctl = from_vmcb->save.dbgctl; - to_vmcb->save.br_from = from_vmcb->save.br_from; - to_vmcb->save.br_to = from_vmcb->save.br_to; - to_vmcb->save.last_excp_from = from_vmcb->save.last_excp_from; - to_vmcb->save.last_excp_to = from_vmcb->save.last_excp_to; - - vmcb_mark_dirty(to_vmcb, VMCB_LBR); -} - void svm_enable_lbrv(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); @@ -814,8 +803,10 @@ void svm_enable_lbrv(struct kvm_vcpu *vcpu) svm_recalc_lbr_msr_intercepts(vcpu); /* Move the LBR msrs to the vmcb02 so that the guest can see them. */ - if (is_guest_mode(vcpu)) - svm_copy_lbrs(svm->vmcb, svm->vmcb01.ptr); + if (is_guest_mode(vcpu)) { + svm_copy_lbrs(&svm->vmcb->save, &svm->vmcb01.ptr->save); + vmcb_mark_dirty(svm->vmcb, VMCB_LBR); + } } static void svm_disable_lbrv(struct kvm_vcpu *vcpu) @@ -830,8 +821,10 @@ static void svm_disable_lbrv(struct kvm_vcpu *vcpu) * Move the LBR msrs back to the vmcb01 to avoid copying them * on nested guest entries. */ - if (is_guest_mode(vcpu)) - svm_copy_lbrs(svm->vmcb01.ptr, svm->vmcb); + if (is_guest_mode(vcpu)) { + svm_copy_lbrs(&svm->vmcb01.ptr->save, &svm->vmcb->save); + vmcb_mark_dirty(svm->vmcb01.ptr, VMCB_LBR); + } } static struct vmcb *svm_get_lbr_vmcb(struct vcpu_svm *svm) diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 26ba9472784eb..8577e35a7096a 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -689,8 +689,16 @@ static inline void *svm_vcpu_alloc_msrpm(void) return svm_alloc_permissions_map(MSRPM_SIZE, GFP_KERNEL_ACCOUNT); } +#define svm_copy_lbrs(to, from) \ +({ \ + (to)->dbgctl = (from)->dbgctl; \ + (to)->br_from = (from)->br_from; \ + (to)->br_to = (from)->br_to; \ + (to)->last_excp_from = (from)->last_excp_from; \ + (to)->last_excp_to = (from)->last_excp_to; \ +}) + void svm_vcpu_free_msrpm(void *msrpm); -void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb); void svm_enable_lbrv(struct kvm_vcpu *vcpu); void svm_update_lbrv(struct kvm_vcpu *vcpu); -- 2.51.2.1026.g39e6a42477-goog