On Mon, Jan 04, 2021, Like Xu wrote: > When CPUID.01H:EDX.DS[21] is set, the IA32_DS_AREA MSR exists and > points to the linear address of the first byte of the DS buffer > management area, which is used to manage the PEBS records. > > When guest PEBS is enabled and the value is different from the > host, KVM will add the IA32_DS_AREA MSR to the msr-switch list. > The guest's DS value can be loaded to the real HW before VM-entry, > and will be removed when guest PEBS is disabled. > > The WRMSR to IA32_DS_AREA MSR brings a #GP(0) if the source register > contains a non-canonical address. The switch of IA32_DS_AREA MSR would > also, setup a quiescent period to write the host PEBS records (if any) > to host DS area rather than guest DS area. > > When guest PEBS is enabled, the MSR_IA32_DS_AREA MSR will be > added to the perf_guest_switch_msr() and switched during the > VMX transitions just like CORE_PERF_GLOBAL_CTRL MSR. > > Originally-by: Andi Kleen <ak@xxxxxxxxxxxxxxx> > Co-developed-by: Kan Liang <kan.liang@xxxxxxxxxxxxxxx> > Signed-off-by: Kan Liang <kan.liang@xxxxxxxxxxxxxxx> > Signed-off-by: Like Xu <like.xu@xxxxxxxxxxxxxxx> > --- > arch/x86/events/intel/core.c | 13 +++++++++++++ > arch/x86/include/asm/kvm_host.h | 1 + > arch/x86/kvm/vmx/pmu_intel.c | 11 +++++++++++ > arch/x86/kvm/vmx/vmx.c | 6 ++++++ > 4 files changed, 31 insertions(+) > > diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c > index 6453b8a6834a..ccddda455bec 100644 > --- a/arch/x86/events/intel/core.c > +++ b/arch/x86/events/intel/core.c > @@ -3690,6 +3690,7 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr) > { > struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs; > + struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds); > > arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL; > arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask; > @@ -3735,6 +3736,18 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr) > *nr = 2; > } > > + if (arr[1].guest) { > + arr[2].msr = MSR_IA32_DS_AREA; > + arr[2].host = (unsigned long)ds; > + /* KVM will update MSR_IA32_DS_AREA with the trapped guest value. */ > + arr[2].guest = 0ull; > + *nr = 3; > + } else if (*nr == 2) { > + arr[2].msr = MSR_IA32_DS_AREA; > + arr[2].host = arr[2].guest = 0; > + *nr = 3; > + } Similar comments as the previous patch, please figure out a way to properly integrate this into the PEBS logic instead of querying arr/nr. > + > return arr; > }