kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Mingwei Zhang <mizhang@google.com>
Cc: Zide Chen <zide.chen@intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	 Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	 Paolo Bonzini <pbonzini@redhat.com>,
	Mark Rutland <mark.rutland@arm.com>,
	 Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@kernel.org>,  Ian Rogers <irogers@google.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Liang@google.com,  Kan <kan.liang@linux.intel.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	 linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
	 kvm@vger.kernel.org, linux-kselftest@vger.kernel.org,
	 Yongwei Ma <yongwei.ma@intel.com>,
	Xiong Zhang <xiong.y.zhang@linux.intel.com>,
	 Dapeng Mi <dapeng1.mi@linux.intel.com>,
	Jim Mattson <jmattson@google.com>,
	 Sandipan Das <sandipan.das@amd.com>,
	Eranian Stephane <eranian@google.com>,
	 Shukla Manali <Manali.Shukla@amd.com>,
	Nikunj Dadhania <nikunj.dadhania@amd.com>
Subject: Re: [PATCH v4 21/38] KVM: x86/pmu/vmx: Save/load guest IA32_PERF_GLOBAL_CTRL with vm_exit/entry_ctrl
Date: Wed, 14 May 2025 17:33:36 -0700	[thread overview]
Message-ID: <aCU2YEpU0dOk7RTk@google.com> (raw)
In-Reply-To: <CAL715WLfr5k=Rz0cQ08xS=eHEyRn83PBTiqQ5H7iX4qH=jiS8A@mail.gmail.com>

