mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'kvm-x86-pmu-6.20' of https://github.com/kvm-x86/linux into HEAD
KVM mediated PMU support for 6.20 Add support for mediated PMUs, where KVM gives the guest full ownership of PMU hardware (contexted switched around the fastpath run loop) and allows direct access to data MSRs and PMCs (restricted by the vPMU model), but intercepts access to control registers, e.g. to enforce event filtering and to prevent the guest from profiling sensitive host state. To keep overall complexity reasonable, mediated PMU usage is all or nothing for a given instance of KVM (controlled via module param). The Mediated PMU is disabled default, partly to maintain backwards compatilibity for existing setup, partly because there are tradeoffs when running with a mediated PMU that may be non-starters for some use cases, e.g. the host loses the ability to profile guests with mediated PMUs, the fastpath run loop is also a blind spot, entry/exit transitions are more expensive, etc. Versus the emulated PMU, where KVM is "just another perf user", the mediated PMU delivers more accurate profiling and monitoring (no risk of contention and thus dropped events), with significantly less overhead (fewer exits and faster emulation/programming of event selectors) E.g. when running Specint-2017 on a single-socket Sapphire Rapids with 56 cores and no-SMT, and using perf from within the guest: Perf command: a. basic-sampling: perf record -F 1000 -e 6-instructions -a --overwrite b. multiplex-sampling: perf record -F 1000 -e 10-instructions -a --overwrite Guest performance overhead: --------------------------------------------------------------------------- | Test case | emulated vPMU | all passthrough | passthrough with | | | | | event filters | --------------------------------------------------------------------------- | basic-sampling | 33.62% | 4.24% | 6.21% | --------------------------------------------------------------------------- | multiplex-sampling | 79.32% | 7.34% | 10.45% | ---------------------------------------------------------------------------
This commit is contained in:
@@ -3079,6 +3079,26 @@ Kernel parameters
|
||||
|
||||
Default is Y (on).
|
||||
|
||||
kvm.enable_pmu=[KVM,X86]
|
||||
If enabled, KVM will virtualize PMU functionality based
|
||||
on the virtual CPU model defined by userspace. This
|
||||
can be overridden on a per-VM basis via
|
||||
KVM_CAP_PMU_CAPABILITY.
|
||||
|
||||
If disabled, KVM will not virtualize PMU functionality,
|
||||
e.g. MSRs, PMCs, PMIs, etc., even if userspace defines
|
||||
a virtual CPU model that contains PMU assets.
|
||||
|
||||
Note, KVM's vPMU support implicitly requires running
|
||||
with an in-kernel local APIC, e.g. to deliver PMIs to
|
||||
the guest. Running without an in-kernel local APIC is
|
||||
not supported, though KVM will allow such a combination
|
||||
(with severely degraded functionality).
|
||||
|
||||
See also enable_mediated_pmu.
|
||||
|
||||
Default is Y (on).
|
||||
|
||||
kvm.enable_virt_at_load=[KVM,ARM64,LOONGARCH,MIPS,RISCV,X86]
|
||||
If enabled, KVM will enable virtualization in hardware
|
||||
when KVM is loaded, and disable virtualization when KVM
|
||||
@@ -3125,6 +3145,35 @@ Kernel parameters
|
||||
If the value is 0 (the default), KVM will pick a period based
|
||||
on the ratio, such that a page is zapped after 1 hour on average.
|
||||
|
||||
kvm-{amd,intel}.enable_mediated_pmu=[KVM,AMD,INTEL]
|
||||
If enabled, KVM will provide a mediated virtual PMU,
|
||||
instead of the default perf-based virtual PMU (if
|
||||
kvm.enable_pmu is true and PMU is enumerated via the
|
||||
virtual CPU model).
|
||||
|
||||
With a perf-based vPMU, KVM operates as a user of perf,
|
||||
i.e. emulates guest PMU counters using perf events.
|
||||
KVM-created perf events are managed by perf as regular
|
||||
(guest-only) events, e.g. are scheduled in/out, contend
|
||||
for hardware resources, etc. Using a perf-based vPMU
|
||||
allows guest and host usage of the PMU to co-exist, but
|
||||
incurs non-trivial overhead and can result in silently
|
||||
dropped guest events (due to resource contention).
|
||||
|
||||
With a mediated vPMU, hardware PMU state is context
|
||||
switched around the world switch to/from the guest.
|
||||
KVM mediates which events the guest can utilize, but
|
||||
gives the guest direct access to all other PMU assets
|
||||
when possible (KVM may intercept some accesses if the
|
||||
virtual CPU model provides a subset of hardware PMU
|
||||
functionality). Using a mediated vPMU significantly
|
||||
reduces PMU virtualization overhead and eliminates lost
|
||||
guest events, but is mutually exclusive with using perf
|
||||
to profile KVM guests and adds latency to most VM-Exits
|
||||
(to context switch PMU state).
|
||||
|
||||
Default is N (off).
|
||||
|
||||
kvm-amd.nested= [KVM,AMD] Control nested virtualization feature in
|
||||
KVM/SVM. Default is 1 (enabled).
|
||||
|
||||
|
||||
@@ -2413,7 +2413,7 @@ static int __init init_subsystems(void)
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
kvm_register_perf_callbacks(NULL);
|
||||
kvm_register_perf_callbacks();
|
||||
|
||||
out:
|
||||
if (err)
|
||||
|
||||
@@ -402,7 +402,7 @@ static int kvm_loongarch_env_init(void)
|
||||
}
|
||||
|
||||
kvm_init_gcsr_flag();
|
||||
kvm_register_perf_callbacks(NULL);
|
||||
kvm_register_perf_callbacks();
|
||||
|
||||
/* Register LoongArch IPI interrupt controller interface. */
|
||||
ret = kvm_loongarch_register_ipi_device();
|
||||
|
||||
@@ -174,7 +174,7 @@ static int __init riscv_kvm_init(void)
|
||||
|
||||
kvm_riscv_setup_vendor_features();
|
||||
|
||||
kvm_register_perf_callbacks(NULL);
|
||||
kvm_register_perf_callbacks();
|
||||
|
||||
rc = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
|
||||
if (rc) {
|
||||
|
||||
@@ -114,6 +114,7 @@ static idtentry_t sysvec_table[NR_SYSTEM_VECTORS] __ro_after_init = {
|
||||
|
||||
SYSVEC(IRQ_WORK_VECTOR, irq_work),
|
||||
|
||||
SYSVEC(PERF_GUEST_MEDIATED_PMI_VECTOR, perf_guest_mediated_pmi_handler),
|
||||
SYSVEC(POSTED_INTR_VECTOR, kvm_posted_intr_ipi),
|
||||
SYSVEC(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi),
|
||||
SYSVEC(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi),
|
||||
|
||||
@@ -1439,6 +1439,8 @@ static int __init amd_core_pmu_init(void)
|
||||
|
||||
amd_pmu_global_cntr_mask = x86_pmu.cntr_mask64;
|
||||
|
||||
x86_get_pmu(smp_processor_id())->capabilities |= PERF_PMU_CAP_MEDIATED_VPMU;
|
||||
|
||||
/* Update PMC handling functions */
|
||||
x86_pmu.enable_all = amd_pmu_v2_enable_all;
|
||||
x86_pmu.disable_all = amd_pmu_v2_disable_all;
|
||||
|
||||
+36
-2
@@ -30,6 +30,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/nospec.h>
|
||||
#include <linux/static_call.h>
|
||||
#include <linux/kvm_types.h>
|
||||
|
||||
#include <asm/apic.h>
|
||||
#include <asm/stacktrace.h>
|
||||
@@ -56,6 +57,8 @@ DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
|
||||
.pmu = &pmu,
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(bool, guest_lvtpc_loaded);
|
||||
|
||||
DEFINE_STATIC_KEY_FALSE(rdpmc_never_available_key);
|
||||
DEFINE_STATIC_KEY_FALSE(rdpmc_always_available_key);
|
||||
DEFINE_STATIC_KEY_FALSE(perf_is_hybrid);
|
||||
@@ -1760,6 +1763,25 @@ void perf_events_lapic_init(void)
|
||||
apic_write(APIC_LVTPC, APIC_DM_NMI);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PERF_GUEST_MEDIATED_PMU
|
||||
void perf_load_guest_lvtpc(u32 guest_lvtpc)
|
||||
{
|
||||
u32 masked = guest_lvtpc & APIC_LVT_MASKED;
|
||||
|
||||
apic_write(APIC_LVTPC,
|
||||
APIC_DM_FIXED | PERF_GUEST_MEDIATED_PMI_VECTOR | masked);
|
||||
this_cpu_write(guest_lvtpc_loaded, true);
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM(perf_load_guest_lvtpc);
|
||||
|
||||
void perf_put_guest_lvtpc(void)
|
||||
{
|
||||
this_cpu_write(guest_lvtpc_loaded, false);
|
||||
apic_write(APIC_LVTPC, APIC_DM_NMI);
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM(perf_put_guest_lvtpc);
|
||||
#endif /* CONFIG_PERF_GUEST_MEDIATED_PMU */
|
||||
|
||||
static int
|
||||
perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)
|
||||
{
|
||||
@@ -1767,6 +1789,17 @@ perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)
|
||||
u64 finish_clock;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Ignore all NMIs when the CPU's LVTPC is configured to route PMIs to
|
||||
* PERF_GUEST_MEDIATED_PMI_VECTOR, i.e. when an NMI time can't be due
|
||||
* to a PMI. Attempting to handle a PMI while the guest's context is
|
||||
* loaded will generate false positives and clobber guest state. Note,
|
||||
* the LVTPC is switched to/from the dedicated mediated PMI IRQ vector
|
||||
* while host events are quiesced.
|
||||
*/
|
||||
if (this_cpu_read(guest_lvtpc_loaded))
|
||||
return NMI_DONE;
|
||||
|
||||
/*
|
||||
* All PMUs/events that share this PMI handler should make sure to
|
||||
* increment active_events for their events.
|
||||
@@ -3073,11 +3106,12 @@ void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
|
||||
cap->version = x86_pmu.version;
|
||||
cap->num_counters_gp = x86_pmu_num_counters(NULL);
|
||||
cap->num_counters_fixed = x86_pmu_num_counters_fixed(NULL);
|
||||
cap->bit_width_gp = x86_pmu.cntval_bits;
|
||||
cap->bit_width_fixed = x86_pmu.cntval_bits;
|
||||
cap->bit_width_gp = cap->num_counters_gp ? x86_pmu.cntval_bits : 0;
|
||||
cap->bit_width_fixed = cap->num_counters_fixed ? x86_pmu.cntval_bits : 0;
|
||||
cap->events_mask = (unsigned int)x86_pmu.events_maskl;
|
||||
cap->events_mask_len = x86_pmu.events_mask_len;
|
||||
cap->pebs_ept = x86_pmu.pebs_ept;
|
||||
cap->mediated = !!(pmu.capabilities & PERF_PMU_CAP_MEDIATED_VPMU);
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM(perf_get_x86_pmu_capability);
|
||||
|
||||
|
||||
@@ -5695,6 +5695,8 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)
|
||||
else
|
||||
pmu->intel_ctrl &= ~GLOBAL_CTRL_EN_PERF_METRICS;
|
||||
|
||||
pmu->pmu.capabilities |= PERF_PMU_CAP_MEDIATED_VPMU;
|
||||
|
||||
intel_pmu_check_event_constraints_all(&pmu->pmu);
|
||||
|
||||
intel_pmu_check_extra_regs(pmu->extra_regs);
|
||||
@@ -7314,6 +7316,9 @@ __init int intel_pmu_init(void)
|
||||
pr_cont(" AnyThread deprecated, ");
|
||||
}
|
||||
|
||||
/* The perf side of core PMU is ready to support the mediated vPMU. */
|
||||
x86_get_pmu(smp_processor_id())->capabilities |= PERF_PMU_CAP_MEDIATED_VPMU;
|
||||
|
||||
/*
|
||||
* Many features on and after V6 require dynamic constraint,
|
||||
* e.g., Arch PEBS, ACR.
|
||||
@@ -7405,6 +7410,7 @@ __init int intel_pmu_init(void)
|
||||
case INTEL_ATOM_SILVERMONT_D:
|
||||
case INTEL_ATOM_SILVERMONT_MID:
|
||||
case INTEL_ATOM_AIRMONT:
|
||||
case INTEL_ATOM_AIRMONT_NP:
|
||||
case INTEL_ATOM_SILVERMONT_MID2:
|
||||
memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
|
||||
sizeof(hw_cache_event_ids));
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
* MSR_CORE_C1_RES: CORE C1 Residency Counter
|
||||
* perf code: 0x00
|
||||
* Available model: SLM,AMT,GLM,CNL,ICX,TNT,ADL,RPL
|
||||
* MTL,SRF,GRR,ARL,LNL,PTL
|
||||
* MTL,SRF,GRR,ARL,LNL,PTL,WCL,NVL
|
||||
* Scope: Core (each processor core has a MSR)
|
||||
* MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
|
||||
* perf code: 0x01
|
||||
@@ -53,19 +53,20 @@
|
||||
* Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
|
||||
* SKL,KNL,GLM,CNL,KBL,CML,ICL,ICX,
|
||||
* TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF,
|
||||
* GRR,ARL,LNL,PTL
|
||||
* GRR,ARL,LNL,PTL,WCL,NVL
|
||||
* Scope: Core
|
||||
* MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
|
||||
* perf code: 0x03
|
||||
* Available model: SNB,IVB,HSW,BDW,SKL,CNL,KBL,CML,
|
||||
* ICL,TGL,RKL,ADL,RPL,MTL,ARL,LNL,
|
||||
* PTL
|
||||
* PTL,WCL,NVL
|
||||
* Scope: Core
|
||||
* MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter.
|
||||
* perf code: 0x00
|
||||
* Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL,
|
||||
* KBL,CML,ICL,ICX,TGL,TNT,RKL,ADL,
|
||||
* RPL,SPR,MTL,ARL,LNL,SRF,PTL
|
||||
* RPL,SPR,MTL,ARL,LNL,SRF,PTL,WCL,
|
||||
* NVL
|
||||
* Scope: Package (physical package)
|
||||
* MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter.
|
||||
* perf code: 0x01
|
||||
@@ -78,7 +79,7 @@
|
||||
* Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
|
||||
* SKL,KNL,GLM,CNL,KBL,CML,ICL,ICX,
|
||||
* TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF,
|
||||
* ARL,LNL,PTL
|
||||
* ARL,LNL,PTL,WCL,NVL
|
||||
* Scope: Package (physical package)
|
||||
* MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter.
|
||||
* perf code: 0x03
|
||||
@@ -97,11 +98,12 @@
|
||||
* MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
|
||||
* perf code: 0x06
|
||||
* Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL,
|
||||
* TNT,RKL,ADL,RPL,MTL,ARL,LNL,PTL
|
||||
* TNT,RKL,ADL,RPL,MTL,ARL,LNL,PTL,
|
||||
* WCL,NVL
|
||||
* Scope: Package (physical package)
|
||||
* MSR_MODULE_C6_RES_MS: Module C6 Residency Counter.
|
||||
* perf code: 0x00
|
||||
* Available model: SRF,GRR
|
||||
* Available model: SRF,GRR,NVL
|
||||
* Scope: A cluster of cores shared L2 cache
|
||||
*
|
||||
*/
|
||||
@@ -527,6 +529,18 @@ static const struct cstate_model lnl_cstates __initconst = {
|
||||
BIT(PERF_CSTATE_PKG_C10_RES),
|
||||
};
|
||||
|
||||
static const struct cstate_model nvl_cstates __initconst = {
|
||||
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
|
||||
BIT(PERF_CSTATE_CORE_C6_RES) |
|
||||
BIT(PERF_CSTATE_CORE_C7_RES),
|
||||
|
||||
.module_events = BIT(PERF_CSTATE_MODULE_C6_RES),
|
||||
|
||||
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
|
||||
BIT(PERF_CSTATE_PKG_C6_RES) |
|
||||
BIT(PERF_CSTATE_PKG_C10_RES),
|
||||
};
|
||||
|
||||
static const struct cstate_model slm_cstates __initconst = {
|
||||
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
|
||||
BIT(PERF_CSTATE_CORE_C6_RES),
|
||||
@@ -599,6 +613,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, &slm_cstates),
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_D, &slm_cstates),
|
||||
X86_MATCH_VFM(INTEL_ATOM_AIRMONT, &slm_cstates),
|
||||
X86_MATCH_VFM(INTEL_ATOM_AIRMONT_NP, &slm_cstates),
|
||||
|
||||
X86_MATCH_VFM(INTEL_BROADWELL, &snb_cstates),
|
||||
X86_MATCH_VFM(INTEL_BROADWELL_D, &snb_cstates),
|
||||
@@ -638,6 +653,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
|
||||
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &icx_cstates),
|
||||
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &icx_cstates),
|
||||
X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, &icx_cstates),
|
||||
X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, &srf_cstates),
|
||||
|
||||
X86_MATCH_VFM(INTEL_TIGERLAKE_L, &icl_cstates),
|
||||
X86_MATCH_VFM(INTEL_TIGERLAKE, &icl_cstates),
|
||||
@@ -654,6 +670,9 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
|
||||
X86_MATCH_VFM(INTEL_ARROWLAKE_U, &adl_cstates),
|
||||
X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_cstates),
|
||||
X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &lnl_cstates),
|
||||
X86_MATCH_VFM(INTEL_WILDCATLAKE_L, &lnl_cstates),
|
||||
X86_MATCH_VFM(INTEL_NOVALAKE, &nvl_cstates),
|
||||
X86_MATCH_VFM(INTEL_NOVALAKE_L, &nvl_cstates),
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
|
||||
|
||||
@@ -78,6 +78,7 @@ static bool test_intel(int idx, void *data)
|
||||
case INTEL_ATOM_SILVERMONT:
|
||||
case INTEL_ATOM_SILVERMONT_D:
|
||||
case INTEL_ATOM_AIRMONT:
|
||||
case INTEL_ATOM_AIRMONT_NP:
|
||||
|
||||
case INTEL_ATOM_GOLDMONT:
|
||||
case INTEL_ATOM_GOLDMONT_D:
|
||||
|
||||
@@ -18,6 +18,9 @@ typedef struct {
|
||||
unsigned int kvm_posted_intr_ipis;
|
||||
unsigned int kvm_posted_intr_wakeup_ipis;
|
||||
unsigned int kvm_posted_intr_nested_ipis;
|
||||
#endif
|
||||
#ifdef CONFIG_GUEST_PERF_EVENTS
|
||||
unsigned int perf_guest_mediated_pmis;
|
||||
#endif
|
||||
unsigned int x86_platform_ipis; /* arch dependent */
|
||||
unsigned int apic_perf_irqs;
|
||||
|
||||
@@ -746,6 +746,12 @@ DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR, sysvec_kvm_posted_intr_nested
|
||||
# define fred_sysvec_kvm_posted_intr_nested_ipi NULL
|
||||
#endif
|
||||
|
||||
# ifdef CONFIG_GUEST_PERF_EVENTS
|
||||
DECLARE_IDTENTRY_SYSVEC(PERF_GUEST_MEDIATED_PMI_VECTOR, sysvec_perf_guest_mediated_pmi_handler);
|
||||
#else
|
||||
# define fred_sysvec_perf_guest_mediated_pmi_handler NULL
|
||||
#endif
|
||||
|
||||
# ifdef CONFIG_X86_POSTED_MSI
|
||||
DECLARE_IDTENTRY_SYSVEC(POSTED_MSI_NOTIFICATION_VECTOR, sysvec_posted_msi_notification);
|
||||
#else
|
||||
|
||||
@@ -77,7 +77,9 @@
|
||||
*/
|
||||
#define IRQ_WORK_VECTOR 0xf6
|
||||
|
||||
/* 0xf5 - unused, was UV_BAU_MESSAGE */
|
||||
/* IRQ vector for PMIs when running a guest with a mediated PMU. */
|
||||
#define PERF_GUEST_MEDIATED_PMI_VECTOR 0xf5
|
||||
|
||||
#define DEFERRED_ERROR_VECTOR 0xf4
|
||||
|
||||
/* Vector on which hypervisor callbacks will be delivered */
|
||||
|
||||
@@ -23,5 +23,9 @@ KVM_X86_PMU_OP_OPTIONAL(reset)
|
||||
KVM_X86_PMU_OP_OPTIONAL(deliver_pmi)
|
||||
KVM_X86_PMU_OP_OPTIONAL(cleanup)
|
||||
|
||||
KVM_X86_PMU_OP_OPTIONAL(write_global_ctrl)
|
||||
KVM_X86_PMU_OP(mediated_load)
|
||||
KVM_X86_PMU_OP(mediated_put)
|
||||
|
||||
#undef KVM_X86_PMU_OP
|
||||
#undef KVM_X86_PMU_OP_OPTIONAL
|
||||
|
||||
@@ -537,6 +537,7 @@ struct kvm_pmc {
|
||||
*/
|
||||
u64 emulated_counter;
|
||||
u64 eventsel;
|
||||
u64 eventsel_hw;
|
||||
struct perf_event *perf_event;
|
||||
struct kvm_vcpu *vcpu;
|
||||
/*
|
||||
@@ -565,6 +566,7 @@ struct kvm_pmu {
|
||||
unsigned nr_arch_fixed_counters;
|
||||
unsigned available_event_types;
|
||||
u64 fixed_ctr_ctrl;
|
||||
u64 fixed_ctr_ctrl_hw;
|
||||
u64 fixed_ctr_ctrl_rsvd;
|
||||
u64 global_ctrl;
|
||||
u64 global_status;
|
||||
@@ -1503,6 +1505,7 @@ struct kvm_arch {
|
||||
|
||||
bool bus_lock_detection_enabled;
|
||||
bool enable_pmu;
|
||||
bool created_mediated_pmu;
|
||||
|
||||
u32 notify_window;
|
||||
u32 notify_vmexit_flags;
|
||||
|
||||
@@ -1219,6 +1219,7 @@
|
||||
#define MSR_CORE_PERF_GLOBAL_STATUS 0x0000038e
|
||||
#define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f
|
||||
#define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390
|
||||
#define MSR_CORE_PERF_GLOBAL_STATUS_SET 0x00000391
|
||||
|
||||
#define MSR_PERF_METRICS 0x00000329
|
||||
|
||||
|
||||
@@ -301,6 +301,7 @@ struct x86_pmu_capability {
|
||||
unsigned int events_mask;
|
||||
int events_mask_len;
|
||||
unsigned int pebs_ept :1;
|
||||
unsigned int mediated :1;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -759,6 +760,11 @@ static inline void perf_events_lapic_init(void) { }
|
||||
static inline void perf_check_microcode(void) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PERF_GUEST_MEDIATED_PMU
|
||||
extern void perf_load_guest_lvtpc(u32 guest_lvtpc);
|
||||
extern void perf_put_guest_lvtpc(void);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
|
||||
extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr, void *data);
|
||||
extern void x86_perf_get_lbr(struct x86_pmu_lbr *lbr);
|
||||
|
||||
@@ -2,11 +2,23 @@
|
||||
#ifndef _ASM_X86_UNWIND_USER_H
|
||||
#define _ASM_X86_UNWIND_USER_H
|
||||
|
||||
#ifdef CONFIG_HAVE_UNWIND_USER_FP
|
||||
#ifdef CONFIG_UNWIND_USER
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/uprobes.h>
|
||||
|
||||
static inline int unwind_user_word_size(struct pt_regs *regs)
|
||||
{
|
||||
/* We can't unwind VM86 stacks */
|
||||
if (regs->flags & X86_VM_MASK)
|
||||
return 0;
|
||||
return user_64bit_mode(regs) ? 8 : 4;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_UNWIND_USER */
|
||||
|
||||
#ifdef CONFIG_HAVE_UNWIND_USER_FP
|
||||
|
||||
#define ARCH_INIT_USER_FP_FRAME(ws) \
|
||||
.cfa_off = 2*(ws), \
|
||||
.ra_off = -1*(ws), \
|
||||
@@ -19,22 +31,11 @@
|
||||
.fp_off = 0, \
|
||||
.use_fp = false,
|
||||
|
||||
static inline int unwind_user_word_size(struct pt_regs *regs)
|
||||
{
|
||||
/* We can't unwind VM86 stacks */
|
||||
if (regs->flags & X86_VM_MASK)
|
||||
return 0;
|
||||
#ifdef CONFIG_X86_64
|
||||
if (!user_64bit_mode(regs))
|
||||
return sizeof(int);
|
||||
#endif
|
||||
return sizeof(long);
|
||||
}
|
||||
|
||||
static inline bool unwind_user_at_function_start(struct pt_regs *regs)
|
||||
{
|
||||
return is_uprobe_at_func_entry(regs);
|
||||
}
|
||||
#define unwind_user_at_function_start unwind_user_at_function_start
|
||||
|
||||
#endif /* CONFIG_HAVE_UNWIND_USER_FP */
|
||||
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
#define VM_EXIT_PT_CONCEAL_PIP 0x01000000
|
||||
#define VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000
|
||||
#define VM_EXIT_LOAD_CET_STATE 0x10000000
|
||||
#define VM_EXIT_SAVE_IA32_PERF_GLOBAL_CTRL 0x40000000
|
||||
|
||||
#define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR 0x00036dff
|
||||
|
||||
|
||||
@@ -158,6 +158,9 @@ static const __initconst struct idt_data apic_idts[] = {
|
||||
INTG(POSTED_INTR_WAKEUP_VECTOR, asm_sysvec_kvm_posted_intr_wakeup_ipi),
|
||||
INTG(POSTED_INTR_NESTED_VECTOR, asm_sysvec_kvm_posted_intr_nested_ipi),
|
||||
# endif
|
||||
#ifdef CONFIG_GUEST_PERF_EVENTS
|
||||
INTG(PERF_GUEST_MEDIATED_PMI_VECTOR, asm_sysvec_perf_guest_mediated_pmi_handler),
|
||||
#endif
|
||||
# ifdef CONFIG_IRQ_WORK
|
||||
INTG(IRQ_WORK_VECTOR, asm_sysvec_irq_work),
|
||||
# endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user