arch/arm64/kvm/pmu.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/pmu.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/pmu.c- Extension
.c- Size
- 5093 bytes
- Lines
- 212
- Domain
- Architecture Layer
- Bucket
- arch/arm64
- 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/kvm_host.hlinux/perf_event.hlinux/perf/arm_pmu.hlinux/perf/arm_pmuv3.h
Detected Declarations
function kvm_pmu_switch_neededfunction kvm_set_pmu_eventsfunction kvm_clr_pmu_eventsfunction kvm_vcpu_pmu_read_evtype_directfunction kvm_vcpu_pmu_write_evtype_directfunction kvm_vcpu_pmu_enable_el0function for_each_set_bitfunction kvm_vcpu_pmu_disable_el0function for_each_set_bitfunction kvm_vcpu_pmu_restore_guestfunction kvm_vcpu_pmu_restore_hostfunction vcpu_loadfunction kvm_vcpu_pmu_resync_el0
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2019 Arm Limited
* Author: Andrew Murray <Andrew.Murray@arm.com>
*/
#include <linux/kvm_host.h>
#include <linux/perf_event.h>
#include <linux/perf/arm_pmu.h>
#include <linux/perf/arm_pmuv3.h>
static DEFINE_PER_CPU(struct kvm_pmu_events, kvm_pmu_events);
/*
* Given the perf event attributes and system type, determine
* if we are going to need to switch counters at guest entry/exit.
*/
static bool kvm_pmu_switch_needed(struct perf_event_attr *attr)
{
/**
* With VHE the guest kernel runs at EL1 and the host at EL2,
* where user (EL0) is excluded then we have no reason to switch
* counters.
*/
if (has_vhe() && attr->exclude_user)
return false;
/* Only switch if attributes are different */
return (attr->exclude_host != attr->exclude_guest);
}
struct kvm_pmu_events *kvm_get_pmu_events(void)
{
return this_cpu_ptr(&kvm_pmu_events);
}
/*
* Add events to track that we may want to switch at guest entry/exit
* time.
*/
void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr)
{
struct kvm_pmu_events *pmu = kvm_get_pmu_events();
if (!system_supports_pmuv3() || !kvm_pmu_switch_needed(attr))
return;
if (!attr->exclude_host)
pmu->events_host |= set;
if (!attr->exclude_guest)
pmu->events_guest |= set;
}
/*
* Stop tracking events
*/
void kvm_clr_pmu_events(u64 clr)
{
struct kvm_pmu_events *pmu = kvm_get_pmu_events();
if (!system_supports_pmuv3())
return;
pmu->events_host &= ~clr;
pmu->events_guest &= ~clr;
}
/*
* Read a value direct from PMEVTYPER<idx> where idx is 0-30
* or PMxCFILTR_EL0 where idx is 31-32.
*/
static u64 kvm_vcpu_pmu_read_evtype_direct(int idx)
{
if (idx == ARMV8_PMU_CYCLE_IDX)
return read_pmccfiltr();
else if (idx == ARMV8_PMU_INSTR_IDX)
return read_pmicfiltr();
return read_pmevtypern(idx);
}
/*
* Write a value direct to PMEVTYPER<idx> where idx is 0-30
* or PMxCFILTR_EL0 where idx is 31-32.
*/
static void kvm_vcpu_pmu_write_evtype_direct(int idx, u32 val)
{
if (idx == ARMV8_PMU_CYCLE_IDX)
write_pmccfiltr(val);
else if (idx == ARMV8_PMU_INSTR_IDX)
write_pmicfiltr(val);
Annotation
- Immediate include surface: `linux/kvm_host.h`, `linux/perf_event.h`, `linux/perf/arm_pmu.h`, `linux/perf/arm_pmuv3.h`.
- Detected declarations: `function kvm_pmu_switch_needed`, `function kvm_set_pmu_events`, `function kvm_clr_pmu_events`, `function kvm_vcpu_pmu_read_evtype_direct`, `function kvm_vcpu_pmu_write_evtype_direct`, `function kvm_vcpu_pmu_enable_el0`, `function for_each_set_bit`, `function kvm_vcpu_pmu_disable_el0`, `function for_each_set_bit`, `function kvm_vcpu_pmu_restore_guest`.
- Atlas domain: Architecture Layer / arch/arm64.
- 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.