> -----邮件原件----- > 发件人: Paolo Bonzini [mailto:pbonzini@xxxxxxxxxx] > 发送时间: 2020年4月29日 18:21 > 收件人: Peter Zijlstra <peterz@xxxxxxxxxxxxx>; Li,Rongqing > <lirongqing@xxxxxxxxx> > 抄送: linux-kernel@xxxxxxxxxxxxxxx; kvm@xxxxxxxxxxxxxxx; x86@xxxxxxxxxx; > hpa@xxxxxxxxx; bp@xxxxxxxxx; mingo@xxxxxxxxxx; tglx@xxxxxxxxxxxxx; > joro@xxxxxxxxxx; jmattson@xxxxxxxxxx; wanpengli@xxxxxxxxxxx; > vkuznets@xxxxxxxxxx; sean.j.christopherson@xxxxxxxxx > 主题: Re: [PATCH][v2] kvm: x86: emulate APERF/MPERF registers > > On 29/04/20 10:54, Peter Zijlstra wrote: > > On Wed, Apr 29, 2020 at 01:46:36PM +0800, Li RongQing wrote: > >> Guest kernel reports a fixed cpu frequency in /proc/cpuinfo, this is > >> confused to user when turbo is enable, and aperf/mperf can be used to > >> show current cpu frequency after 7d5905dc14a > >> "(x86 / CPU: Always show current CPU frequency in /proc/cpuinfo)" > >> so we should emulate aperf mperf to achieve it > >> > >> the period of aperf/mperf in guest mode are accumulated as emulated > >> value, and add per-VM knod to enable emulate mperfaperf > >> > >> diff v1: > >> 1. support AMD > >> 2. support per-vm capability to enable > > Would it make sense to provide a pass-through APERF/MPERF for > > KVM_HINTS_REALTIME ? Because that hint guarantees we have a 1:1 > > vCPU:CPU binding and guaranteed no over-commit. > > > > Yes but that's up to userspace. > > Paolo Seem kernel should give the capability to userspace to disable the intercept mperf/aperf for KVM_HINTS_REALTIME So I will change this patch to support three mode mperfaperf: none, software emulate, and pt diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1d157a8dba46..6b05f78bde78 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1657,9 +1657,11 @@ static void init_vmcb(struct vcpu_svm *svm) set_intercept(svm, INTERCEPT_SKINIT); set_intercept(svm, INTERCEPT_WBINVD); set_intercept(svm, INTERCEPT_XSETBV); - set_intercept(svm, INTERCEPT_RDPRU); set_intercept(svm, INTERCEPT_RSM); + if (!guest_mperfaperf_pt(svm->vcpu.kvm)) + set_intercept(svm, INTERCEPT_RDPRU); + if (!kvm_mwait_in_guest(svm->vcpu.kvm)) { set_intercept(svm, INTERCEPT_MONITOR); set_intercept(svm, INTERCEPT_MWAIT); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index b05e276e262b..231732924c50 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6765,6 +6765,12 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) vmx_disable_intercept_for_msr(msr_bitmap, MSR_CORE_C6_RESIDENCY, MSR_TYPE_R); vmx_disable_intercept_for_msr(msr_bitmap, MSR_CORE_C7_RESIDENCY, MSR_TYPE_R); } + + if (guest_mperfaperf_pt(vcpu->kvm)) { + vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_MPERF, MSR_TYPE_R); + vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_APERF, MSR_TYPE_R); + } + vmx->msr_bitmap_mode = 0; vmx->loaded_vmcs = &vmx->vmcs01; -Li