On Wed, Mar 26, 2025, Mingwei Zhang wrote:
> On Wed, Mar 26, 2025 at 9:51 AM Chen, Zide <zide.chen@intel.com> wrote:
> > > diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
> > > index 6ad71752be4b..4e8cefcce7ab 100644
> > > --- a/arch/x86/kvm/pmu.c
> > > +++ b/arch/x86/kvm/pmu.c
> > > @@ -646,6 +646,30 @@ void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu)
> > >       }
> > >  }
> > >
> > > +static void kvm_pmu_sync_global_ctrl_from_vmcs(struct kvm_vcpu *vcpu)
> > > +{
> > > +     struct msr_data msr_info = { .index = MSR_CORE_PERF_GLOBAL_CTRL };
> > > +
> > > +     if (!kvm_mediated_pmu_enabled(vcpu))
> > > +             return;
> > > +
> > > +     /* Sync pmu->global_ctrl from GUEST_IA32_PERF_GLOBAL_CTRL. */
> > > +     kvm_pmu_call(get_msr)(vcpu, &msr_info);
> > > +}
> > > +
> > > +static void kvm_pmu_sync_global_ctrl_to_vmcs(struct kvm_vcpu *vcpu, u64 global_ctrl)
> > > +{
> > > +     struct msr_data msr_info = {
> > > +             .index = MSR_CORE_PERF_GLOBAL_CTRL,
> > > +             .data = global_ctrl };
> > > +
> > > +     if (!kvm_mediated_pmu_enabled(vcpu))
> > > +             return;
> > > +
> > > +     /* Sync pmu->global_ctrl to GUEST_IA32_PERF_GLOBAL_CTRL. */
> > > +     kvm_pmu_call(set_msr)(vcpu, &msr_info);

Eh, just add a dedicated kvm_pmu_ops hook.  Feeding this through set_msr() avoids
adding another hook, but makes the code hard to follow and requires the above
ugly boilerplate.

> > > +}
> > > +
> > >  bool kvm_pmu_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
> > >  {
> > >       switch (msr) {
> > > @@ -680,7 +704,6 @@ int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
> > >               msr_info->data = pmu->global_status;
> > >               break;
> > >       case MSR_AMD64_PERF_CNTR_GLOBAL_CTL:
> > > -     case MSR_CORE_PERF_GLOBAL_CTRL:
> > >               msr_info->data = pmu->global_ctrl;
> > >               break;
> > >       case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR:
> > > @@ -731,6 +754,9 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
> >
> >
> > pmu->global_ctrl doesn't always have the up-to-date guest value, need to
> > sync from vmcs/vmbc before comparing it against 'data'.
> >
> > +               kvm_pmu_sync_global_ctrl_from_vmcs(vcpu);
> >                 if (pmu->global_ctrl != data) {
> 
> Good catch. Thanks!
> 
> This is why I really prefer just unconditionally syncing the global
> ctrl from VMCS to pmu->global_ctrl and vice versa.
> 
> We might get into similar problems as well in the future.

The problem isn't conditional synchronization, it's that y'all reinvented the
wheel, poorly.  This is a solved problem via EXREG and wrappers.

That said, I went through the exercise of adding a PERF_GLOBAL_CTRL EXREG and
associated wrappers, and didn't love the result.  Host writes should be rare, so
the dirty tracking is overkill.  For reads, the cost of VMREAD is lower than
VMWRITE (doesn't trigger consistency check re-evaluation on VM-Enter), and is
dwarfed by the cost of switching all other PMU state.

So I think for the initial implementation, it makes sense to propagated writes
to the VMCS on demand, but do VMREAD after VM-Exit (if VM-Enter was successful).
We can always revisit the optimization if/when we optimize the PMU world switches,
e.g. to defer them if there are no active host events.

> > > diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> > > index 8a7af02d466e..ecf72394684d 100644
> > > --- a/arch/x86/kvm/vmx/nested.c
> > > +++ b/arch/x86/kvm/vmx/nested.c
> > > @@ -7004,7 +7004,8 @@ static void nested_vmx_setup_exit_ctls(struct vmcs_config *vmcs_conf,
> > >               VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR |
> > >               VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER |
> > >               VM_EXIT_SAVE_VMX_PREEMPTION_TIMER | VM_EXIT_ACK_INTR_ON_EXIT |
> > > -             VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
> > > +             VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
> > > +             VM_EXIT_SAVE_IA32_PERF_GLOBAL_CTRL;

This is completely wrong.  Stuffing VM_EXIT_SAVE_IA32_PERF_GLOBAL_CTRL here
advertises support for KVM emulation of the control, and that support is non-existent
in this patch (and series).

Just drop this, emulation of VM_EXIT_SAVE_IA32_PERF_GLOBAL_CTRL can be done
separately.

> > > +     mediated = kvm_mediated_pmu_enabled(vcpu);
> > > +     if (cpu_has_load_perf_global_ctrl()) {
> > > +             vm_entry_controls_changebit(vmx,
> > > +                     VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL, mediated);
> > > +             /*
> > > +              * Initialize guest PERF_GLOBAL_CTRL to reset value as SDM rules.
> > > +              *
> > > +              * Note: GUEST_IA32_PERF_GLOBAL_CTRL must be initialized to
> > > +              * "BIT_ULL(pmu->nr_arch_gp_counters) - 1" instead of pmu->global_ctrl
> > > +              * since pmu->global_ctrl is only be initialized when guest
> > > +              * pmu->version > 1. Otherwise if pmu->version is 1, pmu->global_ctrl
> > > +              * is 0 and guest counters are never really enabled.
> > > +              */
> > > +             if (mediated)
> > > +                     vmcs_write64(GUEST_IA32_PERF_GLOBAL_CTRL,
> > > +                                  BIT_ULL(pmu->nr_arch_gp_counters) - 1);

This belongs in common code, as a call to the aforementioned hook to propagate
PERF_GLOBAL_CTRL to hardware.

> > > +     }
> > > +
> > > +     if (cpu_has_save_perf_global_ctrl())
> > > +             vm_exit_controls_changebit(vmx,
> > > +                     VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
> > > +                     VM_EXIT_SAVE_IA32_PERF_GLOBAL_CTRL, mediated);
> > >  }
> > >
> > >  static void intel_pmu_init(struct kvm_vcpu *vcpu)
> > > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> > > index ff66f17d6358..38ecf3c116bd 100644
> > > --- a/arch/x86/kvm/vmx/vmx.c
> > > +++ b/arch/x86/kvm/vmx/vmx.c
> > > @@ -4390,6 +4390,13 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
> > >
> > >       if (cpu_has_load_ia32_efer())
> > >               vmcs_write64(HOST_IA32_EFER, kvm_host.efer);
> > > +
> > > +     /*
> > > +      * Initialize host PERF_GLOBAL_CTRL to 0 to disable all counters
> > > +      * immediately once VM exits. Mediated vPMU then call perf_guest_exit()
> > > +      * to re-enable host perf events.
> > > +      */
> > > +     vmcs_write64(HOST_IA32_PERF_GLOBAL_CTRL, 0);

This needs to be conditioned on the mediated PMU being enabled, because this field
is not constant when using the emulated PMU (or no vPMU).

> > > @@ -8451,6 +8462,15 @@ __init int vmx_hardware_setup(void)
> > >               enable_sgx = false;
> > >  #endif
> > >
> > > +     /*
> > > +      * All CPUs that support a mediated PMU are expected to support loading
> > > +      * and saving PERF_GLOBAL_CTRL via dedicated VMCS fields.
> > > +      */
> > > +     if (enable_mediated_pmu &&
> > > +         (WARN_ON_ONCE(!cpu_has_load_perf_global_ctrl() ||
> > > +                       !cpu_has_save_perf_global_ctrl())))

This needs to be conditioned on !HYPERVISOR, or it *will* fire.

And placing this check here, without *any* mention of *why* you did so, is evil
and made me very grumpy.  I had to discover the hard way that you checked the
VMCS fields here, instead of in kvm_init_pmu_capability() where it logically
belongs, because the VMCS configuration isn't yet initialized.

Grumpiness aside, I don't like this late clear of enable_mediated_pmu, as it risks
a variation of the problem you're trying to avoid, i.e. risks consuming the variable
between kvm_init_pmu_capability() and here.

I don't see any reason why setup_vmcs_config() can't be called before
kvm_x86_vendor_init(), so unless I'm missing/forgetting something, let's just do
that, and move these checks where they belong.

  reply	other threads:[~2025-05-15  0:33 UTC|newest]

Thread overview: 128+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-24 17:30 [PATCH v4 00/38] Mediated vPMU 4.0 for x86 Mingwei Zhang
2025-03-24 17:30 ` [PATCH v4 01/38] perf: Support get/put mediated PMU interfaces Mingwei Zhang
2025-05-14 22:48   ` Sean Christopherson
2025-05-15  1:31     ` Mi, Dapeng
2025-03-24 17:30 ` [PATCH v4 02/38] perf: Skip pmu_ctx based on event_type Mingwei Zhang
2025-03-24 17:30 ` [PATCH v4 03/38] perf: Clean up perf ctx time Mingwei Zhang
2025-03-24 17:30 ` [PATCH v4 04/38] perf: Add a EVENT_GUEST flag Mingwei Zhang
2025-05-14 22:51   ` Sean Christopherson
2025-05-15  1:35     ` Mi, Dapeng
2025-05-19  6:58   ` Namhyung Kim
2025-05-20 16:09     ` Liang, Kan
2025-05-20 17:51       ` Namhyung Kim
2025-05-20 18:50         ` Liang, Kan
2025-05-21 19:46   ` Namhyung Kim
2025-03-24 17:30 ` [PATCH v4 05/38] perf: Add generic exclude_guest support Mingwei Zhang
2025-04-25 11:13   ` Peter Zijlstra
2025-05-14 23:19     ` Sean Christopherson
2025-05-15  1:37       ` Mi, Dapeng
2025-05-15 18:39       ` Liang, Kan
2025-05-15 19:25         ` Sean Christopherson
2025-05-15 20:18           ` Liang, Kan
2025-05-21 19:55   ` Namhyung Kim
2025-05-21 20:12     ` Liang, Kan
2025-03-24 17:30 ` [PATCH v4 06/38] x86/irq: Factor out common code for installing kvm irq handler Mingwei Zhang
2025-05-14 23:21   ` Sean Christopherson
2025-05-15  2:10     ` Mi, Dapeng
2025-03-24 17:30 ` [PATCH v4 07/38] perf: core/x86: Register a new vector for KVM GUEST PMI Mingwei Zhang
2025-05-14 23:24   ` Sean Christopherson
2025-05-15  1:40     ` Mi, Dapeng
2025-03-24 17:30 ` [PATCH v4 08/38] KVM: x86/pmu: Register KVM_GUEST_PMI_VECTOR handler Mingwei Zhang
2025-03-24 17:30 ` [PATCH v4 09/38] perf: Add switch_guest_ctx() interface Mingwei Zhang
2025-04-25 11:12   ` Peter Zijlstra
2025-05-14 23:30   ` Sean Christopherson
2025-05-15  1:45     ` Mi, Dapeng
2025-05-21 20:01   ` Namhyung Kim
2025-03-24 17:30 ` [PATCH v4 10/38] perf/x86: Support switch_guest_ctx interface Mingwei Zhang
2025-04-25 11:15   ` Peter Zijlstra
2025-04-25 13:06     ` Liang, Kan
2025-04-25 13:43       ` Peter Zijlstra
2025-04-25 13:56         ` Liang, Kan
2025-07-30  0:31           ` Sean Christopherson
2025-03-24 17:30 ` [PATCH v4 11/38] perf/x86: Forbid PMI handler when guest own PMU Mingwei Zhang
2025-05-15  0:00   ` Sean Christopherson
2025-05-15  1:52     ` Mi, Dapeng
2025-03-24 17:30 ` [PATCH v4 12/38] perf/x86/core: Do not set bit width for unavailable counters Mingwei Zhang
2025-03-24 17:30 ` [PATCH v4 13/38] perf/x86/core: Plumb mediated PMU capability from x86_pmu to x86_pmu_cap Mingwei Zhang
2025-03-24 17:30 ` [PATCH v4 14/38] KVM: x86/pmu: Introduce enable_mediated_pmu global parameter Mingwei Zhang
2025-05-15  0:09   ` Sean Christopherson
2025-05-15  2:53     ` Mi, Dapeng
2025-05-21 18:43       ` Sean Christopherson
2025-05-22  1:36         ` Mi, Dapeng
2025-03-24 17:30 ` [PATCH v4 15/38] KVM: x86/pmu: Check PMU cpuid configuration from user space Mingwei Zhang
2025-05-15  0:12   ` Sean Christopherson
2025-05-15  3:00     ` Mi, Dapeng
2025-03-24 17:30 ` [PATCH v4 16/38] KVM: x86: Rename vmx_vmentry/vmexit_ctrl() helpers Mingwei Zhang
2025-03-24 17:30 ` [PATCH v4 17/38] KVM: x86/pmu: Add perf_capabilities field in struct kvm_host_values{} Mingwei Zhang
2025-05-15  0:12   ` Sean Christopherson
2025-05-15  3:04     ` Mi, Dapeng
2025-03-24 17:30 ` [PATCH v4 18/38] KVM: x86/pmu: Move PMU_CAP_{FW_WRITES,LBR_FMT} into msr-index.h header Mingwei Zhang
2025-03-24 17:30 ` [PATCH v4 19/38] KVM: VMX: Add macros to wrap around {secondary,tertiary}_exec_controls_changebit() Mingwei Zhang
2025-03-24 17:31 ` [PATCH v4 20/38] KVM: x86/pmu: Check if mediated vPMU can intercept rdpmc Mingwei Zhang
2025-05-15  0:19   ` Sean Christopherson
2025-05-15  3:23     ` Mi, Dapeng
2025-05-26  6:15   ` Sandipan Das
2025-07-09 15:53     ` Sean Christopherson
2025-07-29  3:29       ` Mi, Dapeng
2025-07-30  0:38         ` Sean Christopherson
2025-07-30  2:25           ` Mi, Dapeng
2025-08-01 23:32             ` Sean Christopherson
2025-08-05  0:54               ` Sean Christopherson
2025-08-06  0:50                 ` Sean Christopherson
2025-03-24 17:31 ` [PATCH v4 21/38] KVM: x86/pmu/vmx: Save/load guest IA32_PERF_GLOBAL_CTRL with vm_exit/entry_ctrl Mingwei Zhang
2025-03-26 16:51   ` Chen, Zide
2025-03-26 20:09     ` Mingwei Zhang
2025-05-15  0:33       ` Sean Christopherson [this message]
2025-05-15  3:45         ` Mi, Dapeng
2025-03-24 17:31 ` [PATCH v4 22/38] KVM: x86/pmu: Optimize intel/amd_pmu_refresh() helpers Mingwei Zhang
2025-05-15  0:37   ` Sean Christopherson
2025-05-15  5:09     ` Mi, Dapeng
2025-05-15 19:22       ` Sean Christopherson
2025-05-16  1:03         ` Mi, Dapeng
2025-03-24 17:31 ` [PATCH v4 23/38] KVM: x86/pmu: Configure the interception of PMU MSRs Mingwei Zhang
2025-05-15  0:41   ` Sean Christopherson
2025-05-15  5:37     ` Mi, Dapeng
2025-05-15 19:06       ` Sean Christopherson
2025-05-16 13:34   ` Sean Christopherson
2025-05-19  5:18     ` Mi, Dapeng
2025-03-24 17:31 ` [PATCH v4 24/38] KVM: x86/pmu: Exclude PMU MSRs in vmx_get_passthrough_msr_slot() Mingwei Zhang
2025-05-16 13:35   ` Sean Christopherson
2025-05-16 14:45     ` Sean Christopherson
2025-05-19  5:21       ` Mi, Dapeng
2025-03-24 17:31 ` [PATCH v4 25/38] KVM: x86/pmu: Add AMD PMU registers to direct access list Mingwei Zhang
2025-05-16 13:36   ` Sean Christopherson
2025-03-24 17:31 ` [PATCH v4 26/38] KVM: x86/pmu: Introduce eventsel_hw to prepare for pmu event filtering Mingwei Zhang
2025-05-15  0:42   ` Sean Christopherson
2025-05-15  5:34     ` Mi, Dapeng
2025-03-24 17:31 ` [PATCH v4 27/38] KVM: x86/pmu: Handle PMU MSRs interception and " Mingwei Zhang
2025-05-15  0:43   ` Sean Christopherson
2025-05-15  5:38     ` Mi, Dapeng
2025-05-16  1:26   ` Mi, Dapeng
2025-05-16 20:54     ` Sean Christopherson
2025-05-19  4:16       ` Mi, Dapeng
2025-03-24 17:31 ` [PATCH v4 28/38] KVM: x86/pmu/svm: Set GuestOnly bit and clear HostOnly bit when guest writes to event selectors Mingwei Zhang
2025-03-24 17:31 ` [PATCH v4 29/38] KVM: x86/pmu: Switch host/guest PMU context at vm-exit/vm-entry Mingwei Zhang
2025-05-15 16:29   ` Sean Christopherson
2025-05-16  2:37     ` Mi, Dapeng
2025-05-16 13:26   ` Sean Christopherson
2025-05-19  5:07     ` Mi, Dapeng
2025-03-24 17:31 ` [PATCH v4 30/38] KVM: x86/pmu: Handle emulated instruction for mediated vPMU Mingwei Zhang
2025-05-16  1:10   ` Sean Christopherson
2025-03-24 17:31 ` [PATCH v4 31/38] KVM: nVMX: Add macros to simplify nested MSR interception setting Mingwei Zhang
2025-03-24 17:31 ` [PATCH v4 32/38] KVM: nVMX: Add nested virtualization support for mediated PMU Mingwei Zhang
2025-05-16 13:33   ` Sean Christopherson
2025-05-19  5:24     ` Mi, Dapeng
2025-03-24 17:31 ` [PATCH v4 33/38] perf/x86/intel: Support PERF_PMU_CAP_MEDIATED_VPMU Mingwei Zhang
2025-03-24 17:31 ` [PATCH v4 34/38] perf/x86/amd: Support PERF_PMU_CAP_MEDIATED_VPMU for AMD host Mingwei Zhang
2025-05-21 20:00   ` Namhyung Kim
2025-03-24 17:31 ` [PATCH v4 35/38] KVM: x86/pmu: Expose enable_mediated_pmu parameter to user space Mingwei Zhang
2025-03-24 17:31 ` [PATCH v4 36/38] KVM: selftests: Add mediated vPMU supported for pmu tests Mingwei Zhang
2025-03-24 17:31 ` [PATCH v4 37/38] KVM: Selftests: Support mediated vPMU for vmx_pmu_caps_test Mingwei Zhang
2025-03-24 17:31 ` [PATCH v4 38/38] KVM: Selftests: Fix pmu_counters_test error for mediated vPMU Mingwei Zhang
2025-04-16  7:22 ` [PATCH v4 00/38] Mediated vPMU 4.0 for x86 Mi, Dapeng
2025-04-25 12:27   ` Peter Zijlstra
2025-05-06  9:57 ` Mi, Dapeng
2025-05-06 19:45   ` Sean Christopherson
2025-05-07  0:46     ` Mi, Dapeng
2025-05-15  0:49 ` Sean Christopherson
2025-05-15  5:45   ` Mi, Dapeng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aCU2YEpU0dOk7RTk@google.com \
    --to=seanjc@google.com \
    --cc=Liang@google.com \
    --cc=Manali.Shukla@amd.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=dapeng1.mi@linux.intel.com \
    --cc=eranian@google.com \
    --cc=hpa@zytor.com \
    --cc=irogers@google.com \
    --cc=jmattson@google.com \
    --cc=jolsa@kernel.org \
    --cc=kan.liang@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mingo@redhat.com \
    --cc=mizhang@google.com \
    --cc=namhyung@kernel.org \
    --cc=nikunj.dadhania@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=sandipan.das@amd.com \
    --cc=xiong.y.zhang@linux.intel.com \
    --cc=yongwei.ma@intel.com \
    --cc=zide.chen@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).