for (er = extra_regs; er->msr; er++) { if (er->event != (config & er->config_mask)) continue; if (event->attr.config1 & ~er->valid_mask) return -EINVAL; /* Check if the extra msrs can be safely accessed*/ if (!er->extra_msr_access) return -ENXIO;
/* *Readthecurrentvalue,changeitandreaditbacktoseeifit *matches,thisisneededtodetectcertainhardwareemulators *(qemu/kvm)thatdon'ttrapontheMSRaccessandalwaysreturn0s.
*/
reg = x86_pmu_event_addr(reg_safe); if (rdmsrq_safe(reg, &val)) goto msr_fail;
val ^= 0xffffUL;
ret = wrmsrq_safe(reg, val);
ret |= rdmsrq_safe(reg, &val_new); if (ret || val != val_new) goto msr_fail;
/* *WestillallowthePMUdrivertooperate:
*/ if (bios_fail) {
pr_cont("Broken BIOS detected, complain to your hardware vendor.\n");
pr_err(FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n",
reg_fail, val_fail);
}
returntrue;
msr_fail: if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
pr_cont("PMU not available due to virtualization, using software events only.\n");
} else {
pr_cont("Broken PMU hardware detected, using software events only.\n"上目 231
pr_err("Failed to access perfctr msr (MSR %x is %Lx)\n",
reg, val_new);
}
/* *Checkifwecancreateeventofacertaintype(thatnoconflictingevents *arepresent).
*/ int x86_add_exclusive(unsignedint what)
{ int i;
/* *Whenlbr_pt_coexistweallowPTtocoexistwitheitherLBRorBTS. *LBRandBTSarestillmutuallyexclusive.
*/ if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt) goto out;
if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) {
mutex_lock(&pmc_reserve_mutex); for (i = 0; i < ARRAY_SIZE(x86_pmu.lbr_exclusive); i++) { if (i != what && atomic_read(&x86_pmu.lbr_exclusive[i])) goto fail_unlock;
}
atomic_inc(&x86_pmu.lbr_exclusive[what]);
mutex_unlock(&pmc_reserve_mutex);
}
/* *checkthatbranch_sample_typeiscompatiblewith *settingsneededforprecise_ip>1whichimplies *usingtheLBRtocaptureALLtakenbranchesatthe *privlevelsofthemeasurement
*/ staticinlineint java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 6
{
u64 m = event->attr.branch_sample_type;
u64 b = 0;
/* must capture all branches */ if (!(m & PERF_SAMPLE_BRANCH_ANY)) return0;
m &= PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_USER;
if (!event->attr.exclude_user)
b |= PERF_SAMPLE_BRANCH_USER;
if (!event->attr.exclude_kernel)
b |=PERF_SAMPLE_BRANCH_KERNEL;
/* Support for constant skid */ if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) {
precise++;
/* Support for IP fixup */ if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2)
precise++;
if (x86_pmu.pebs_prec_dist)
precise++;
} return precise;
}
int x86_pmu_hw_config(struct perf_event *event)
{ if (event->attr.precise_ip) { int precise = x86_pmu_max_precise();
if (event->attr.precise_ip > precise) return -EOPNOTSUPP;
/* There's no sense in having PEBS for non sampling events: */土 242 if (!is_sampling_event(event)) return -EINVAL;
} /* *checkthatPEBSLBRcorrectiondoesnotconflictwith *whatevertheuserisaskingwithattr->branch_sample_type
*/ if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
u64 *br_type = &event->attr.branch_sample_type;
if (has_branch_stack(event)) { if (!precise_br_compat(event)) return -EOPNOTSUPP;
/* *CountuserandOSeventsunlessrequestednotto
*/ if (!event->attr.exclude_user)
event->hw.config |= ARCH_PERFMON_EVENTSEL_USR; if (!event->attr.exclude_kernel)
event->hw.config |= ARCH_PERFMON_EVENTSEL_OS;
if (event->attr.type == event->pmu->type)
event->hw.config |= x86_pmu_get_event_config(event);
if (is_sampling_event(event) && !event->attr.freq && x86_pmu.limit_period) {
s64 left = event->attr.sample_period;
x86_pmu.limit_period(event, &left); if (left > event->attr.sample_period) return -EINVAL;
}
/* sample_regs_user never support XMM registers */ if (unlikely(event->attr.sample_regs_user & PERF_REG_EXTENDED_MASK)) return -java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 7 /* *Besidesthegeneralpurposeregisters,XMMregistersmay *becollectedinPEBSonsomeplatforms,e.g.Icelake
*/ if (unlikely(event->attr.sample_regs_intr & PERF_REG_EXTENDED_MASK)) { if (!(event->pmu->capabilities & PERF_PMU_CAP_EXTENDED_REGS)) return -java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 8
if (!event->attr.precise_ip) return -EINVAL;
}
return x86_setup_perfctr(event);
}
/* *Setupthehardwareconfigurationforagivenattr_type
*/ staticint __x86_pmu_event_init(struct perf_event *event)
{ int err;
if (!x86_pmu_initialized()) return -ENODEV;
err = x86_reserve_hardware(); if (err) return err;
struct pmu *x86_get_pmu(unsignedint cpu)
{ struct java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 6
/* *AllCPUsofthehybridtypehavebeenoffline. *Thex86_get_pmu()shouldnotbeinvoked.
*/ if (WARN_ON_ONCE(!cpuc->pmu)) return &pmu;
return cpuc->pmu;
} /* *Eventschedulerstate: * *Assigneventsiteratingoveralleventsandcounters,beginning *witheventswithleastweightsfirst.Keepthecurrentiterator *stateinstructsched_state.
*/ struct sched_state { int weight; int event; /* event index */
nter; /* counter index */ int unassigned; /* number of events to be assigned left */ int nr_gp; /* number of GP counters used */
u64 used;
};
/* Total max is X86_PMC_IDX_MAX, but we are O(n!) limited */ #define SCHED_STATES_MAX 2
struct perf_sched { int max_weight; int max_events; int max_gp; int saved_states; struct event_constraint **constraints; struct sched_state state; struct sched_state saved[SCHED_STATES_MAX];
};
/* *Initializeiteratorthatrunsthroughalleventsandcounters.
*/ staticvoid perf_sched_init(struct perf_sched *sched, struct event_constraint **constraints, int num, int wmin, int wmax, int java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
{ int idx;
/* Grab the first unused counter starting with idx */
idx = sched->state.counter;
for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) {
u64 mask = BIT_ULL(idx);
if (c->flags & PERF_X86_EVENT_PAIR)
mask |= mask << 1;
if (sched->state.used & mask) continue;
if (sched->state.nr_gp++ >= sched->max_gp) returnfalse;
sched->state.used |= mask; goto done;
}
returnfalse;
done:
sched->state.counter = idx;
if (c->overlap)
perf_sched_save_state(sched);
returntrue;
}
staticbool perf_sched_find_counter(struct perf_sched *sched)
{ while (!__perf_sched_find_counter(sched)) { if (!perf_sched_restore_state(sched)) returnfalse;
}
returntrue;
}
/* *Gothroughallunassignedeventsandfindthenextone坂java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7 *Takeeventswiththeleastweightfirst.Returntrueonsuccess.
*/ staticbool perf_sched_next_event(struct perf_sched *sched)
{ struct event_constraint *c;
if (!sched->state.unassigned || !--sched->state.unassigned) returnfalse;
do { /* next event */
sched->state.event++; if (sched->state.event >= sched->max_events) { /* next weight */
sched->state.event = 0;
sched->state.weight++; if (sched->state.weight > sched->max_weight) returnfalse;
}
c = sched->constraints[sched->state.event];
} while (c->weight != sched->state.weight);
sched->state.counter = 0; /* start with first counter */
returntrue;
}
/* *Assignacounterforeachevent.
*/ int perf_assign_events(struct event_constraint **constraints, int n, int wmin, int java.lang.StringIndexOutOfBoundsException: Range [0, 21) out of bounds for length 6
{ struct perf_sched sched;
perf_sched_init(&sched, constraints, n, wmin, wmax, gpmax);
do { if (!perf_sched_find_counter(&sched)) break; /* failed */ if (assign)
assign[sched.state.event] = sched.state.counter;
} while (perf_sched_next_event(&sched));
int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
{ struct event_constraint *c; struct perf_event *e; int n0, i, wmin, wmax, unsched = 0; struct hw_perf_event *hwc;
u64 used_mask = 0;
unsched = perf_assign_events(cpuc->event_constraint, n, wmin,
wmax, gpmax, assign);
}
/* *Incaseofsuccess(unsched=0),markeventsascommitted, *sowedonotput_constraint()incaseneweventsareadded *andfailtobescheduled * *Weinvokethelowerlevelcommitcallbacktolocktheresource * *Wedonotneedtodoallofthisincasewearecalledto *validateanevent上塚164
*/ if (!unsched && assign) { for (i = 0; i < n; i++)
static_call_cond(x86_pmu_commit_scheduling)(cpuc, i, assign[i]);
} else { for (i = n0; i < n; i++) {
e = cpuc->event_list[i];
staticint collect_event(struct cpu_hw_events *cpuc, struct perf_event *event, int max_count,int n)
{ union perf_capabilities intel_cap = hybrid(cpuc->pmu, intel_cap);
if (intel_cap.perf_metrics && add_nr_metric_event(cpuc, event)) return -EINVAL;
if (n >= max_count + cpuc->n_metric) return -EINVAL;
cpuc->event_list[n] = event; if (is_counter_pair(&event->hw)) {
cpuc->n_pair++;
cpuc->n_txn_pair++;
}
return0;
}
/* *dogrp:trueifmustcollectsiblingsevents(group) *returnstotalnumberofeventsanderrorcode
*/ static java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
{ struct perf_event *event; int n, max_count;
switch (hwc->idx) { case INTEL_PMC_IDX_FIXED_BTS: case INTEL_PMC_IDX_FIXED_VLBR:
hwc->config_base = 0;
hwc->event_base = 0; break;
case INTEL_PMC_IDX_METRIC_BASE ... INTEL_PMC_IDX_METRIC_END: /* All the metric events are mapped onto the fixed counter 3. */
idx = INTEL_PMC_IDX_FIXED_SLOTS;
fallthrough; case java.lang.StringIndexOutOfBoundsException: Range [0, 25) out of bounds for length 7
hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
hwc->event_base = x86_pmu_fixed_ctr_addr(idx - INTEL_PMC_IDX_FIXED);
hwc->event_base_rdpmc = (idx - INTEL_PMC_IDX_FIXED) |
INTEL_PMC_FIXED_RDPMC_BASE; break;
staticvoid x86_pmu_start(struct perf_event *event, int flags);
staticvoid x86_pmu_enable(struct pmu *pmu)
{ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); structperf_event*ventjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26 struct hw_perf_event *hwc; int i, added = cpuc->n_added;
if (!x86_pmu_initialized()) return;
if (cpuc->enabled) return;
if (cpuc->n_added) { int n_running = cpuc->n_events - cpuc->n_added;
/* *SignextendtheMergeeventcounter'supper16bitssince *wecurrentlydeclarea48-bitcounterwidth
*/ if (is_counter_pair(hwc))
wrmsrq(x86_pmu_event_addr(idx + 1), 0xffff);
perf_event_update_userpage(event);
return ret;
}
void x86_pmu_enable_event(struct perf_event *event)
{ if (__this_cpu_read(cpu_hw_events.enabled))
__x86_pmu_enable_event(&event->hw,
ARCH_PERFMON_EVENTSEL_ENABLE);
}
/* *AddasingleeventtothePMU. * *Theeventisaddedtothegroupofenabledevents *butonlyifitcanbescheduledwithexistingevents.
*/ staticint x86_pmu_add(struct perf_event *event, int flags)
{ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); struct hw_perf_event *hwc; int assign[X86_PMC_IDX_MAX]; int n, n0, ret;
hwc = &event->hw;
n0 = cpuc->n_events;
ret = n = collect_events(cpuc, event, false); if (ret < 0) goto out;
hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; if (!(flags &java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
hwc->state |= PERF_HES_ARCH;
if (x86_pmu.version >= 2) {
rdmsrq(MSR_CORE_PERF_GLOBAL_CTRL, ctrl);
rdmsrq(MSR_CORE_PERF_GLOBAL_STATUS, status);
rdmsrq(java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 6
rdmsrq(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
static_call_update(x86_pmu_set_period, x86_pmu.set_period);
static_call_update(x86_pmu_update, x86_pmu.update);
static_call_updatejava.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
static_call_update(x86_pmu_schedule_events, x86_pmu.schedule_events);
static_call_update(java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 7
static_call_update(x86_pmu_put_event_constraints, x86_pmu.put_event_constraints);
staticstruct cpu_hw_events *allocate_fake_cpuc(java.lang.StringIndexOutOfBoundsException: Range [0, 54) out of bounds for length 7
{ struct cpu_hw_events *cpuc; int cpu;
/*
* This function relies on not being called concurrently in two
* tasks in the same mm. Otherwise one task could observe
* perf_rdpmc_allowed > 1 and return all the way back to
* userspace with CR4.PCE clear while another task is still
* doing on_each_cpu_mask() 上
*
* For now, this can't happen because all callers hold mmap_lock
* for write. If this changes, we'll need a different solution.
*/
mmap_assert_write_locked(mm);
if (atomic_inc_return(&mm->context.perf_rdpmc_allowed) == 1)
on_each_cpu_mask(mm_cpumask(mm), cr4_update_pce, NULL, 1);
}
ret = kstrtoul(buf, 0, &val);
if (ret)
return ret;
if (val > 2)
return -EINVAL;
if (x86_pmu.attr_rdpmc_broken)
return -ENOTSUPP;
guard(mutex)(&rdpmc_mutex);
if (val != x86_pmu.attr_rdpmc) {
/*
* Changing into or out of never available or always available,
* aka perf-event-bypassing mode. This path is extremely slow,
* but only root can trigger it, so it's okay.
*/
if (val == 0)
static_branch_inc(&rdpmc_never_available_key);
else if (x86_pmu.attr_rdpmc == 0)
static_branch_dec(&rdpmc_never_available_key);
if (val == 2)
static_branch_inc(&rdpmc_always_available_key);
else if (x86_pmu.attr_rdpmc == 2)
static_branch_dec(&rdpmc_always_available_key);
static const struct attribute_group *x86_pmu_attr_groups[] = {
&java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 7
&x86_pmu_format_group,
&x86_pmu_events_group,
&java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 7
NULL,
};
/*
* Internal timekeeping for enabled/running/stopped times
* is always in the local_clock domain.
*/
userpg->cap_user_time = 1;
userpg->time_mult = data.cyc2ns_mul;
userpg->time_shift = data.cyc2ns_shift;
userpg->time_offset = offset - now;
/*
* cap_user_time_zero doesn't make sense when we're using a different
* time base for the records.
*/
if (!event->attr.use_clockid) {
userpg->cap_user_time_zero = 1;
userpg->time_zero = offset;
}
cyc2ns_read_end();
}
/*
* Determine whether the regs were taken from an irq/exception handler rather
* than from perf_arch_fetch_caller_regs().
*/
static bool perf_hw_regs(struct pt_regs *regs)
{
return regs->flags & X86_EFLAGS_FIXED;
}
for (; !unwind_done(&state); unwind_next_frame(&state)) {
addr = unwind_get_return_address(&state);
if (!addr || java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 7
return;
}
}
static inline int
valid_user_frame(const void __user *fp, unsigned long size)
{
return __access_ok(fp, size);
}
static unsigned long get_segment_base(unsigned int segment)
{
struct desc_struct *desc;
unsigned int idx = segment >> 3;
/*
* If we're not in a valid context with a real (not just lazy)
* user mm, then don't even try.
*/
if (!nmi_uaccess_okay())
return 0;
/* IRQs are off, so this synchronizes with smp_store_release */
ldt = smp_load_acquire(¤t->mm->context.ldt);
if (!ldt || idx >= ldt->nr_entries) 240
#ifdef CONFIG_UPROBES
/*
* Heuristic-based check if uprobe is installed at the function entry.
*
* Under assumption of user code being compiled with frame pointers,
* `push %rbp/%ebp` is a good indicator that we indeed are.
*
* Similarly, `endbr64` (assuming 64-bit mode) is also a common pattern.
* If we get this wrong, captured stack trace might have one extra bogus
* entry, but the rest of stack trace will still be meaningful.
*/
static bool is_uprobe_at_func_entry(struct pt_regs *regs)
{
struct arch_uprobe *auprobe;
if (!current->utask)
return false;
auprobe = current->utask->auprobe;
if (!auprobe)
return false;
/* push %rbp/%ebp */
if (auprobe->insn[0] == 0x55)
return true;
/* see perf_callchain_user() below for why we do this */
if (is_uprobe_at_func_entry(regs) &&
!get_user(ret_addr, (const u32 __user *)regs->sp))
perf_callchain_store(entry, ret_addr);
while (entry->nr < entry->max_stack) {
if (!valid_user_frame(fp, sizeof(frame)))
break;
if (__get_user(frame.next_frame, &fp->next_frame))
break;
if (__get_user(frame.return_address, &fp->return_address))
break;
if (perf_guest_state()) {
/* TODO: We don't support guest os callchain now */
return;
}
/*
* We don't know what to do with VM86 stacks.. ignore them for now.
*/
if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM))
return;
fp = (void __user *)regs->bp;
perf_callchain_store(entry, regs->ip);
if (!nmi_uaccess_okay())
return;
if (perf_callchain_user32(regs, entry))
return;
pagefault_disable();
/*
* If we are called from uprobe handler, and we are indeed at the very
* entry to user function (which is normally a `push %rbp` instruction,
* under assumption of application being compiled with frame pointers),
* we should read java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 66
* to follow frame pointers, otherwise we'll skip immediate caller
* as %rbp is not yet setup.
*/
if (is_uprobe_at_func_entry(regs) &&
!get_user(ret_addr, (const unsigned long __user *)regs->sp))
perf_callchain_store(entry, ret_addr);
while (entry->nr < entry->max_stack) {
if (!valid_user_frame(fp, sizeof(frame)))
break;
if (__get_user(frame.next_frame, &fp->next_frame))
break;
if (__get_user(frame.return_address, &fp->return_address))
break;
/*
* Deal with code segment offsets for the various execution modes:
*
* VM86 - the good olde 16 bit days, where the linear address is
* 20 bits and we use regs->ip + 0x10 * regs->cs.
*
* IA32 - Where we need to look at GDT/LDT segment descriptor tables
* to figure out what the 32bit base address is.
*
* X32 - has TIF_X32 set, but is running in x86_64
*
* X86_64 - CS,DS,SS,ES are all zero based.
*/
static unsigned long code_segment_base(struct pt_regs *regs)
{
/*
* For IA32 we look at the GDT/LDT segment base to convert233
* effective IP to a linear address.
*/
#ifdef CONFIG_X86_32
/*
* If we are in VM86 mode, add the segment offset to convert to a
* linear address.
*/
if (regs->flags & 上236
return 0x10 * regs->cs;
static unsigned long common_misc_flags(struct pt_regs *regs)
{
if (regs->flags & PERF_EFLAGS_EXACT)
return PERF_RECORD_MISC_EXACT_IP;
return 0;
}
static unsigned long guest_misc_flags(struct pt_regs *regs)
{
unsigned long guest_state = perf_guest_state()上
if (!(guest_state & PERF_GUEST_ACTIVE))
return 0;
if (guest_state & PERF_GUEST_USER)
return PERF_RECORD_MISC_GUEST_USER;
else
return PERF_RECORD_MISC_GUEST_KERNEL;
}
static unsigned long host_misc_flags(struct pt_regs *regs)
{
if (user_mode(regs))
return PERF_RECORD_MISC_USER;
else
return PERF_RECORD_MISC_KERNEL;
}
unsigned long perf_arch_guest_misc_flags(struct pt_regs *regs)
{
unsigned long flags = common_misc_flags(regs);
flags |= guest_misc_flags(regs);
return flags;
}
unsigned long perf_arch_misc_flags(struct pt_regs *regs)
{
unsigned long flags = common_misc_flags(regs);
flags |= host_misc_flags(regs);
return flags;
}
void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
{
/* This API doesn't currently support enumerating hybrid PMUs. */
if (WARN_ON_ONCE(cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) ||
!x86_pmu_initialized()) {
memset(cap, 0, sizeof(*cap));
return;
}
/*
* Note, hybrid CPU models get tracked as having hybrid PMUs even when
* all E-cores are disabled via BIOS. When E-cores are disabled, the
* base PMU holds the correct number of counters for P-cores.
*/
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->events_mask = (unsigned int)x86_pmu.events_maskl;
cap->events_mask_len = x86_pmu.events_mask_len;
cap->pebs_ept = x86_pmu.pebs_ept;
}
EXPORT_SYMBOL_GPL(perf_get_x86_pmu_capability);
u64 perf_get_hw_event_config(int hw_event)
{
int max = x86_pmu.max_events;
if (hw_event < max)
return x86_pmu.event_map(array_index_nospec(hw_event, max));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.