[PATCH 0/4] Part of fix for host and guest LBR event coexist

From: Xiong Zhang
Date: Fri Jun 16 2023 - 07:34:58 EST


Perf has four types of events: per cpu pinned event, per process pinned
event, per cpu event, per process event, their priority are from high to
low. This means higher priority event could premmpt lower prority event
and owns hardware resource. Perf scheduler activates an event on specific
cpu through sending ipi to the target cpu.

When guest access LBR msr at the first time, kvm will create a per process
pinned vLBR event which take part in perf scheduler. When vLBR event is
active, LBR will be owned by guest and guest could access LBR msr. When
vLBR event is inactive, LBR is ownned by host and guest couldn't access LBR
msr.

But current vLBR event is always active even if LBR is owned by host higher
prority per cpu pinned LBR event, this violates perf scheduler's rule. vLBR
event is a kind of perf event and doesn't have any special for perf
scheduler, it should follow perf scheduler's rule.

This patchset try to fix this violation, make vLBR event not break host,
and expects the following results when host and guest LBR event coexist:
1. If host per cpu pinned LBR event is active when vm starts, guest vLBR
event couldn't preempt LBR, so guest couldn't use LBR.
2. If host other LBR events are active when vm starts, guest vLBR event
could preempt LBR, so guest could use LBR.
3. If host per cpu pinned LBR event begin active when guest vLBR event is
active, guest vLBR event will lose LBR and guest couldn't use LBR anymore.
4. If host other LBR events begin active when guest vLBR event is active,
guest vLBR event keeps LBR, guest could still use LBR.
5. If host per cpu pinned LBR event becomes inactive when guest vLBR event
is inactive, guest vLBR event could be active and own LBR, so guest could
use LBR.

In the first three commits, each commit fix an issue when host and guest
LBR coexist, the fourth commit add a kernel selftests to cover the above
cases when host and guest LBR coexist.

Even with this patchset, the coexist of host and guest perf LBR events
still has gap, actually this gap exists in vPMU arch when host and guest
perf event coexist, kvm guest perf event could be inactive in two cases:
1. Counter or hw resource is full at kvm guest perf event creataion.
2. host higher priority event preempts kvm guest perf event in vm exit
handler.
But current guest couldn't get any notification about these failure, and
guest think its PMU still works, then get wrong data. Maybe some PV
interface is needed.

Perf command to create per cpu pinned LBR event:
perf record -b -a -e instructions:D

Xiong Zhang (4):
perf/x86/intel: Get shared reg constraints first for vLBR
KVM: VMX/pmu: Save host debugctlmsr just before vm entry
KVM: vmx/pmu: Enable inactive vLBR event in guest LBR MSR emulation
KVM:X86:selftests: Add test case for guest and host LBR preemption

arch/x86/events/intel/core.c | 6 +-
arch/x86/kvm/vmx/pmu_intel.c | 9 +-
arch/x86/kvm/vmx/vmx.c | 5 +-
tools/testing/selftests/kvm/Makefile | 1 +
.../selftests/kvm/include/ucall_common.h | 17 ++
.../kvm/x86_64/pmu_event_filter_test.c | 16 --
.../kvm/x86_64/vmx_pmu_lbr_contend.c | 171 ++++++++++++++++++
7 files changed, 201 insertions(+), 24 deletions(-)
create mode 100644 tools/testing/selftests/kvm/x86_64/vmx_pmu_lbr_contend.c

--
2.25.1