arch/x86/kvm/vmx/pmu_intel.c
Source file repositories/reference/linux-study-clean/arch/x86/kvm/vmx/pmu_intel.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kvm/vmx/pmu_intel.c- Extension
.c- Size
- 25055 bytes
- Lines
- 862
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/types.hlinux/kvm_host.hlinux/perf_event.hasm/msr.hasm/perf_event.hasm/cpuid/api.hx86.hcpuid.hlapic.hnested.hpmu.htdx.h
Detected Declarations
function reprogram_fixed_countersfunction Purposefunction intel_pmu_lbr_is_compatiblefunction intel_pmu_lbr_is_enabledfunction intel_pmu_is_valid_lbr_msrfunction intel_is_valid_msrfunction intel_pmu_release_guest_lbr_eventfunction intel_pmu_create_guest_lbr_eventfunction intel_pmu_handle_lbr_msrs_accessfunction intel_pmu_get_msrfunction intel_pmu_set_msrfunction samefunction intel_pmu_enable_fixed_counter_bitsfunction intel_pmu_refreshfunction intel_pmu_initfunction intel_pmu_resetfunction bitfunction intel_pmu_deliver_pmifunction vmx_update_intercept_for_lbr_msrsfunction vmx_disable_lbr_msrs_passthroughfunction vmx_enable_lbr_msrs_passthroughfunction eventsfunction intel_pmu_cleanupfunction intel_pmu_cross_mapped_checkfunction kvm_for_each_pmcfunction intel_pmu_is_mediated_pmu_supportedfunction intel_pmu_write_global_ctrlfunction intel_mediated_pmu_loadfunction intel_mediated_pmu_put
Annotated Snippet
if (pmu->pebs_enable != data) {
diff = pmu->pebs_enable ^ data;
pmu->pebs_enable = data;
kvm_pmu_request_counters_reprogram(pmu, diff);
}
break;
case MSR_IA32_DS_AREA:
if (is_noncanonical_msr_address(data, vcpu))
return 1;
pmu->ds_area = data;
break;
case MSR_PEBS_DATA_CFG:
if (data & pmu->pebs_data_cfg_rsvd)
return 1;
pmu->pebs_data_cfg = data;
break;
default:
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
(pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
if ((msr & MSR_PMC_FULL_WIDTH_BIT) &&
(data & ~pmu->counter_bitmask[KVM_PMC_GP]))
return 1;
if (!msr_info->host_initiated &&
!(msr & MSR_PMC_FULL_WIDTH_BIT))
data = (s64)(s32)data;
pmc_write_counter(pmc, data);
break;
} else if ((pmc = get_fixed_pmc(pmu, msr))) {
pmc_write_counter(pmc, data);
break;
} else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
reserved_bits = pmu->reserved_bits;
if ((pmc->idx == 2) &&
(pmu->raw_event_mask & HSW_IN_TX_CHECKPOINTED))
reserved_bits ^= HSW_IN_TX_CHECKPOINTED;
if (data & reserved_bits)
return 1;
if (data != pmc->eventsel) {
pmc->eventsel = data;
pmc->eventsel_hw = data;
kvm_pmu_request_counter_reprogram(pmc);
}
break;
} else if (intel_pmu_handle_lbr_msrs_access(vcpu, msr_info, false)) {
break;
}
/* Not a known PMU MSR. */
return 1;
}
return 0;
}
/*
* Map fixed counter events to architectural general purpose event encodings.
* Perf doesn't provide APIs to allow KVM to directly program a fixed counter,
* and so KVM instead programs the architectural event to effectively request
* the fixed counter. Perf isn't guaranteed to use a fixed counter and may
* instead program the encoding into a general purpose counter, e.g. if a
* different perf_event is already utilizing the requested counter, but the end
* result is the same (ignoring the fact that using a general purpose counter
* will likely exacerbate counter contention).
*
* Forcibly inlined to allow asserting on @index at build time, and there should
* never be more than one user.
*/
static __always_inline u64 intel_get_fixed_pmc_eventsel(unsigned int index)
{
const enum perf_hw_id fixed_pmc_perf_ids[] = {
[0] = PERF_COUNT_HW_INSTRUCTIONS,
[1] = PERF_COUNT_HW_CPU_CYCLES,
[2] = PERF_COUNT_HW_REF_CPU_CYCLES,
};
u64 eventsel;
BUILD_BUG_ON(ARRAY_SIZE(fixed_pmc_perf_ids) != KVM_MAX_NR_INTEL_FIXED_COUNTERS);
BUILD_BUG_ON(index >= KVM_MAX_NR_INTEL_FIXED_COUNTERS);
/*
* Yell if perf reports support for a fixed counter but perf doesn't
* have a known encoding for the associated general purpose event.
*/
eventsel = perf_get_hw_event_config(fixed_pmc_perf_ids[index]);
WARN_ON_ONCE(!eventsel && index < kvm_pmu_cap.num_counters_fixed);
return eventsel;
}
Annotation
- Immediate include surface: `linux/types.h`, `linux/kvm_host.h`, `linux/perf_event.h`, `asm/msr.h`, `asm/perf_event.h`, `asm/cpuid/api.h`, `x86.h`, `cpuid.h`.
- Detected declarations: `function reprogram_fixed_counters`, `function Purpose`, `function intel_pmu_lbr_is_compatible`, `function intel_pmu_lbr_is_enabled`, `function intel_pmu_is_valid_lbr_msr`, `function intel_is_valid_msr`, `function intel_pmu_release_guest_lbr_event`, `function intel_pmu_create_guest_lbr_event`, `function intel_pmu_handle_lbr_msrs_access`, `function intel_pmu_get_msr`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.