2017-11-09 18:54 GMT+08:00 Paolo Bonzini <pbonzini@xxxxxxxxxx>: > On 09/11/2017 03:02, Wanpeng Li wrote: >> From: Wanpeng Li <wanpeng.li@xxxxxxxxxxx> >> >> PV-Flush guest would indicate to flush on enter, flush the TLB before >> entering and exiting the guest. >> >> Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx> >> Cc: Radim Krčmář <rkrcmar@xxxxxxxxxx> >> Signed-off-by: Wanpeng Li <wanpeng.li@xxxxxxxxxxx> >> --- >> arch/x86/kvm/x86.c | 12 ++++++++++-- >> 1 file changed, 10 insertions(+), 2 deletions(-) >> >> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c >> index 1ea28a2..f295360 100644 >> --- a/arch/x86/kvm/x86.c >> +++ b/arch/x86/kvm/x86.c >> @@ -2116,7 +2116,13 @@ static void record_steal_time(struct kvm_vcpu *vcpu) >> &vcpu->arch.st.steal, sizeof(struct kvm_steal_time)))) >> return; >> >> - vcpu->arch.st.steal.preempted = KVM_VCPU_NOT_PREEMPTED; >> + if (xchg(&vcpu->arch.st.steal.preempted, KVM_VCPU_NOT_PREEMPTED) == >> + (KVM_VCPU_SHOULD_FLUSH | KVM_VCPU_PREEMPTED)) >> + /* >> + * Do TLB_FLUSH before entering the guest, its passed >> + * the stage of request checking >> + */ >> + kvm_x86_ops->tlb_flush(vcpu); >> >> if (vcpu->arch.st.steal.version & 1) >> vcpu->arch.st.steal.version += 1; /* first time write, random junk */ >> @@ -2887,7 +2893,9 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) >> if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) >> return; >> >> - vcpu->arch.st.steal.preempted = KVM_VCPU_PREEMPTED; >> + if (xchg(&vcpu->arch.st.steal.preempted, KVM_VCPU_PREEMPTED) == >> + KVM_VCPU_SHOULD_FLUSH) >> + kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); > > This is not necessary. Instead, you can just OR the KVM_VCPU_PREEMPTED > bit; record_steal_time will pick up the request and do the TLB flush later. > > Also, I think this is a case where you should prefer INVVPID to INVEP. > That's because "execution of the INVEPT instruction invalidates > guest-physical mappings and combined mappings" while "execution of the > INVVPID instruction invalidates linear mappings and combined mappings". > In this case, invalidating guest-physical mapping is unnecessary. > > So you could add a new bool argument to kvm_x86_ops->tlb_flush. In > vmx.c, __vmx_flush_tlb can do invept if "enable_ept && (invalidate_gpa > || !enable_vpid)". Agreed. Regards, Wanpeng Li