On Fri, May 24, 2024, Kai Huang wrote: > > @@ -1548,6 +1548,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) > > struct vcpu_svm *svm = to_svm(vcpu); > > struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); > > + if (vcpu->scheduled_out && !kvm_pause_in_guest(vcpu->kvm)) > > + shrink_ple_window(vcpu); > > + > > [...] > > > @@ -1517,6 +1517,9 @@ void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) > > { > > struct vcpu_vmx *vmx = to_vmx(vcpu); > > + if (vcpu->scheduled_out && !kvm_pause_in_guest(vcpu->kvm)) > > + shrink_ple_window(vcpu); > > + > > Nit: Perhaps we need a kvm_x86_ops::shrink_ple_window()? :-) Heh, that duplicate code annoys me too. The problem is the "old" window value comes from the VMCS/VMCB, so either we'd end up with multiple kvm_x86_ops, or we'd only be able to consolidate the scheduled_out + kvm_pause_in_guest() code, which isn't all that interesting. Aha! Actually, VMX already open codes the functionality provided by VCPU_EXREG_*, e.g. has vmx->ple_window_dirty. If we add VCPU_EXREG_PLE_WINDOW, then the info get be made available to common x86 code without having to add new hooks. And that would also allow moving the guts of handle_pause()/pause_interception() to common code, i.e. will also allow deduplicating the "grow" side of things.