mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-01 08:04:22 +08:00
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf update from Thomas Gleixner: "The perf crowd presents: Kernel updates: - Removal of jprobes - Cleanup and consolidatation the handling of kprobes - Cleanup and consolidation of hardware breakpoints - The usual pile of fixes and updates to PMUs and event descriptors Tooling updates: - Updates and improvements all over the place. Nothing outstanding, just the (good) boring incremental grump work" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (103 commits) perf trace: Do not require --no-syscalls to suppress strace like output perf bpf: Include uapi/linux/bpf.h from the 'perf trace' script's bpf.h perf tools: Allow overriding MAX_NR_CPUS at compile time perf bpf: Show better message when failing to load an object perf list: Unify metric group description format with PMU event description perf vendor events arm64: Update ThunderX2 implementation defined pmu core events perf cs-etm: Generate branch sample for CS_ETM_TRACE_ON packet perf cs-etm: Generate branch sample when receiving a CS_ETM_TRACE_ON packet perf cs-etm: Support dummy address value for CS_ETM_TRACE_ON packet perf cs-etm: Fix start tracing packet handling perf build: Fix installation directory for eBPF perf c2c report: Fix crash for empty browser perf tests: Fix indexing when invoking subtests perf trace: Beautify the AF_INET & AF_INET6 'socket' syscall 'protocol' args perf trace beauty: Add beautifiers for 'socket''s 'protocol' arg perf trace beauty: Do not print NULL strarray entries perf beauty: Add a generator for IPPROTO_ socket's protocol constants tools include uapi: Grab a copy of linux/in.h perf tests: Fix complex event name parsing perf evlist: Fix error out while applying initial delay and LBR ...
This commit is contained in:
commit
8603596a32
@ -80,6 +80,26 @@ After the instruction is single-stepped, Kprobes executes the
|
||||
"post_handler," if any, that is associated with the kprobe.
|
||||
Execution then continues with the instruction following the probepoint.
|
||||
|
||||
Changing Execution Path
|
||||
-----------------------
|
||||
|
||||
Since kprobes can probe into a running kernel code, it can change the
|
||||
register set, including instruction pointer. This operation requires
|
||||
maximum care, such as keeping the stack frame, recovering the execution
|
||||
path etc. Since it operates on a running kernel and needs deep knowledge
|
||||
of computer architecture and concurrent computing, you can easily shoot
|
||||
your foot.
|
||||
|
||||
If you change the instruction pointer (and set up other related
|
||||
registers) in pre_handler, you must return !0 so that kprobes stops
|
||||
single stepping and just returns to the given address.
|
||||
This also means post_handler should not be called anymore.
|
||||
|
||||
Note that this operation may be harder on some architectures which use
|
||||
TOC (Table of Contents) for function call, since you have to setup a new
|
||||
TOC for your function in your module, and recover the old one after
|
||||
returning from it.
|
||||
|
||||
Return Probes
|
||||
-------------
|
||||
|
||||
@ -262,7 +282,7 @@ is optimized, that modification is ignored. Thus, if you want to
|
||||
tweak the kernel's execution path, you need to suppress optimization,
|
||||
using one of the following techniques:
|
||||
|
||||
- Specify an empty function for the kprobe's post_handler or break_handler.
|
||||
- Specify an empty function for the kprobe's post_handler.
|
||||
|
||||
or
|
||||
|
||||
@ -474,7 +494,7 @@ error occurs during registration, all probes in the array, up to
|
||||
the bad probe, are safely unregistered before the register_*probes
|
||||
function returns.
|
||||
|
||||
- kps/rps/jps: an array of pointers to ``*probe`` data structures
|
||||
- kps/rps: an array of pointers to ``*probe`` data structures
|
||||
- num: the number of the array entries.
|
||||
|
||||
.. note::
|
||||
@ -566,12 +586,11 @@ the same handler) may run concurrently on different CPUs.
|
||||
Kprobes does not use mutexes or allocate memory except during
|
||||
registration and unregistration.
|
||||
|
||||
Probe handlers are run with preemption disabled. Depending on the
|
||||
architecture and optimization state, handlers may also run with
|
||||
interrupts disabled (e.g., kretprobe handlers and optimized kprobe
|
||||
handlers run without interrupt disabled on x86/x86-64). In any case,
|
||||
your handler should not yield the CPU (e.g., by attempting to acquire
|
||||
a semaphore).
|
||||
Probe handlers are run with preemption disabled or interrupt disabled,
|
||||
which depends on the architecture and optimization state. (e.g.,
|
||||
kretprobe handlers and optimized kprobe handlers run without interrupt
|
||||
disabled on x86/x86-64). In any case, your handler should not yield
|
||||
the CPU (e.g., by attempting to acquire a semaphore, or waiting I/O).
|
||||
|
||||
Since a return probe is implemented by replacing the return
|
||||
address with the trampoline's address, stack backtraces and calls
|
||||
|
@ -45,8 +45,6 @@ struct prev_kprobe {
|
||||
|
||||
struct kprobe_ctlblk {
|
||||
unsigned int kprobe_status;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
char jprobes_stack[MAX_STACK_SIZE];
|
||||
struct prev_kprobe prev_kprobe;
|
||||
};
|
||||
|
||||
|
@ -225,24 +225,18 @@ int __kprobes arc_kprobe_handler(unsigned long addr, struct pt_regs *regs)
|
||||
|
||||
/* If we have no pre-handler or it returned 0, we continue with
|
||||
* normal processing. If we have a pre-handler and it returned
|
||||
* non-zero - which is expected from setjmp_pre_handler for
|
||||
* jprobe, we return without single stepping and leave that to
|
||||
* the break-handler which is invoked by a kprobe from
|
||||
* jprobe_return
|
||||
* non-zero - which means user handler setup registers to exit
|
||||
* to another instruction, we must skip the single stepping.
|
||||
*/
|
||||
if (!p->pre_handler || !p->pre_handler(p, regs)) {
|
||||
setup_singlestep(p, regs);
|
||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||
} else {
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (kprobe_running()) {
|
||||
p = __this_cpu_read(current_kprobe);
|
||||
if (p->break_handler && p->break_handler(p, regs)) {
|
||||
setup_singlestep(p, regs);
|
||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* no_kprobe: */
|
||||
@ -386,38 +380,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
unsigned long sp_addr = regs->sp;
|
||||
|
||||
kcb->jprobe_saved_regs = *regs;
|
||||
memcpy(kcb->jprobes_stack, (void *)sp_addr, MIN_STACK_SIZE(sp_addr));
|
||||
regs->ret = (unsigned long)(jp->entry);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void __kprobes jprobe_return(void)
|
||||
{
|
||||
__asm__ __volatile__("unimp_s");
|
||||
return;
|
||||
}
|
||||
|
||||
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
unsigned long sp_addr;
|
||||
|
||||
*regs = kcb->jprobe_saved_regs;
|
||||
sp_addr = regs->sp;
|
||||
memcpy((void *)sp_addr, kcb->jprobes_stack, MIN_STACK_SIZE(sp_addr));
|
||||
preempt_enable_no_resched();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void __used kretprobe_trampoline_holder(void)
|
||||
{
|
||||
__asm__ __volatile__(".global kretprobe_trampoline\n"
|
||||
@ -483,9 +445,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
|
||||
kretprobe_assert(ri, orig_ret_address, trampoline_address);
|
||||
regs->ret = orig_ret_address;
|
||||
|
||||
reset_current_kprobe();
|
||||
kretprobe_hash_unlock(current, &flags);
|
||||
preempt_enable_no_resched();
|
||||
|
||||
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
|
||||
hlist_del(&ri->hlist);
|
||||
|
@ -111,14 +111,17 @@ static inline void decode_ctrl_reg(u32 reg,
|
||||
asm volatile("mcr p14, 0, %0, " #N "," #M ", " #OP2 : : "r" (VAL));\
|
||||
} while (0)
|
||||
|
||||
struct perf_event_attr;
|
||||
struct notifier_block;
|
||||
struct perf_event;
|
||||
struct pmu;
|
||||
|
||||
extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
|
||||
int *gen_len, int *gen_type);
|
||||
extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
|
||||
extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
|
||||
extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
|
||||
extern int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw);
|
||||
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
|
||||
unsigned long val, void *data);
|
||||
|
||||
|
@ -44,8 +44,6 @@ struct prev_kprobe {
|
||||
struct kprobe_ctlblk {
|
||||
unsigned int kprobe_status;
|
||||
struct prev_kprobe prev_kprobe;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
char jprobes_stack[MAX_STACK_SIZE];
|
||||
};
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *);
|
||||
|
@ -51,7 +51,6 @@ struct arch_probes_insn {
|
||||
* We assume one instruction can consume at most 64 bytes stack, which is
|
||||
* 'push {r0-r15}'. Instructions consume more or unknown stack space like
|
||||
* 'str r0, [sp, #-80]' and 'str r0, [sp, r1]' should be prohibit to probe.
|
||||
* Both kprobe and jprobe use this macro.
|
||||
*/
|
||||
#define MAX_STACK_SIZE 64
|
||||
|
||||
|
@ -456,14 +456,13 @@ static int get_hbp_len(u8 hbp_len)
|
||||
/*
|
||||
* Check whether bp virtual address is in kernel space.
|
||||
*/
|
||||
int arch_check_bp_in_kernelspace(struct perf_event *bp)
|
||||
int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned long va;
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
va = info->address;
|
||||
len = get_hbp_len(info->ctrl.len);
|
||||
va = hw->address;
|
||||
len = get_hbp_len(hw->ctrl.len);
|
||||
|
||||
return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
|
||||
}
|
||||
@ -518,42 +517,42 @@ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
|
||||
/*
|
||||
* Construct an arch_hw_breakpoint from a perf_event.
|
||||
*/
|
||||
static int arch_build_bp_info(struct perf_event *bp)
|
||||
static int arch_build_bp_info(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
/* Type */
|
||||
switch (bp->attr.bp_type) {
|
||||
switch (attr->bp_type) {
|
||||
case HW_BREAKPOINT_X:
|
||||
info->ctrl.type = ARM_BREAKPOINT_EXECUTE;
|
||||
hw->ctrl.type = ARM_BREAKPOINT_EXECUTE;
|
||||
break;
|
||||
case HW_BREAKPOINT_R:
|
||||
info->ctrl.type = ARM_BREAKPOINT_LOAD;
|
||||
hw->ctrl.type = ARM_BREAKPOINT_LOAD;
|
||||
break;
|
||||
case HW_BREAKPOINT_W:
|
||||
info->ctrl.type = ARM_BREAKPOINT_STORE;
|
||||
hw->ctrl.type = ARM_BREAKPOINT_STORE;
|
||||
break;
|
||||
case HW_BREAKPOINT_RW:
|
||||
info->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
|
||||
hw->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Len */
|
||||
switch (bp->attr.bp_len) {
|
||||
switch (attr->bp_len) {
|
||||
case HW_BREAKPOINT_LEN_1:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_1;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_1;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_2:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_2;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_2;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_4:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_4;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_8:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_8;
|
||||
if ((info->ctrl.type != ARM_BREAKPOINT_EXECUTE)
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_8;
|
||||
if ((hw->ctrl.type != ARM_BREAKPOINT_EXECUTE)
|
||||
&& max_watchpoint_len >= 8)
|
||||
break;
|
||||
default:
|
||||
@ -566,24 +565,24 @@ static int arch_build_bp_info(struct perf_event *bp)
|
||||
* by the hardware and must be aligned to the appropriate number of
|
||||
* bytes.
|
||||
*/
|
||||
if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE &&
|
||||
info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
|
||||
info->ctrl.len != ARM_BREAKPOINT_LEN_4)
|
||||
if (hw->ctrl.type == ARM_BREAKPOINT_EXECUTE &&
|
||||
hw->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
|
||||
hw->ctrl.len != ARM_BREAKPOINT_LEN_4)
|
||||
return -EINVAL;
|
||||
|
||||
/* Address */
|
||||
info->address = bp->attr.bp_addr;
|
||||
hw->address = attr->bp_addr;
|
||||
|
||||
/* Privilege */
|
||||
info->ctrl.privilege = ARM_BREAKPOINT_USER;
|
||||
if (arch_check_bp_in_kernelspace(bp))
|
||||
info->ctrl.privilege |= ARM_BREAKPOINT_PRIV;
|
||||
hw->ctrl.privilege = ARM_BREAKPOINT_USER;
|
||||
if (arch_check_bp_in_kernelspace(hw))
|
||||
hw->ctrl.privilege |= ARM_BREAKPOINT_PRIV;
|
||||
|
||||
/* Enabled? */
|
||||
info->ctrl.enabled = !bp->attr.disabled;
|
||||
hw->ctrl.enabled = !attr->disabled;
|
||||
|
||||
/* Mismatch */
|
||||
info->ctrl.mismatch = 0;
|
||||
hw->ctrl.mismatch = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -591,9 +590,10 @@ static int arch_build_bp_info(struct perf_event *bp)
|
||||
/*
|
||||
* Validate the arch-specific HW Breakpoint register settings.
|
||||
*/
|
||||
int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
int ret = 0;
|
||||
u32 offset, alignment_mask = 0x3;
|
||||
|
||||
@ -602,14 +602,14 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
return -ENODEV;
|
||||
|
||||
/* Build the arch_hw_breakpoint. */
|
||||
ret = arch_build_bp_info(bp);
|
||||
ret = arch_build_bp_info(bp, attr, hw);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* Check address alignment. */
|
||||
if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
|
||||
if (hw->ctrl.len == ARM_BREAKPOINT_LEN_8)
|
||||
alignment_mask = 0x7;
|
||||
offset = info->address & alignment_mask;
|
||||
offset = hw->address & alignment_mask;
|
||||
switch (offset) {
|
||||
case 0:
|
||||
/* Aligned */
|
||||
@ -617,19 +617,19 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
case 1:
|
||||
case 2:
|
||||
/* Allow halfword watchpoints and breakpoints. */
|
||||
if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
|
||||
if (hw->ctrl.len == ARM_BREAKPOINT_LEN_2)
|
||||
break;
|
||||
case 3:
|
||||
/* Allow single byte watchpoint. */
|
||||
if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
|
||||
if (hw->ctrl.len == ARM_BREAKPOINT_LEN_1)
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
info->address &= ~alignment_mask;
|
||||
info->ctrl.len <<= offset;
|
||||
hw->address &= ~alignment_mask;
|
||||
hw->ctrl.len <<= offset;
|
||||
|
||||
if (is_default_overflow_handler(bp)) {
|
||||
/*
|
||||
@ -640,7 +640,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
return -EINVAL;
|
||||
|
||||
/* We don't allow mismatch breakpoints in kernel space. */
|
||||
if (arch_check_bp_in_kernelspace(bp))
|
||||
if (arch_check_bp_in_kernelspace(hw))
|
||||
return -EPERM;
|
||||
|
||||
/*
|
||||
@ -655,8 +655,8 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
* reports them.
|
||||
*/
|
||||
if (!debug_exception_updates_fsr() &&
|
||||
(info->ctrl.type == ARM_BREAKPOINT_LOAD ||
|
||||
info->ctrl.type == ARM_BREAKPOINT_STORE))
|
||||
(hw->ctrl.type == ARM_BREAKPOINT_LOAD ||
|
||||
hw->ctrl.type == ARM_BREAKPOINT_STORE))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -47,9 +47,6 @@
|
||||
(unsigned long)(addr) + \
|
||||
(size))
|
||||
|
||||
/* Used as a marker in ARM_pc to note when we're in a jprobe. */
|
||||
#define JPROBE_MAGIC_ADDR 0xffffffff
|
||||
|
||||
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
|
||||
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
|
||||
|
||||
@ -289,8 +286,8 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
break;
|
||||
case KPROBE_REENTER:
|
||||
/* A nested probe was hit in FIQ, it is a BUG */
|
||||
pr_warn("Unrecoverable kprobe detected at %p.\n",
|
||||
p->addr);
|
||||
pr_warn("Unrecoverable kprobe detected.\n");
|
||||
dump_kprobe(p);
|
||||
/* fall through */
|
||||
default:
|
||||
/* impossible cases */
|
||||
@ -303,10 +300,10 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
|
||||
/*
|
||||
* If we have no pre-handler or it returned 0, we
|
||||
* continue with normal processing. If we have a
|
||||
* pre-handler and it returned non-zero, it prepped
|
||||
* for calling the break_handler below on re-entry,
|
||||
* so get out doing nothing more here.
|
||||
* continue with normal processing. If we have a
|
||||
* pre-handler and it returned non-zero, it will
|
||||
* modify the execution path and no need to single
|
||||
* stepping. Let's just reset current kprobe and exit.
|
||||
*/
|
||||
if (!p->pre_handler || !p->pre_handler(p, regs)) {
|
||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||
@ -315,20 +312,9 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
kcb->kprobe_status = KPROBE_HIT_SSDONE;
|
||||
p->post_handler(p, regs, 0);
|
||||
}
|
||||
reset_current_kprobe();
|
||||
}
|
||||
reset_current_kprobe();
|
||||
}
|
||||
} else if (cur) {
|
||||
/* We probably hit a jprobe. Call its break handler. */
|
||||
if (cur->break_handler && cur->break_handler(cur, regs)) {
|
||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||
singlestep(cur, regs, kcb);
|
||||
if (cur->post_handler) {
|
||||
kcb->kprobe_status = KPROBE_HIT_SSDONE;
|
||||
cur->post_handler(cur, regs, 0);
|
||||
}
|
||||
}
|
||||
reset_current_kprobe();
|
||||
} else {
|
||||
/*
|
||||
* The probe was removed and a race is in progress.
|
||||
@ -521,117 +507,6 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
|
||||
regs->ARM_lr = (unsigned long)&kretprobe_trampoline;
|
||||
}
|
||||
|
||||
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
long sp_addr = regs->ARM_sp;
|
||||
long cpsr;
|
||||
|
||||
kcb->jprobe_saved_regs = *regs;
|
||||
memcpy(kcb->jprobes_stack, (void *)sp_addr, MIN_STACK_SIZE(sp_addr));
|
||||
regs->ARM_pc = (long)jp->entry;
|
||||
|
||||
cpsr = regs->ARM_cpsr | PSR_I_BIT;
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
/* Set correct Thumb state in cpsr */
|
||||
if (regs->ARM_pc & 1)
|
||||
cpsr |= PSR_T_BIT;
|
||||
else
|
||||
cpsr &= ~PSR_T_BIT;
|
||||
#endif
|
||||
regs->ARM_cpsr = cpsr;
|
||||
|
||||
preempt_disable();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void __kprobes jprobe_return(void)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
__asm__ __volatile__ (
|
||||
/*
|
||||
* Setup an empty pt_regs. Fill SP and PC fields as
|
||||
* they're needed by longjmp_break_handler.
|
||||
*
|
||||
* We allocate some slack between the original SP and start of
|
||||
* our fabricated regs. To be precise we want to have worst case
|
||||
* covered which is STMFD with all 16 regs so we allocate 2 *
|
||||
* sizeof(struct_pt_regs)).
|
||||
*
|
||||
* This is to prevent any simulated instruction from writing
|
||||
* over the regs when they are accessing the stack.
|
||||
*/
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
"sub r0, %0, %1 \n\t"
|
||||
"mov sp, r0 \n\t"
|
||||
#else
|
||||
"sub sp, %0, %1 \n\t"
|
||||
#endif
|
||||
"ldr r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t"
|
||||
"str %0, [sp, %2] \n\t"
|
||||
"str r0, [sp, %3] \n\t"
|
||||
"mov r0, sp \n\t"
|
||||
"bl kprobe_handler \n\t"
|
||||
|
||||
/*
|
||||
* Return to the context saved by setjmp_pre_handler
|
||||
* and restored by longjmp_break_handler.
|
||||
*/
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
"ldr lr, [sp, %2] \n\t" /* lr = saved sp */
|
||||
"ldrd r0, r1, [sp, %5] \n\t" /* r0,r1 = saved lr,pc */
|
||||
"ldr r2, [sp, %4] \n\t" /* r2 = saved psr */
|
||||
"stmdb lr!, {r0, r1, r2} \n\t" /* push saved lr and */
|
||||
/* rfe context */
|
||||
"ldmia sp, {r0 - r12} \n\t"
|
||||
"mov sp, lr \n\t"
|
||||
"ldr lr, [sp], #4 \n\t"
|
||||
"rfeia sp! \n\t"
|
||||
#else
|
||||
"ldr r0, [sp, %4] \n\t"
|
||||
"msr cpsr_cxsf, r0 \n\t"
|
||||
"ldmia sp, {r0 - pc} \n\t"
|
||||
#endif
|
||||
:
|
||||
: "r" (kcb->jprobe_saved_regs.ARM_sp),
|
||||
"I" (sizeof(struct pt_regs) * 2),
|
||||
"J" (offsetof(struct pt_regs, ARM_sp)),
|
||||
"J" (offsetof(struct pt_regs, ARM_pc)),
|
||||
"J" (offsetof(struct pt_regs, ARM_cpsr)),
|
||||
"J" (offsetof(struct pt_regs, ARM_lr))
|
||||
: "memory", "cc");
|
||||
}
|
||||
|
||||
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
long stack_addr = kcb->jprobe_saved_regs.ARM_sp;
|
||||
long orig_sp = regs->ARM_sp;
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
|
||||
if (regs->ARM_pc == JPROBE_MAGIC_ADDR) {
|
||||
if (orig_sp != stack_addr) {
|
||||
struct pt_regs *saved_regs =
|
||||
(struct pt_regs *)kcb->jprobe_saved_regs.ARM_sp;
|
||||
printk("current sp %lx does not match saved sp %lx\n",
|
||||
orig_sp, stack_addr);
|
||||
printk("Saved registers for jprobe %p\n", jp);
|
||||
show_regs(saved_regs);
|
||||
printk("Current registers\n");
|
||||
show_regs(regs);
|
||||
BUG();
|
||||
}
|
||||
*regs = kcb->jprobe_saved_regs;
|
||||
memcpy((void *)stack_addr, kcb->jprobes_stack,
|
||||
MIN_STACK_SIZE(stack_addr));
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __kprobes arch_trampoline_kprobe(struct kprobe *p)
|
||||
{
|
||||
return 0;
|
||||
|
@ -1461,7 +1461,6 @@ fail:
|
||||
print_registers(&result_regs);
|
||||
|
||||
if (mem) {
|
||||
pr_err("current_stack=%p\n", current_stack);
|
||||
pr_err("expected_memory:\n");
|
||||
print_memory(expected_memory, mem_size);
|
||||
pr_err("result_memory:\n");
|
||||
|
@ -119,13 +119,16 @@ static inline void decode_ctrl_reg(u32 reg,
|
||||
|
||||
struct task_struct;
|
||||
struct notifier_block;
|
||||
struct perf_event_attr;
|
||||
struct perf_event;
|
||||
struct pmu;
|
||||
|
||||
extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
|
||||
int *gen_len, int *gen_type, int *offset);
|
||||
extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
|
||||
extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
|
||||
extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
|
||||
extern int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw);
|
||||
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
|
||||
unsigned long val, void *data);
|
||||
|
||||
|
@ -48,7 +48,6 @@ struct kprobe_ctlblk {
|
||||
unsigned long saved_irqflag;
|
||||
struct prev_kprobe prev_kprobe;
|
||||
struct kprobe_step_ctx ss_ctx;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
};
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *);
|
||||
|
@ -343,14 +343,13 @@ static int get_hbp_len(u8 hbp_len)
|
||||
/*
|
||||
* Check whether bp virtual address is in kernel space.
|
||||
*/
|
||||
int arch_check_bp_in_kernelspace(struct perf_event *bp)
|
||||
int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned long va;
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
va = info->address;
|
||||
len = get_hbp_len(info->ctrl.len);
|
||||
va = hw->address;
|
||||
len = get_hbp_len(hw->ctrl.len);
|
||||
|
||||
return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
|
||||
}
|
||||
@ -421,53 +420,53 @@ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
|
||||
/*
|
||||
* Construct an arch_hw_breakpoint from a perf_event.
|
||||
*/
|
||||
static int arch_build_bp_info(struct perf_event *bp)
|
||||
static int arch_build_bp_info(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
/* Type */
|
||||
switch (bp->attr.bp_type) {
|
||||
switch (attr->bp_type) {
|
||||
case HW_BREAKPOINT_X:
|
||||
info->ctrl.type = ARM_BREAKPOINT_EXECUTE;
|
||||
hw->ctrl.type = ARM_BREAKPOINT_EXECUTE;
|
||||
break;
|
||||
case HW_BREAKPOINT_R:
|
||||
info->ctrl.type = ARM_BREAKPOINT_LOAD;
|
||||
hw->ctrl.type = ARM_BREAKPOINT_LOAD;
|
||||
break;
|
||||
case HW_BREAKPOINT_W:
|
||||
info->ctrl.type = ARM_BREAKPOINT_STORE;
|
||||
hw->ctrl.type = ARM_BREAKPOINT_STORE;
|
||||
break;
|
||||
case HW_BREAKPOINT_RW:
|
||||
info->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
|
||||
hw->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Len */
|
||||
switch (bp->attr.bp_len) {
|
||||
switch (attr->bp_len) {
|
||||
case HW_BREAKPOINT_LEN_1:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_1;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_1;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_2:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_2;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_2;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_3:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_3;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_3;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_4:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_4;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_5:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_5;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_5;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_6:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_6;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_6;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_7:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_7;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_7;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_8:
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_8;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_8;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -478,37 +477,37 @@ static int arch_build_bp_info(struct perf_event *bp)
|
||||
* AArch32 also requires breakpoints of length 2 for Thumb.
|
||||
* Watchpoints can be of length 1, 2, 4 or 8 bytes.
|
||||
*/
|
||||
if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
|
||||
if (hw->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
|
||||
if (is_compat_bp(bp)) {
|
||||
if (info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
|
||||
info->ctrl.len != ARM_BREAKPOINT_LEN_4)
|
||||
if (hw->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
|
||||
hw->ctrl.len != ARM_BREAKPOINT_LEN_4)
|
||||
return -EINVAL;
|
||||
} else if (info->ctrl.len != ARM_BREAKPOINT_LEN_4) {
|
||||
} else if (hw->ctrl.len != ARM_BREAKPOINT_LEN_4) {
|
||||
/*
|
||||
* FIXME: Some tools (I'm looking at you perf) assume
|
||||
* that breakpoints should be sizeof(long). This
|
||||
* is nonsense. For now, we fix up the parameter
|
||||
* but we should probably return -EINVAL instead.
|
||||
*/
|
||||
info->ctrl.len = ARM_BREAKPOINT_LEN_4;
|
||||
hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
|
||||
}
|
||||
}
|
||||
|
||||
/* Address */
|
||||
info->address = bp->attr.bp_addr;
|
||||
hw->address = attr->bp_addr;
|
||||
|
||||
/*
|
||||
* Privilege
|
||||
* Note that we disallow combined EL0/EL1 breakpoints because
|
||||
* that would complicate the stepping code.
|
||||
*/
|
||||
if (arch_check_bp_in_kernelspace(bp))
|
||||
info->ctrl.privilege = AARCH64_BREAKPOINT_EL1;
|
||||
if (arch_check_bp_in_kernelspace(hw))
|
||||
hw->ctrl.privilege = AARCH64_BREAKPOINT_EL1;
|
||||
else
|
||||
info->ctrl.privilege = AARCH64_BREAKPOINT_EL0;
|
||||
hw->ctrl.privilege = AARCH64_BREAKPOINT_EL0;
|
||||
|
||||
/* Enabled? */
|
||||
info->ctrl.enabled = !bp->attr.disabled;
|
||||
hw->ctrl.enabled = !attr->disabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -516,14 +515,15 @@ static int arch_build_bp_info(struct perf_event *bp)
|
||||
/*
|
||||
* Validate the arch-specific HW Breakpoint register settings.
|
||||
*/
|
||||
int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
int ret;
|
||||
u64 alignment_mask, offset;
|
||||
|
||||
/* Build the arch_hw_breakpoint. */
|
||||
ret = arch_build_bp_info(bp);
|
||||
ret = arch_build_bp_info(bp, attr, hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -537,42 +537,42 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
* that here.
|
||||
*/
|
||||
if (is_compat_bp(bp)) {
|
||||
if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
|
||||
if (hw->ctrl.len == ARM_BREAKPOINT_LEN_8)
|
||||
alignment_mask = 0x7;
|
||||
else
|
||||
alignment_mask = 0x3;
|
||||
offset = info->address & alignment_mask;
|
||||
offset = hw->address & alignment_mask;
|
||||
switch (offset) {
|
||||
case 0:
|
||||
/* Aligned */
|
||||
break;
|
||||
case 1:
|
||||
/* Allow single byte watchpoint. */
|
||||
if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
|
||||
if (hw->ctrl.len == ARM_BREAKPOINT_LEN_1)
|
||||
break;
|
||||
case 2:
|
||||
/* Allow halfword watchpoints and breakpoints. */
|
||||
if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
|
||||
if (hw->ctrl.len == ARM_BREAKPOINT_LEN_2)
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE)
|
||||
if (hw->ctrl.type == ARM_BREAKPOINT_EXECUTE)
|
||||
alignment_mask = 0x3;
|
||||
else
|
||||
alignment_mask = 0x7;
|
||||
offset = info->address & alignment_mask;
|
||||
offset = hw->address & alignment_mask;
|
||||
}
|
||||
|
||||
info->address &= ~alignment_mask;
|
||||
info->ctrl.len <<= offset;
|
||||
hw->address &= ~alignment_mask;
|
||||
hw->ctrl.len <<= offset;
|
||||
|
||||
/*
|
||||
* Disallow per-task kernel breakpoints since these would
|
||||
* complicate the stepping code.
|
||||
*/
|
||||
if (info->ctrl.privilege == AARCH64_BREAKPOINT_EL1 && bp->hw.target)
|
||||
if (hw->ctrl.privilege == AARCH64_BREAKPOINT_EL1 && bp->hw.target)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
@ -275,7 +275,7 @@ static int __kprobes reenter_kprobe(struct kprobe *p,
|
||||
break;
|
||||
case KPROBE_HIT_SS:
|
||||
case KPROBE_REENTER:
|
||||
pr_warn("Unrecoverable kprobe detected at %p.\n", p->addr);
|
||||
pr_warn("Unrecoverable kprobe detected.\n");
|
||||
dump_kprobe(p);
|
||||
BUG();
|
||||
break;
|
||||
@ -395,9 +395,9 @@ static void __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
/*
|
||||
* If we have no pre-handler or it returned 0, we
|
||||
* continue with normal processing. If we have a
|
||||
* pre-handler and it returned non-zero, it prepped
|
||||
* for calling the break_handler below on re-entry,
|
||||
* so get out doing nothing more here.
|
||||
* pre-handler and it returned non-zero, it will
|
||||
* modify the execution path and no need to single
|
||||
* stepping. Let's just reset current kprobe and exit.
|
||||
*
|
||||
* pre_handler can hit a breakpoint and can step thru
|
||||
* before return, keep PSTATE D-flag enabled until
|
||||
@ -405,16 +405,8 @@ static void __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
*/
|
||||
if (!p->pre_handler || !p->pre_handler(p, regs)) {
|
||||
setup_singlestep(p, regs, kcb, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ((le32_to_cpu(*(kprobe_opcode_t *) addr) ==
|
||||
BRK64_OPCODE_KPROBES) && cur_kprobe) {
|
||||
/* We probably hit a jprobe. Call its break handler. */
|
||||
if (cur_kprobe->break_handler &&
|
||||
cur_kprobe->break_handler(cur_kprobe, regs)) {
|
||||
setup_singlestep(cur_kprobe, regs, kcb, 0);
|
||||
return;
|
||||
} else
|
||||
reset_current_kprobe();
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -465,74 +457,6 @@ kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr)
|
||||
return DBG_HOOK_HANDLED;
|
||||
}
|
||||
|
||||
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
kcb->jprobe_saved_regs = *regs;
|
||||
/*
|
||||
* Since we can't be sure where in the stack frame "stacked"
|
||||
* pass-by-value arguments are stored we just don't try to
|
||||
* duplicate any of the stack. Do not use jprobes on functions that
|
||||
* use more than 64 bytes (after padding each to an 8 byte boundary)
|
||||
* of arguments, or pass individual arguments larger than 16 bytes.
|
||||
*/
|
||||
|
||||
instruction_pointer_set(regs, (unsigned long) jp->entry);
|
||||
preempt_disable();
|
||||
pause_graph_tracing();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void __kprobes jprobe_return(void)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
/*
|
||||
* Jprobe handler return by entering break exception,
|
||||
* encoded same as kprobe, but with following conditions
|
||||
* -a special PC to identify it from the other kprobes.
|
||||
* -restore stack addr to original saved pt_regs
|
||||
*/
|
||||
asm volatile(" mov sp, %0 \n"
|
||||
"jprobe_return_break: brk %1 \n"
|
||||
:
|
||||
: "r" (kcb->jprobe_saved_regs.sp),
|
||||
"I" (BRK64_ESR_KPROBES)
|
||||
: "memory");
|
||||
|
||||
unreachable();
|
||||
}
|
||||
|
||||
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
long stack_addr = kcb->jprobe_saved_regs.sp;
|
||||
long orig_sp = kernel_stack_pointer(regs);
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
extern const char jprobe_return_break[];
|
||||
|
||||
if (instruction_pointer(regs) != (u64) jprobe_return_break)
|
||||
return 0;
|
||||
|
||||
if (orig_sp != stack_addr) {
|
||||
struct pt_regs *saved_regs =
|
||||
(struct pt_regs *)kcb->jprobe_saved_regs.sp;
|
||||
pr_err("current sp %lx does not match saved sp %lx\n",
|
||||
orig_sp, stack_addr);
|
||||
pr_err("Saved registers for jprobe %p\n", jp);
|
||||
__show_regs(saved_regs);
|
||||
pr_err("Current registers\n");
|
||||
__show_regs(regs);
|
||||
BUG();
|
||||
}
|
||||
unpause_graph_tracing();
|
||||
*regs = kcb->jprobe_saved_regs;
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool arch_within_kprobe_blacklist(unsigned long addr)
|
||||
{
|
||||
if ((addr >= (unsigned long)__kprobes_text_start &&
|
||||
|
@ -82,8 +82,6 @@ struct prev_kprobe {
|
||||
#define ARCH_PREV_KPROBE_SZ 2
|
||||
struct kprobe_ctlblk {
|
||||
unsigned long kprobe_status;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
unsigned long jprobes_saved_stacked_regs[MAX_PARAM_RSE_SIZE];
|
||||
unsigned long *bsp;
|
||||
unsigned long cfm;
|
||||
atomic_t prev_kprobe_index;
|
||||
|
@ -14,7 +14,6 @@
|
||||
*/
|
||||
#define __IA64_BREAK_KDB 0x80100
|
||||
#define __IA64_BREAK_KPROBE 0x81000 /* .. 0x81fff */
|
||||
#define __IA64_BREAK_JPROBE 0x82000
|
||||
|
||||
/*
|
||||
* OS-specific break numbers:
|
||||
|
@ -25,7 +25,7 @@ obj-$(CONFIG_NUMA) += numa.o
|
||||
obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o
|
||||
obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
|
||||
obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o
|
||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
||||
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o
|
||||
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Jprobe specific operations
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Copyright (C) Intel Corporation, 2005
|
||||
*
|
||||
* 2005-May Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
|
||||
* <anil.s.keshavamurthy@intel.com> initial implementation
|
||||
*
|
||||
* Jprobes (a.k.a. "jump probes" which is built on-top of kprobes) allow a
|
||||
* probe to be inserted into the beginning of a function call. The fundamental
|
||||
* difference between a jprobe and a kprobe is the jprobe handler is executed
|
||||
* in the same context as the target function, while the kprobe handlers
|
||||
* are executed in interrupt context.
|
||||
*
|
||||
* For jprobes we initially gain control by placing a break point in the
|
||||
* first instruction of the targeted function. When we catch that specific
|
||||
* break, we:
|
||||
* * set the return address to our jprobe_inst_return() function
|
||||
* * jump to the jprobe handler function
|
||||
*
|
||||
* Since we fixed up the return address, the jprobe handler will return to our
|
||||
* jprobe_inst_return() function, giving us control again. At this point we
|
||||
* are back in the parents frame marker, so we do yet another call to our
|
||||
* jprobe_break() function to fix up the frame marker as it would normally
|
||||
* exist in the target function.
|
||||
*
|
||||
* Our jprobe_return function then transfers control back to kprobes.c by
|
||||
* executing a break instruction using one of our reserved numbers. When we
|
||||
* catch that break in kprobes.c, we continue like we do for a normal kprobe
|
||||
* by single stepping the emulated instruction, and then returning execution
|
||||
* to the correct location.
|
||||
*/
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/break.h>
|
||||
|
||||
/*
|
||||
* void jprobe_break(void)
|
||||
*/
|
||||
.section .kprobes.text, "ax"
|
||||
ENTRY(jprobe_break)
|
||||
break.m __IA64_BREAK_JPROBE
|
||||
END(jprobe_break)
|
||||
|
||||
/*
|
||||
* void jprobe_inst_return(void)
|
||||
*/
|
||||
GLOBAL_ENTRY(jprobe_inst_return)
|
||||
br.call.sptk.many b0=jprobe_break
|
||||
END(jprobe_inst_return)
|
||||
|
||||
GLOBAL_ENTRY(invalidate_stacked_regs)
|
||||
movl r16=invalidate_restore_cfm
|
||||
;;
|
||||
mov b6=r16
|
||||
;;
|
||||
br.ret.sptk.many b6
|
||||
;;
|
||||
invalidate_restore_cfm:
|
||||
mov r16=ar.rsc
|
||||
;;
|
||||
mov ar.rsc=r0
|
||||
;;
|
||||
loadrs
|
||||
;;
|
||||
mov ar.rsc=r16
|
||||
;;
|
||||
br.cond.sptk.many rp
|
||||
END(invalidate_stacked_regs)
|
||||
|
||||
GLOBAL_ENTRY(flush_register_stack)
|
||||
// flush dirty regs to backing store (must be first in insn group)
|
||||
flushrs
|
||||
;;
|
||||
br.ret.sptk.many rp
|
||||
END(flush_register_stack)
|
||||
|
@ -35,8 +35,6 @@
|
||||
#include <asm/sections.h>
|
||||
#include <asm/exception.h>
|
||||
|
||||
extern void jprobe_inst_return(void);
|
||||
|
||||
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
|
||||
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
|
||||
|
||||
@ -480,12 +478,9 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
kretprobe_assert(ri, orig_ret_address, trampoline_address);
|
||||
|
||||
reset_current_kprobe();
|
||||
kretprobe_hash_unlock(current, &flags);
|
||||
preempt_enable_no_resched();
|
||||
|
||||
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
|
||||
hlist_del(&ri->hlist);
|
||||
@ -819,14 +814,6 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
|
||||
prepare_ss(p, regs);
|
||||
kcb->kprobe_status = KPROBE_REENTER;
|
||||
return 1;
|
||||
} else if (args->err == __IA64_BREAK_JPROBE) {
|
||||
/*
|
||||
* jprobe instrumented function just completed
|
||||
*/
|
||||
p = __this_cpu_read(current_kprobe);
|
||||
if (p->break_handler && p->break_handler(p, regs)) {
|
||||
goto ss_probe;
|
||||
}
|
||||
} else if (!is_ia64_break_inst(regs)) {
|
||||
/* The breakpoint instruction was removed by
|
||||
* another cpu right after we hit, no further
|
||||
@ -861,15 +848,12 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
|
||||
set_current_kprobe(p, kcb);
|
||||
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
|
||||
if (p->pre_handler && p->pre_handler(p, regs))
|
||||
/*
|
||||
* Our pre-handler is specifically requesting that we just
|
||||
* do a return. This is used for both the jprobe pre-handler
|
||||
* and the kretprobe trampoline
|
||||
*/
|
||||
if (p->pre_handler && p->pre_handler(p, regs)) {
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ss_probe:
|
||||
#if !defined(CONFIG_PREEMPT)
|
||||
if (p->ainsn.inst_flag == INST_FLAG_BOOSTABLE && !p->post_handler) {
|
||||
/* Boost up -- we can execute copied instructions directly */
|
||||
@ -992,7 +976,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||
case DIE_BREAK:
|
||||
/* err is break number from ia64_bad_break() */
|
||||
if ((args->err >> 12) == (__IA64_BREAK_KPROBE >> 12)
|
||||
|| args->err == __IA64_BREAK_JPROBE
|
||||
|| args->err == 0)
|
||||
if (pre_kprobes_handler(args))
|
||||
ret = NOTIFY_STOP;
|
||||
@ -1040,74 +1023,6 @@ unsigned long arch_deref_entry_point(void *entry)
|
||||
return ((struct fnptr *)entry)->ip;
|
||||
}
|
||||
|
||||
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
unsigned long addr = arch_deref_entry_point(jp->entry);
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
struct param_bsp_cfm pa;
|
||||
int bytes;
|
||||
|
||||
/*
|
||||
* Callee owns the argument space and could overwrite it, eg
|
||||
* tail call optimization. So to be absolutely safe
|
||||
* we save the argument space before transferring the control
|
||||
* to instrumented jprobe function which runs in
|
||||
* the process context
|
||||
*/
|
||||
pa.ip = regs->cr_iip;
|
||||
unw_init_running(ia64_get_bsp_cfm, &pa);
|
||||
bytes = (char *)ia64_rse_skip_regs(pa.bsp, pa.cfm & 0x3f)
|
||||
- (char *)pa.bsp;
|
||||
memcpy( kcb->jprobes_saved_stacked_regs,
|
||||
pa.bsp,
|
||||
bytes );
|
||||
kcb->bsp = pa.bsp;
|
||||
kcb->cfm = pa.cfm;
|
||||
|
||||
/* save architectural state */
|
||||
kcb->jprobe_saved_regs = *regs;
|
||||
|
||||
/* after rfi, execute the jprobe instrumented function */
|
||||
regs->cr_iip = addr & ~0xFULL;
|
||||
ia64_psr(regs)->ri = addr & 0xf;
|
||||
regs->r1 = ((struct fnptr *)(jp->entry))->gp;
|
||||
|
||||
/*
|
||||
* fix the return address to our jprobe_inst_return() function
|
||||
* in the jprobes.S file
|
||||
*/
|
||||
regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ia64 does not need this */
|
||||
void __kprobes jprobe_return(void)
|
||||
{
|
||||
}
|
||||
|
||||
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
int bytes;
|
||||
|
||||
/* restoring architectural state */
|
||||
*regs = kcb->jprobe_saved_regs;
|
||||
|
||||
/* restoring the original argument space */
|
||||
flush_register_stack();
|
||||
bytes = (char *)ia64_rse_skip_regs(kcb->bsp, kcb->cfm & 0x3f)
|
||||
- (char *)kcb->bsp;
|
||||
memcpy( kcb->bsp,
|
||||
kcb->jprobes_saved_stacked_regs,
|
||||
bytes );
|
||||
invalidate_stacked_regs();
|
||||
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct kprobe trampoline_p = {
|
||||
.pre_handler = trampoline_probe_handler
|
||||
};
|
||||
|
@ -68,16 +68,6 @@ struct prev_kprobe {
|
||||
unsigned long saved_epc;
|
||||
};
|
||||
|
||||
#define MAX_JPROBES_STACK_SIZE 128
|
||||
#define MAX_JPROBES_STACK_ADDR \
|
||||
(((unsigned long)current_thread_info()) + THREAD_SIZE - 32 - sizeof(struct pt_regs))
|
||||
|
||||
#define MIN_JPROBES_STACK_SIZE(ADDR) \
|
||||
((((ADDR) + MAX_JPROBES_STACK_SIZE) > MAX_JPROBES_STACK_ADDR) \
|
||||
? MAX_JPROBES_STACK_ADDR - (ADDR) \
|
||||
: MAX_JPROBES_STACK_SIZE)
|
||||
|
||||
|
||||
#define SKIP_DELAYSLOT 0x0001
|
||||
|
||||
/* per-cpu kprobe control block */
|
||||
@ -86,12 +76,9 @@ struct kprobe_ctlblk {
|
||||
unsigned long kprobe_old_SR;
|
||||
unsigned long kprobe_saved_SR;
|
||||
unsigned long kprobe_saved_epc;
|
||||
unsigned long jprobe_saved_sp;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
/* Per-thread fields, used while emulating branches */
|
||||
unsigned long flags;
|
||||
unsigned long target_epc;
|
||||
u8 jprobes_stack[MAX_JPROBES_STACK_SIZE];
|
||||
struct prev_kprobe prev_kprobe;
|
||||
};
|
||||
|
||||
|
@ -326,19 +326,13 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
preempt_enable_no_resched();
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
if (addr->word != breakpoint_insn.word) {
|
||||
/*
|
||||
* The breakpoint instruction was removed by
|
||||
* another cpu right after we hit, no further
|
||||
* handling of this interrupt is appropriate
|
||||
*/
|
||||
ret = 1;
|
||||
goto no_kprobe;
|
||||
}
|
||||
p = __this_cpu_read(current_kprobe);
|
||||
if (p->break_handler && p->break_handler(p, regs))
|
||||
goto ss_probe;
|
||||
} else if (addr->word != breakpoint_insn.word) {
|
||||
/*
|
||||
* The breakpoint instruction was removed by
|
||||
* another cpu right after we hit, no further
|
||||
* handling of this interrupt is appropriate
|
||||
*/
|
||||
ret = 1;
|
||||
}
|
||||
goto no_kprobe;
|
||||
}
|
||||
@ -364,10 +358,11 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
|
||||
if (p->pre_handler && p->pre_handler(p, regs)) {
|
||||
/* handler has already set things up, so skip ss setup */
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ss_probe:
|
||||
prepare_singlestep(p, regs, kcb);
|
||||
if (kcb->flags & SKIP_DELAYSLOT) {
|
||||
kcb->kprobe_status = KPROBE_HIT_SSDONE;
|
||||
@ -468,51 +463,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
kcb->jprobe_saved_regs = *regs;
|
||||
kcb->jprobe_saved_sp = regs->regs[29];
|
||||
|
||||
memcpy(kcb->jprobes_stack, (void *)kcb->jprobe_saved_sp,
|
||||
MIN_JPROBES_STACK_SIZE(kcb->jprobe_saved_sp));
|
||||
|
||||
regs->cp0_epc = (unsigned long)(jp->entry);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Defined in the inline asm below. */
|
||||
void jprobe_return_end(void);
|
||||
|
||||
void __kprobes jprobe_return(void)
|
||||
{
|
||||
/* Assembler quirk necessitates this '0,code' business. */
|
||||
asm volatile(
|
||||
"break 0,%0\n\t"
|
||||
".globl jprobe_return_end\n"
|
||||
"jprobe_return_end:\n"
|
||||
: : "n" (BRK_KPROBE_BP) : "memory");
|
||||
}
|
||||
|
||||
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
if (regs->cp0_epc >= (unsigned long)jprobe_return &&
|
||||
regs->cp0_epc <= (unsigned long)jprobe_return_end) {
|
||||
*regs = kcb->jprobe_saved_regs;
|
||||
memcpy((void *)kcb->jprobe_saved_sp, kcb->jprobes_stack,
|
||||
MIN_JPROBES_STACK_SIZE(kcb->jprobe_saved_sp));
|
||||
preempt_enable_no_resched();
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function return probe trampoline:
|
||||
* - init_kprobes() establishes a probepoint here
|
||||
@ -595,9 +545,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
|
||||
kretprobe_assert(ri, orig_ret_address, trampoline_address);
|
||||
instruction_pointer(regs) = orig_ret_address;
|
||||
|
||||
reset_current_kprobe();
|
||||
kretprobe_hash_unlock(current, &flags);
|
||||
preempt_enable_no_resched();
|
||||
|
||||
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
|
||||
hlist_del(&ri->hlist);
|
||||
|
@ -52,6 +52,7 @@ struct arch_hw_breakpoint {
|
||||
#include <asm/reg.h>
|
||||
#include <asm/debug.h>
|
||||
|
||||
struct perf_event_attr;
|
||||
struct perf_event;
|
||||
struct pmu;
|
||||
struct perf_sample_data;
|
||||
@ -60,8 +61,10 @@ struct perf_sample_data;
|
||||
|
||||
extern int hw_breakpoint_slots(int type);
|
||||
extern int arch_bp_generic_fields(int type, int *gen_bp_type);
|
||||
extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
|
||||
extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
|
||||
extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
|
||||
extern int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw);
|
||||
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
|
||||
unsigned long val, void *data);
|
||||
int arch_install_hw_breakpoint(struct perf_event *bp);
|
||||
|
@ -88,7 +88,6 @@ struct prev_kprobe {
|
||||
struct kprobe_ctlblk {
|
||||
unsigned long kprobe_status;
|
||||
unsigned long kprobe_saved_msr;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
struct prev_kprobe prev_kprobe;
|
||||
};
|
||||
|
||||
@ -103,17 +102,6 @@ extern int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
|
||||
extern int kprobe_handler(struct pt_regs *regs);
|
||||
extern int kprobe_post_handler(struct pt_regs *regs);
|
||||
#ifdef CONFIG_KPROBES_ON_FTRACE
|
||||
extern int __is_active_jprobe(unsigned long addr);
|
||||
extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
|
||||
struct kprobe_ctlblk *kcb);
|
||||
#else
|
||||
static inline int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
|
||||
struct kprobe_ctlblk *kcb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
static inline int kprobe_handler(struct pt_regs *regs) { return 0; }
|
||||
static inline int kprobe_post_handler(struct pt_regs *regs) { return 0; }
|
||||
|
@ -119,11 +119,9 @@ void arch_unregister_hw_breakpoint(struct perf_event *bp)
|
||||
/*
|
||||
* Check for virtual address in kernel space.
|
||||
*/
|
||||
int arch_check_bp_in_kernelspace(struct perf_event *bp)
|
||||
int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
return is_kernel_addr(info->address);
|
||||
return is_kernel_addr(hw->address);
|
||||
}
|
||||
|
||||
int arch_bp_generic_fields(int type, int *gen_bp_type)
|
||||
@ -141,30 +139,31 @@ int arch_bp_generic_fields(int type, int *gen_bp_type)
|
||||
/*
|
||||
* Validate the arch-specific HW Breakpoint register settings
|
||||
*/
|
||||
int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
int ret = -EINVAL, length_max;
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
if (!bp)
|
||||
return ret;
|
||||
|
||||
info->type = HW_BRK_TYPE_TRANSLATE;
|
||||
if (bp->attr.bp_type & HW_BREAKPOINT_R)
|
||||
info->type |= HW_BRK_TYPE_READ;
|
||||
if (bp->attr.bp_type & HW_BREAKPOINT_W)
|
||||
info->type |= HW_BRK_TYPE_WRITE;
|
||||
if (info->type == HW_BRK_TYPE_TRANSLATE)
|
||||
hw->type = HW_BRK_TYPE_TRANSLATE;
|
||||
if (attr->bp_type & HW_BREAKPOINT_R)
|
||||
hw->type |= HW_BRK_TYPE_READ;
|
||||
if (attr->bp_type & HW_BREAKPOINT_W)
|
||||
hw->type |= HW_BRK_TYPE_WRITE;
|
||||
if (hw->type == HW_BRK_TYPE_TRANSLATE)
|
||||
/* must set alteast read or write */
|
||||
return ret;
|
||||
if (!(bp->attr.exclude_user))
|
||||
info->type |= HW_BRK_TYPE_USER;
|
||||
if (!(bp->attr.exclude_kernel))
|
||||
info->type |= HW_BRK_TYPE_KERNEL;
|
||||
if (!(bp->attr.exclude_hv))
|
||||
info->type |= HW_BRK_TYPE_HYP;
|
||||
info->address = bp->attr.bp_addr;
|
||||
info->len = bp->attr.bp_len;
|
||||
if (!attr->exclude_user)
|
||||
hw->type |= HW_BRK_TYPE_USER;
|
||||
if (!attr->exclude_kernel)
|
||||
hw->type |= HW_BRK_TYPE_KERNEL;
|
||||
if (!attr->exclude_hv)
|
||||
hw->type |= HW_BRK_TYPE_HYP;
|
||||
hw->address = attr->bp_addr;
|
||||
hw->len = attr->bp_len;
|
||||
|
||||
/*
|
||||
* Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8)
|
||||
@ -178,12 +177,12 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
if (cpu_has_feature(CPU_FTR_DAWR)) {
|
||||
length_max = 512 ; /* 64 doublewords */
|
||||
/* DAWR region can't cross 512 boundary */
|
||||
if ((bp->attr.bp_addr >> 9) !=
|
||||
((bp->attr.bp_addr + bp->attr.bp_len - 1) >> 9))
|
||||
if ((attr->bp_addr >> 9) !=
|
||||
((attr->bp_addr + attr->bp_len - 1) >> 9))
|
||||
return -EINVAL;
|
||||
}
|
||||
if (info->len >
|
||||
(length_max - (info->address & HW_BREAKPOINT_ALIGN)))
|
||||
if (hw->len >
|
||||
(length_max - (hw->address & HW_BREAKPOINT_ALIGN)))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -25,50 +25,6 @@
|
||||
#include <linux/preempt.h>
|
||||
#include <linux/ftrace.h>
|
||||
|
||||
/*
|
||||
* This is called from ftrace code after invoking registered handlers to
|
||||
* disambiguate regs->nip changes done by jprobes and livepatch. We check if
|
||||
* there is an active jprobe at the provided address (mcount location).
|
||||
*/
|
||||
int __is_active_jprobe(unsigned long addr)
|
||||
{
|
||||
if (!preemptible()) {
|
||||
struct kprobe *p = raw_cpu_read(current_kprobe);
|
||||
return (p && (unsigned long)p->addr == addr) ? 1 : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nokprobe_inline
|
||||
int __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
|
||||
struct kprobe_ctlblk *kcb, unsigned long orig_nip)
|
||||
{
|
||||
/*
|
||||
* Emulate singlestep (and also recover regs->nip)
|
||||
* as if there is a nop
|
||||
*/
|
||||
regs->nip = (unsigned long)p->addr + MCOUNT_INSN_SIZE;
|
||||
if (unlikely(p->post_handler)) {
|
||||
kcb->kprobe_status = KPROBE_HIT_SSDONE;
|
||||
p->post_handler(p, regs, 0);
|
||||
}
|
||||
__this_cpu_write(current_kprobe, NULL);
|
||||
if (orig_nip)
|
||||
regs->nip = orig_nip;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
|
||||
struct kprobe_ctlblk *kcb)
|
||||
{
|
||||
if (kprobe_ftrace(p))
|
||||
return __skip_singlestep(p, regs, kcb, 0);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
NOKPROBE_SYMBOL(skip_singlestep);
|
||||
|
||||
/* Ftrace callback handler for kprobes */
|
||||
void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
|
||||
struct ftrace_ops *ops, struct pt_regs *regs)
|
||||
@ -76,18 +32,14 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
|
||||
struct kprobe *p;
|
||||
struct kprobe_ctlblk *kcb;
|
||||
|
||||
preempt_disable();
|
||||
|
||||
p = get_kprobe((kprobe_opcode_t *)nip);
|
||||
if (unlikely(!p) || kprobe_disabled(p))
|
||||
goto end;
|
||||
return;
|
||||
|
||||
kcb = get_kprobe_ctlblk();
|
||||
if (kprobe_running()) {
|
||||
kprobes_inc_nmissed_count(p);
|
||||
} else {
|
||||
unsigned long orig_nip = regs->nip;
|
||||
|
||||
/*
|
||||
* On powerpc, NIP is *before* this instruction for the
|
||||
* pre handler
|
||||
@ -96,19 +48,23 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
|
||||
|
||||
__this_cpu_write(current_kprobe, p);
|
||||
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
if (!p->pre_handler || !p->pre_handler(p, regs))
|
||||
__skip_singlestep(p, regs, kcb, orig_nip);
|
||||
else {
|
||||
if (!p->pre_handler || !p->pre_handler(p, regs)) {
|
||||
/*
|
||||
* If pre_handler returns !0, it sets regs->nip and
|
||||
* resets current kprobe. In this case, we should not
|
||||
* re-enable preemption.
|
||||
* Emulate singlestep (and also recover regs->nip)
|
||||
* as if there is a nop
|
||||
*/
|
||||
return;
|
||||
regs->nip += MCOUNT_INSN_SIZE;
|
||||
if (unlikely(p->post_handler)) {
|
||||
kcb->kprobe_status = KPROBE_HIT_SSDONE;
|
||||
p->post_handler(p, regs, 0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If pre_handler returns !0, it changes regs->nip. We have to
|
||||
* skip emulating post_handler.
|
||||
*/
|
||||
__this_cpu_write(current_kprobe, NULL);
|
||||
}
|
||||
end:
|
||||
preempt_enable_no_resched();
|
||||
}
|
||||
NOKPROBE_SYMBOL(kprobe_ftrace_handler);
|
||||
|
||||
|
@ -317,25 +317,17 @@ int kprobe_handler(struct pt_regs *regs)
|
||||
}
|
||||
prepare_singlestep(p, regs);
|
||||
return 1;
|
||||
} else {
|
||||
if (*addr != BREAKPOINT_INSTRUCTION) {
|
||||
/* If trap variant, then it belongs not to us */
|
||||
kprobe_opcode_t cur_insn = *addr;
|
||||
if (is_trap(cur_insn))
|
||||
goto no_kprobe;
|
||||
/* The breakpoint instruction was removed by
|
||||
* another cpu right after we hit, no further
|
||||
* handling of this interrupt is appropriate
|
||||
*/
|
||||
ret = 1;
|
||||
} else if (*addr != BREAKPOINT_INSTRUCTION) {
|
||||
/* If trap variant, then it belongs not to us */
|
||||
kprobe_opcode_t cur_insn = *addr;
|
||||
|
||||
if (is_trap(cur_insn))
|
||||
goto no_kprobe;
|
||||
}
|
||||
p = __this_cpu_read(current_kprobe);
|
||||
if (p->break_handler && p->break_handler(p, regs)) {
|
||||
if (!skip_singlestep(p, regs, kcb))
|
||||
goto ss_probe;
|
||||
ret = 1;
|
||||
}
|
||||
/* The breakpoint instruction was removed by
|
||||
* another cpu right after we hit, no further
|
||||
* handling of this interrupt is appropriate
|
||||
*/
|
||||
ret = 1;
|
||||
}
|
||||
goto no_kprobe;
|
||||
}
|
||||
@ -350,7 +342,7 @@ int kprobe_handler(struct pt_regs *regs)
|
||||
*/
|
||||
kprobe_opcode_t cur_insn = *addr;
|
||||
if (is_trap(cur_insn))
|
||||
goto no_kprobe;
|
||||
goto no_kprobe;
|
||||
/*
|
||||
* The breakpoint instruction was removed right
|
||||
* after we hit it. Another cpu has removed
|
||||
@ -366,11 +358,13 @@ int kprobe_handler(struct pt_regs *regs)
|
||||
|
||||
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
set_current_kprobe(p, regs, kcb);
|
||||
if (p->pre_handler && p->pre_handler(p, regs))
|
||||
/* handler has already set things up, so skip ss setup */
|
||||
if (p->pre_handler && p->pre_handler(p, regs)) {
|
||||
/* handler changed execution path, so skip ss setup */
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ss_probe:
|
||||
if (p->ainsn.boostable >= 0) {
|
||||
ret = try_to_emulate(p, regs);
|
||||
|
||||
@ -611,60 +605,6 @@ unsigned long arch_deref_entry_point(void *entry)
|
||||
}
|
||||
NOKPROBE_SYMBOL(arch_deref_entry_point);
|
||||
|
||||
int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
|
||||
|
||||
/* setup return addr to the jprobe handler routine */
|
||||
regs->nip = arch_deref_entry_point(jp->entry);
|
||||
#ifdef PPC64_ELF_ABI_v2
|
||||
regs->gpr[12] = (unsigned long)jp->entry;
|
||||
#elif defined(PPC64_ELF_ABI_v1)
|
||||
regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* jprobes use jprobe_return() which skips the normal return
|
||||
* path of the function, and this messes up the accounting of the
|
||||
* function graph tracer.
|
||||
*
|
||||
* Pause function graph tracing while performing the jprobe function.
|
||||
*/
|
||||
pause_graph_tracing();
|
||||
|
||||
return 1;
|
||||
}
|
||||
NOKPROBE_SYMBOL(setjmp_pre_handler);
|
||||
|
||||
void __used jprobe_return(void)
|
||||
{
|
||||
asm volatile("jprobe_return_trap:\n"
|
||||
"trap\n"
|
||||
::: "memory");
|
||||
}
|
||||
NOKPROBE_SYMBOL(jprobe_return);
|
||||
|
||||
int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
if (regs->nip != ppc_kallsyms_lookup_name("jprobe_return_trap")) {
|
||||
pr_debug("longjmp_break_handler NIP (0x%lx) does not match jprobe_return_trap (0x%lx)\n",
|
||||
regs->nip, ppc_kallsyms_lookup_name("jprobe_return_trap"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
|
||||
/* It's OK to start function graph tracing again */
|
||||
unpause_graph_tracing();
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
NOKPROBE_SYMBOL(longjmp_break_handler);
|
||||
|
||||
static struct kprobe trampoline_p = {
|
||||
.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
|
||||
.pre_handler = trampoline_probe_handler
|
||||
|
@ -104,39 +104,13 @@ ftrace_regs_call:
|
||||
bl ftrace_stub
|
||||
nop
|
||||
|
||||
/* Load the possibly modified NIP */
|
||||
ld r15, _NIP(r1)
|
||||
|
||||
/* Load ctr with the possibly modified NIP */
|
||||
ld r3, _NIP(r1)
|
||||
mtctr r3
|
||||
#ifdef CONFIG_LIVEPATCH
|
||||
cmpd r14, r15 /* has NIP been altered? */
|
||||
cmpd r14, r3 /* has NIP been altered? */
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_LIVEPATCH) && defined(CONFIG_KPROBES_ON_FTRACE)
|
||||
/* NIP has not been altered, skip over further checks */
|
||||
beq 1f
|
||||
|
||||
/* Check if there is an active jprobe on us */
|
||||
subi r3, r14, 4
|
||||
bl __is_active_jprobe
|
||||
nop
|
||||
|
||||
/*
|
||||
* If r3 == 1, then this is a kprobe/jprobe.
|
||||
* else, this is livepatched function.
|
||||
*
|
||||
* The conditional branch for livepatch_handler below will use the
|
||||
* result of this comparison. For kprobe/jprobe, we just need to branch to
|
||||
* the new NIP, not call livepatch_handler. The branch below is bne, so we
|
||||
* want CR0[EQ] to be true if this is a kprobe/jprobe. Which means we want
|
||||
* CR0[EQ] = (r3 == 1).
|
||||
*/
|
||||
cmpdi r3, 1
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* Load CTR with the possibly modified NIP */
|
||||
mtctr r15
|
||||
|
||||
/* Restore gprs */
|
||||
REST_GPR(0,r1)
|
||||
REST_10GPRS(2,r1)
|
||||
@ -154,10 +128,7 @@ ftrace_regs_call:
|
||||
addi r1, r1, SWITCH_FRAME_SIZE
|
||||
|
||||
#ifdef CONFIG_LIVEPATCH
|
||||
/*
|
||||
* Based on the cmpd or cmpdi above, if the NIP was altered and we're
|
||||
* not on a kprobe/jprobe, then handle livepatch.
|
||||
*/
|
||||
/* Based on the cmpd above, if the NIP was altered handle livepatch */
|
||||
bne- livepatch_handler
|
||||
#endif
|
||||
|
||||
|
@ -1469,7 +1469,7 @@ static int collect_events(struct perf_event *group, int max_count,
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a event to the PMU.
|
||||
* Add an event to the PMU.
|
||||
* If all events are not already frozen, then we disable and
|
||||
* re-enable the PMU in order to get hw_perf_enable to do the
|
||||
* actual work of reconfiguring the PMU.
|
||||
@ -1548,7 +1548,7 @@ nocheck:
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a event from the PMU.
|
||||
* Remove an event from the PMU.
|
||||
*/
|
||||
static void power_pmu_del(struct perf_event *event, int ef_flags)
|
||||
{
|
||||
@ -1742,7 +1742,7 @@ static int power_pmu_commit_txn(struct pmu *pmu)
|
||||
/*
|
||||
* Return 1 if we might be able to put event on a limited PMC,
|
||||
* or 0 if not.
|
||||
* A event can only go on a limited PMC if it counts something
|
||||
* An event can only go on a limited PMC if it counts something
|
||||
* that a limited PMC can count, doesn't require interrupts, and
|
||||
* doesn't exclude any processor mode.
|
||||
*/
|
||||
|
@ -68,8 +68,6 @@ struct kprobe_ctlblk {
|
||||
unsigned long kprobe_saved_imask;
|
||||
unsigned long kprobe_saved_ctl[3];
|
||||
struct prev_kprobe prev_kprobe;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
|
||||
};
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *p);
|
||||
|
@ -321,38 +321,20 @@ static int kprobe_handler(struct pt_regs *regs)
|
||||
* If we have no pre-handler or it returned 0, we
|
||||
* continue with single stepping. If we have a
|
||||
* pre-handler and it returned non-zero, it prepped
|
||||
* for calling the break_handler below on re-entry
|
||||
* for jprobe processing, so get out doing nothing
|
||||
* more here.
|
||||
* for changing execution path, so get out doing
|
||||
* nothing more here.
|
||||
*/
|
||||
push_kprobe(kcb, p);
|
||||
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
if (p->pre_handler && p->pre_handler(p, regs))
|
||||
if (p->pre_handler && p->pre_handler(p, regs)) {
|
||||
pop_kprobe(kcb);
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||
}
|
||||
enable_singlestep(kcb, regs, (unsigned long) p->ainsn.insn);
|
||||
return 1;
|
||||
} else if (kprobe_running()) {
|
||||
p = __this_cpu_read(current_kprobe);
|
||||
if (p->break_handler && p->break_handler(p, regs)) {
|
||||
/*
|
||||
* Continuation after the jprobe completed and
|
||||
* caused the jprobe_return trap. The jprobe
|
||||
* break_handler "returns" to the original
|
||||
* function that still has the kprobe breakpoint
|
||||
* installed. We continue with single stepping.
|
||||
*/
|
||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||
enable_singlestep(kcb, regs,
|
||||
(unsigned long) p->ainsn.insn);
|
||||
return 1;
|
||||
} /* else:
|
||||
* No kprobe at this address and the current kprobe
|
||||
* has no break handler (no jprobe!). The kernel just
|
||||
* exploded, let the standard trap handler pick up the
|
||||
* pieces.
|
||||
*/
|
||||
} /* else:
|
||||
* No kprobe at this address and no active kprobe. The trap has
|
||||
* not been caused by a kprobe breakpoint. The race of breakpoint
|
||||
@ -452,9 +434,7 @@ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
|
||||
regs->psw.addr = orig_ret_address;
|
||||
|
||||
pop_kprobe(get_kprobe_ctlblk());
|
||||
kretprobe_hash_unlock(current, &flags);
|
||||
preempt_enable_no_resched();
|
||||
|
||||
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
|
||||
hlist_del(&ri->hlist);
|
||||
@ -661,60 +641,6 @@ int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
}
|
||||
NOKPROBE_SYMBOL(kprobe_exceptions_notify);
|
||||
|
||||
int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
unsigned long stack;
|
||||
|
||||
memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
|
||||
|
||||
/* setup return addr to the jprobe handler routine */
|
||||
regs->psw.addr = (unsigned long) jp->entry;
|
||||
regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
|
||||
|
||||
/* r15 is the stack pointer */
|
||||
stack = (unsigned long) regs->gprs[15];
|
||||
|
||||
memcpy(kcb->jprobes_stack, (void *) stack, MIN_STACK_SIZE(stack));
|
||||
|
||||
/*
|
||||
* jprobes use jprobe_return() which skips the normal return
|
||||
* path of the function, and this messes up the accounting of the
|
||||
* function graph tracer to get messed up.
|
||||
*
|
||||
* Pause function graph tracing while performing the jprobe function.
|
||||
*/
|
||||
pause_graph_tracing();
|
||||
return 1;
|
||||
}
|
||||
NOKPROBE_SYMBOL(setjmp_pre_handler);
|
||||
|
||||
void jprobe_return(void)
|
||||
{
|
||||
asm volatile(".word 0x0002");
|
||||
}
|
||||
NOKPROBE_SYMBOL(jprobe_return);
|
||||
|
||||
int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
unsigned long stack;
|
||||
|
||||
/* It's OK to start function graph tracing again */
|
||||
unpause_graph_tracing();
|
||||
|
||||
stack = (unsigned long) kcb->jprobe_saved_regs.gprs[15];
|
||||
|
||||
/* Put the regs back */
|
||||
memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
|
||||
/* put the stack back */
|
||||
memcpy((void *) stack, kcb->jprobes_stack, MIN_STACK_SIZE(stack));
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
NOKPROBE_SYMBOL(longjmp_break_handler);
|
||||
|
||||
static struct kprobe trampoline = {
|
||||
.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
|
||||
.pre_handler = trampoline_probe_handler
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
struct arch_hw_breakpoint {
|
||||
char *name; /* Contains name of the symbol to set bkpt */
|
||||
unsigned long address;
|
||||
u16 len;
|
||||
u16 type;
|
||||
@ -41,6 +40,7 @@ struct sh_ubc {
|
||||
struct clk *clk; /* optional interface clock / MSTP bit */
|
||||
};
|
||||
|
||||
struct perf_event_attr;
|
||||
struct perf_event;
|
||||
struct task_struct;
|
||||
struct pmu;
|
||||
@ -54,8 +54,10 @@ static inline int hw_breakpoint_slots(int type)
|
||||
}
|
||||
|
||||
/* arch/sh/kernel/hw_breakpoint.c */
|
||||
extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
|
||||
extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
|
||||
extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
|
||||
extern int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw);
|
||||
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
|
||||
unsigned long val, void *data);
|
||||
|
||||
|
@ -27,7 +27,6 @@ struct kprobe;
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *);
|
||||
void kretprobe_trampoline(void);
|
||||
void jprobe_return_end(void);
|
||||
|
||||
/* Architecture specific copy of original instruction*/
|
||||
struct arch_specific_insn {
|
||||
@ -43,9 +42,6 @@ struct prev_kprobe {
|
||||
/* per-cpu kprobe control block */
|
||||
struct kprobe_ctlblk {
|
||||
unsigned long kprobe_status;
|
||||
unsigned long jprobe_saved_r15;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
|
||||
struct prev_kprobe prev_kprobe;
|
||||
};
|
||||
|
||||
|
@ -124,14 +124,13 @@ static int get_hbp_len(u16 hbp_len)
|
||||
/*
|
||||
* Check for virtual address in kernel space.
|
||||
*/
|
||||
int arch_check_bp_in_kernelspace(struct perf_event *bp)
|
||||
int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned long va;
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
va = info->address;
|
||||
len = get_hbp_len(info->len);
|
||||
va = hw->address;
|
||||
len = get_hbp_len(hw->len);
|
||||
|
||||
return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
|
||||
}
|
||||
@ -174,40 +173,40 @@ int arch_bp_generic_fields(int sh_len, int sh_type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_build_bp_info(struct perf_event *bp)
|
||||
static int arch_build_bp_info(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
info->address = bp->attr.bp_addr;
|
||||
hw->address = attr->bp_addr;
|
||||
|
||||
/* Len */
|
||||
switch (bp->attr.bp_len) {
|
||||
switch (attr->bp_len) {
|
||||
case HW_BREAKPOINT_LEN_1:
|
||||
info->len = SH_BREAKPOINT_LEN_1;
|
||||
hw->len = SH_BREAKPOINT_LEN_1;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_2:
|
||||
info->len = SH_BREAKPOINT_LEN_2;
|
||||
hw->len = SH_BREAKPOINT_LEN_2;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_4:
|
||||
info->len = SH_BREAKPOINT_LEN_4;
|
||||
hw->len = SH_BREAKPOINT_LEN_4;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_8:
|
||||
info->len = SH_BREAKPOINT_LEN_8;
|
||||
hw->len = SH_BREAKPOINT_LEN_8;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Type */
|
||||
switch (bp->attr.bp_type) {
|
||||
switch (attr->bp_type) {
|
||||
case HW_BREAKPOINT_R:
|
||||
info->type = SH_BREAKPOINT_READ;
|
||||
hw->type = SH_BREAKPOINT_READ;
|
||||
break;
|
||||
case HW_BREAKPOINT_W:
|
||||
info->type = SH_BREAKPOINT_WRITE;
|
||||
hw->type = SH_BREAKPOINT_WRITE;
|
||||
break;
|
||||
case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
|
||||
info->type = SH_BREAKPOINT_RW;
|
||||
hw->type = SH_BREAKPOINT_RW;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -219,19 +218,20 @@ static int arch_build_bp_info(struct perf_event *bp)
|
||||
/*
|
||||
* Validate the arch-specific HW Breakpoint register settings
|
||||
*/
|
||||
int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
unsigned int align;
|
||||
int ret;
|
||||
|
||||
ret = arch_build_bp_info(bp);
|
||||
ret = arch_build_bp_info(bp, attr, hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = -EINVAL;
|
||||
|
||||
switch (info->len) {
|
||||
switch (hw->len) {
|
||||
case SH_BREAKPOINT_LEN_1:
|
||||
align = 0;
|
||||
break;
|
||||
@ -248,18 +248,11 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* For kernel-addresses, either the address or symbol name can be
|
||||
* specified.
|
||||
*/
|
||||
if (info->name)
|
||||
info->address = (unsigned long)kallsyms_lookup_name(info->name);
|
||||
|
||||
/*
|
||||
* Check that the low-order bits of the address are appropriate
|
||||
* for the alignment implied by len.
|
||||
*/
|
||||
if (info->address & align)
|
||||
if (hw->address & align)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@ -346,7 +339,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
|
||||
perf_bp_event(bp, args->regs);
|
||||
|
||||
/* Deliver the signal to userspace */
|
||||
if (!arch_check_bp_in_kernelspace(bp)) {
|
||||
if (!arch_check_bp_in_kernelspace(&bp->hw.info)) {
|
||||
force_sig_fault(SIGTRAP, TRAP_HWBKPT,
|
||||
(void __user *)NULL, current);
|
||||
}
|
||||
|
@ -248,11 +248,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
prepare_singlestep(p, regs);
|
||||
kcb->kprobe_status = KPROBE_REENTER;
|
||||
return 1;
|
||||
} else {
|
||||
p = __this_cpu_read(current_kprobe);
|
||||
if (p->break_handler && p->break_handler(p, regs)) {
|
||||
goto ss_probe;
|
||||
}
|
||||
}
|
||||
goto no_kprobe;
|
||||
}
|
||||
@ -277,11 +272,13 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
set_current_kprobe(p, regs, kcb);
|
||||
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
|
||||
if (p->pre_handler && p->pre_handler(p, regs))
|
||||
if (p->pre_handler && p->pre_handler(p, regs)) {
|
||||
/* handler has already set things up, so skip ss setup */
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ss_probe:
|
||||
prepare_singlestep(p, regs);
|
||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||
return 1;
|
||||
@ -358,8 +355,6 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
regs->pc = orig_ret_address;
|
||||
kretprobe_hash_unlock(current, &flags);
|
||||
|
||||
preempt_enable_no_resched();
|
||||
|
||||
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
|
||||
hlist_del(&ri->hlist);
|
||||
kfree(ri);
|
||||
@ -508,14 +503,8 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||
if (post_kprobe_handler(args->regs))
|
||||
ret = NOTIFY_STOP;
|
||||
} else {
|
||||
if (kprobe_handler(args->regs)) {
|
||||
if (kprobe_handler(args->regs))
|
||||
ret = NOTIFY_STOP;
|
||||
} else {
|
||||
p = __this_cpu_read(current_kprobe);
|
||||
if (p->break_handler &&
|
||||
p->break_handler(p, args->regs))
|
||||
ret = NOTIFY_STOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -523,57 +512,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
unsigned long addr;
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
kcb->jprobe_saved_regs = *regs;
|
||||
kcb->jprobe_saved_r15 = regs->regs[15];
|
||||
addr = kcb->jprobe_saved_r15;
|
||||
|
||||
/*
|
||||
* TBD: As Linus pointed out, gcc assumes that the callee
|
||||
* owns the argument space and could overwrite it, e.g.
|
||||
* tailcall optimization. So, to be absolutely safe
|
||||
* we also save and restore enough stack bytes to cover
|
||||
* the argument area.
|
||||
*/
|
||||
memcpy(kcb->jprobes_stack, (kprobe_opcode_t *) addr,
|
||||
MIN_STACK_SIZE(addr));
|
||||
|
||||
regs->pc = (unsigned long)(jp->entry);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void __kprobes jprobe_return(void)
|
||||
{
|
||||
asm volatile ("trapa #0x3a\n\t" "jprobe_return_end:\n\t" "nop\n\t");
|
||||
}
|
||||
|
||||
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
unsigned long stack_addr = kcb->jprobe_saved_r15;
|
||||
u8 *addr = (u8 *)regs->pc;
|
||||
|
||||
if ((addr >= (u8 *)jprobe_return) &&
|
||||
(addr <= (u8 *)jprobe_return_end)) {
|
||||
*regs = kcb->jprobe_saved_regs;
|
||||
|
||||
memcpy((kprobe_opcode_t *)stack_addr, kcb->jprobes_stack,
|
||||
MIN_STACK_SIZE(stack_addr));
|
||||
|
||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct kprobe trampoline_p = {
|
||||
.addr = (kprobe_opcode_t *)&kretprobe_trampoline,
|
||||
.pre_handler = trampoline_probe_handler
|
||||
|
@ -44,7 +44,6 @@ struct kprobe_ctlblk {
|
||||
unsigned long kprobe_status;
|
||||
unsigned long kprobe_orig_tnpc;
|
||||
unsigned long kprobe_orig_tstate_pil;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
struct prev_kprobe prev_kprobe;
|
||||
};
|
||||
|
||||
|
@ -147,18 +147,12 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
kcb->kprobe_status = KPROBE_REENTER;
|
||||
prepare_singlestep(p, regs, kcb);
|
||||
return 1;
|
||||
} else {
|
||||
if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) {
|
||||
} else if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) {
|
||||
/* The breakpoint instruction was removed by
|
||||
* another cpu right after we hit, no further
|
||||
* handling of this interrupt is appropriate
|
||||
*/
|
||||
ret = 1;
|
||||
goto no_kprobe;
|
||||
}
|
||||
p = __this_cpu_read(current_kprobe);
|
||||
if (p->break_handler && p->break_handler(p, regs))
|
||||
goto ss_probe;
|
||||
ret = 1;
|
||||
}
|
||||
goto no_kprobe;
|
||||
}
|
||||
@ -181,10 +175,12 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
|
||||
set_current_kprobe(p, regs, kcb);
|
||||
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
if (p->pre_handler && p->pre_handler(p, regs))
|
||||
if (p->pre_handler && p->pre_handler(p, regs)) {
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ss_probe:
|
||||
prepare_singlestep(p, regs, kcb);
|
||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||
return 1;
|
||||
@ -441,53 +437,6 @@ out:
|
||||
exception_exit(prev_state);
|
||||
}
|
||||
|
||||
/* Jprobes support. */
|
||||
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs));
|
||||
|
||||
regs->tpc = (unsigned long) jp->entry;
|
||||
regs->tnpc = ((unsigned long) jp->entry) + 0x4UL;
|
||||
regs->tstate |= TSTATE_PIL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void __kprobes jprobe_return(void)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
register unsigned long orig_fp asm("g1");
|
||||
|
||||
orig_fp = kcb->jprobe_saved_regs.u_regs[UREG_FP];
|
||||
__asm__ __volatile__("\n"
|
||||
"1: cmp %%sp, %0\n\t"
|
||||
"blu,a,pt %%xcc, 1b\n\t"
|
||||
" restore\n\t"
|
||||
".globl jprobe_return_trap_instruction\n"
|
||||
"jprobe_return_trap_instruction:\n\t"
|
||||
"ta 0x70"
|
||||
: /* no outputs */
|
||||
: "r" (orig_fp));
|
||||
}
|
||||
|
||||
extern void jprobe_return_trap_instruction(void);
|
||||
|
||||
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
u32 *addr = (u32 *) regs->tpc;
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
if (addr == (u32 *) jprobe_return_trap_instruction) {
|
||||
memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs));
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The value stored in the return address register is actually 2
|
||||
* instructions before where the callee will return to.
|
||||
* Sequences usually look something like this
|
||||
@ -562,9 +511,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
|
||||
regs->tpc = orig_ret_address;
|
||||
regs->tnpc = orig_ret_address + 4;
|
||||
|
||||
reset_current_kprobe();
|
||||
kretprobe_hash_unlock(current, &flags);
|
||||
preempt_enable_no_resched();
|
||||
|
||||
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
|
||||
hlist_del(&ri->hlist);
|
||||
|
@ -2041,15 +2041,15 @@ static void intel_pmu_disable_event(struct perf_event *event)
|
||||
cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx);
|
||||
cpuc->intel_cp_status &= ~(1ull << hwc->idx);
|
||||
|
||||
if (unlikely(event->attr.precise_ip))
|
||||
intel_pmu_pebs_disable(event);
|
||||
|
||||
if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
|
||||
intel_pmu_disable_fixed(hwc);
|
||||
return;
|
||||
}
|
||||
|
||||
x86_pmu_disable_event(event);
|
||||
|
||||
if (unlikely(event->attr.precise_ip))
|
||||
intel_pmu_pebs_disable(event);
|
||||
}
|
||||
|
||||
static void intel_pmu_del_event(struct perf_event *event)
|
||||
@ -2068,17 +2068,19 @@ static void intel_pmu_read_event(struct perf_event *event)
|
||||
x86_perf_event_update(event);
|
||||
}
|
||||
|
||||
static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
|
||||
static void intel_pmu_enable_fixed(struct perf_event *event)
|
||||
{
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
|
||||
u64 ctrl_val, bits, mask;
|
||||
u64 ctrl_val, mask, bits = 0;
|
||||
|
||||
/*
|
||||
* Enable IRQ generation (0x8),
|
||||
* Enable IRQ generation (0x8), if not PEBS,
|
||||
* and enable ring-3 counting (0x2) and ring-0 counting (0x1)
|
||||
* if requested:
|
||||
*/
|
||||
bits = 0x8ULL;
|
||||
if (!event->attr.precise_ip)
|
||||
bits |= 0x8;
|
||||
if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
|
||||
bits |= 0x2;
|
||||
if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
|
||||
@ -2120,14 +2122,14 @@ static void intel_pmu_enable_event(struct perf_event *event)
|
||||
if (unlikely(event_is_checkpointed(event)))
|
||||
cpuc->intel_cp_status |= (1ull << hwc->idx);
|
||||
|
||||
if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
|
||||
intel_pmu_enable_fixed(hwc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlikely(event->attr.precise_ip))
|
||||
intel_pmu_pebs_enable(event);
|
||||
|
||||
if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
|
||||
intel_pmu_enable_fixed(event);
|
||||
return;
|
||||
}
|
||||
|
||||
__x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
|
||||
}
|
||||
|
||||
@ -2280,7 +2282,10 @@ again:
|
||||
* counters from the GLOBAL_STATUS mask and we always process PEBS
|
||||
* events via drain_pebs().
|
||||
*/
|
||||
status &= ~(cpuc->pebs_enabled & PEBS_COUNTER_MASK);
|
||||
if (x86_pmu.flags & PMU_FL_PEBS_ALL)
|
||||
status &= ~cpuc->pebs_enabled;
|
||||
else
|
||||
status &= ~(cpuc->pebs_enabled & PEBS_COUNTER_MASK);
|
||||
|
||||
/*
|
||||
* PEBS overflow sets bit 62 in the global status register
|
||||
@ -4072,7 +4077,6 @@ __init int intel_pmu_init(void)
|
||||
intel_pmu_lbr_init_skl();
|
||||
|
||||
x86_pmu.event_constraints = intel_slm_event_constraints;
|
||||
x86_pmu.pebs_constraints = intel_glp_pebs_event_constraints;
|
||||
x86_pmu.extra_regs = intel_glm_extra_regs;
|
||||
/*
|
||||
* It's recommended to use CPU_CLK_UNHALTED.CORE_P + NPEBS
|
||||
@ -4082,6 +4086,7 @@ __init int intel_pmu_init(void)
|
||||
x86_pmu.pebs_prec_dist = true;
|
||||
x86_pmu.lbr_pt_coexist = true;
|
||||
x86_pmu.flags |= PMU_FL_HAS_RSP_1;
|
||||
x86_pmu.flags |= PMU_FL_PEBS_ALL;
|
||||
x86_pmu.get_event_constraints = glp_get_event_constraints;
|
||||
x86_pmu.cpu_events = glm_events_attrs;
|
||||
/* Goldmont Plus has 4-wide pipeline */
|
||||
|
@ -713,12 +713,6 @@ struct event_constraint intel_glm_pebs_event_constraints[] = {
|
||||
EVENT_CONSTRAINT_END
|
||||
};
|
||||
|
||||
struct event_constraint intel_glp_pebs_event_constraints[] = {
|
||||
/* Allow all events as PEBS with no flags */
|
||||
INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
|
||||
EVENT_CONSTRAINT_END
|
||||
};
|
||||
|
||||
struct event_constraint intel_nehalem_pebs_event_constraints[] = {
|
||||
INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */
|
||||
INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
|
||||
@ -871,6 +865,13 @@ struct event_constraint *intel_pebs_constraints(struct perf_event *event)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Extended PEBS support
|
||||
* Makes the PEBS code search the normal constraints.
|
||||
*/
|
||||
if (x86_pmu.flags & PMU_FL_PEBS_ALL)
|
||||
return NULL;
|
||||
|
||||
return &emptyconstraint;
|
||||
}
|
||||
|
||||
@ -896,10 +897,16 @@ static inline void pebs_update_threshold(struct cpu_hw_events *cpuc)
|
||||
{
|
||||
struct debug_store *ds = cpuc->ds;
|
||||
u64 threshold;
|
||||
int reserved;
|
||||
|
||||
if (x86_pmu.flags & PMU_FL_PEBS_ALL)
|
||||
reserved = x86_pmu.max_pebs_events + x86_pmu.num_counters_fixed;
|
||||
else
|
||||
reserved = x86_pmu.max_pebs_events;
|
||||
|
||||
if (cpuc->n_pebs == cpuc->n_large_pebs) {
|
||||
threshold = ds->pebs_absolute_maximum -
|
||||
x86_pmu.max_pebs_events * x86_pmu.pebs_record_size;
|
||||
reserved * x86_pmu.pebs_record_size;
|
||||
} else {
|
||||
threshold = ds->pebs_buffer_base + x86_pmu.pebs_record_size;
|
||||
}
|
||||
@ -963,7 +970,11 @@ void intel_pmu_pebs_enable(struct perf_event *event)
|
||||
* This must be done in pmu::start(), because PERF_EVENT_IOC_PERIOD.
|
||||
*/
|
||||
if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) {
|
||||
ds->pebs_event_reset[hwc->idx] =
|
||||
unsigned int idx = hwc->idx;
|
||||
|
||||
if (idx >= INTEL_PMC_IDX_FIXED)
|
||||
idx = MAX_PEBS_EVENTS + (idx - INTEL_PMC_IDX_FIXED);
|
||||
ds->pebs_event_reset[idx] =
|
||||
(u64)(-hwc->sample_period) & x86_pmu.cntval_mask;
|
||||
} else {
|
||||
ds->pebs_event_reset[hwc->idx] = 0;
|
||||
@ -1481,9 +1492,10 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
|
||||
struct debug_store *ds = cpuc->ds;
|
||||
struct perf_event *event;
|
||||
void *base, *at, *top;
|
||||
short counts[MAX_PEBS_EVENTS] = {};
|
||||
short error[MAX_PEBS_EVENTS] = {};
|
||||
int bit, i;
|
||||
short counts[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
|
||||
short error[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
|
||||
int bit, i, size;
|
||||
u64 mask;
|
||||
|
||||
if (!x86_pmu.pebs_active)
|
||||
return;
|
||||
@ -1493,6 +1505,13 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
|
||||
|
||||
ds->pebs_index = ds->pebs_buffer_base;
|
||||
|
||||
mask = (1ULL << x86_pmu.max_pebs_events) - 1;
|
||||
size = x86_pmu.max_pebs_events;
|
||||
if (x86_pmu.flags & PMU_FL_PEBS_ALL) {
|
||||
mask |= ((1ULL << x86_pmu.num_counters_fixed) - 1) << INTEL_PMC_IDX_FIXED;
|
||||
size = INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed;
|
||||
}
|
||||
|
||||
if (unlikely(base >= top)) {
|
||||
/*
|
||||
* The drain_pebs() could be called twice in a short period
|
||||
@ -1502,7 +1521,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
|
||||
* update the event->count for this case.
|
||||
*/
|
||||
for_each_set_bit(bit, (unsigned long *)&cpuc->pebs_enabled,
|
||||
x86_pmu.max_pebs_events) {
|
||||
size) {
|
||||
event = cpuc->events[bit];
|
||||
if (event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD)
|
||||
intel_pmu_save_and_restart_reload(event, 0);
|
||||
@ -1515,12 +1534,12 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
|
||||
u64 pebs_status;
|
||||
|
||||
pebs_status = p->status & cpuc->pebs_enabled;
|
||||
pebs_status &= (1ULL << x86_pmu.max_pebs_events) - 1;
|
||||
pebs_status &= mask;
|
||||
|
||||
/* PEBS v3 has more accurate status bits */
|
||||
if (x86_pmu.intel_cap.pebs_format >= 3) {
|
||||
for_each_set_bit(bit, (unsigned long *)&pebs_status,
|
||||
x86_pmu.max_pebs_events)
|
||||
size)
|
||||
counts[bit]++;
|
||||
|
||||
continue;
|
||||
@ -1568,7 +1587,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
|
||||
counts[bit]++;
|
||||
}
|
||||
|
||||
for (bit = 0; bit < x86_pmu.max_pebs_events; bit++) {
|
||||
for (bit = 0; bit < size; bit++) {
|
||||
if ((counts[bit] == 0) && (error[bit] == 0))
|
||||
continue;
|
||||
|
||||
|
@ -216,6 +216,8 @@ static void intel_pmu_lbr_reset_64(void)
|
||||
|
||||
void intel_pmu_lbr_reset(void)
|
||||
{
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
|
||||
if (!x86_pmu.lbr_nr)
|
||||
return;
|
||||
|
||||
@ -223,6 +225,9 @@ void intel_pmu_lbr_reset(void)
|
||||
intel_pmu_lbr_reset_32();
|
||||
else
|
||||
intel_pmu_lbr_reset_64();
|
||||
|
||||
cpuc->last_task_ctx = NULL;
|
||||
cpuc->last_log_id = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -334,6 +339,7 @@ static inline u64 rdlbr_to(unsigned int idx)
|
||||
|
||||
static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
|
||||
{
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
int i;
|
||||
unsigned lbr_idx, mask;
|
||||
u64 tos;
|
||||
@ -344,9 +350,21 @@ static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
mask = x86_pmu.lbr_nr - 1;
|
||||
tos = task_ctx->tos;
|
||||
for (i = 0; i < tos; i++) {
|
||||
/*
|
||||
* Does not restore the LBR registers, if
|
||||
* - No one else touched them, and
|
||||
* - Did not enter C6
|
||||
*/
|
||||
if ((task_ctx == cpuc->last_task_ctx) &&
|
||||
(task_ctx->log_id == cpuc->last_log_id) &&
|
||||
rdlbr_from(tos)) {
|
||||
task_ctx->lbr_stack_state = LBR_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
mask = x86_pmu.lbr_nr - 1;
|
||||
for (i = 0; i < task_ctx->valid_lbrs; i++) {
|
||||
lbr_idx = (tos - i) & mask;
|
||||
wrlbr_from(lbr_idx, task_ctx->lbr_from[i]);
|
||||
wrlbr_to (lbr_idx, task_ctx->lbr_to[i]);
|
||||
@ -354,14 +372,24 @@ static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
|
||||
if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
|
||||
wrmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
|
||||
}
|
||||
|
||||
for (; i < x86_pmu.lbr_nr; i++) {
|
||||
lbr_idx = (tos - i) & mask;
|
||||
wrlbr_from(lbr_idx, 0);
|
||||
wrlbr_to(lbr_idx, 0);
|
||||
if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
|
||||
wrmsrl(MSR_LBR_INFO_0 + lbr_idx, 0);
|
||||
}
|
||||
|
||||
wrmsrl(x86_pmu.lbr_tos, tos);
|
||||
task_ctx->lbr_stack_state = LBR_NONE;
|
||||
}
|
||||
|
||||
static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx)
|
||||
{
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
unsigned lbr_idx, mask;
|
||||
u64 tos;
|
||||
u64 tos, from;
|
||||
int i;
|
||||
|
||||
if (task_ctx->lbr_callstack_users == 0) {
|
||||
@ -371,15 +399,22 @@ static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx)
|
||||
|
||||
mask = x86_pmu.lbr_nr - 1;
|
||||
tos = intel_pmu_lbr_tos();
|
||||
for (i = 0; i < tos; i++) {
|
||||
for (i = 0; i < x86_pmu.lbr_nr; i++) {
|
||||
lbr_idx = (tos - i) & mask;
|
||||
task_ctx->lbr_from[i] = rdlbr_from(lbr_idx);
|
||||
from = rdlbr_from(lbr_idx);
|
||||
if (!from)
|
||||
break;
|
||||
task_ctx->lbr_from[i] = from;
|
||||
task_ctx->lbr_to[i] = rdlbr_to(lbr_idx);
|
||||
if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
|
||||
rdmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
|
||||
}
|
||||
task_ctx->valid_lbrs = i;
|
||||
task_ctx->tos = tos;
|
||||
task_ctx->lbr_stack_state = LBR_VALID;
|
||||
|
||||
cpuc->last_task_ctx = task_ctx;
|
||||
cpuc->last_log_id = ++task_ctx->log_id;
|
||||
}
|
||||
|
||||
void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in)
|
||||
@ -531,7 +566,7 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
|
||||
*/
|
||||
static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
|
||||
{
|
||||
bool need_info = false;
|
||||
bool need_info = false, call_stack = false;
|
||||
unsigned long mask = x86_pmu.lbr_nr - 1;
|
||||
int lbr_format = x86_pmu.intel_cap.lbr_format;
|
||||
u64 tos = intel_pmu_lbr_tos();
|
||||
@ -542,7 +577,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
|
||||
if (cpuc->lbr_sel) {
|
||||
need_info = !(cpuc->lbr_sel->config & LBR_NO_INFO);
|
||||
if (cpuc->lbr_sel->config & LBR_CALL_STACK)
|
||||
num = tos;
|
||||
call_stack = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
@ -555,6 +590,13 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
|
||||
from = rdlbr_from(lbr_idx);
|
||||
to = rdlbr_to(lbr_idx);
|
||||
|
||||
/*
|
||||
* Read LBR call stack entries
|
||||
* until invalid entry (0s) is detected.
|
||||
*/
|
||||
if (call_stack && !from)
|
||||
break;
|
||||
|
||||
if (lbr_format == LBR_FORMAT_INFO && need_info) {
|
||||
u64 info;
|
||||
|
||||
|
@ -163,6 +163,7 @@ struct intel_excl_cntrs {
|
||||
unsigned core_id; /* per-core: core id */
|
||||
};
|
||||
|
||||
struct x86_perf_task_context;
|
||||
#define MAX_LBR_ENTRIES 32
|
||||
|
||||
enum {
|
||||
@ -214,6 +215,8 @@ struct cpu_hw_events {
|
||||
struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES];
|
||||
struct er_account *lbr_sel;
|
||||
u64 br_sel;
|
||||
struct x86_perf_task_context *last_task_ctx;
|
||||
int last_log_id;
|
||||
|
||||
/*
|
||||
* Intel host/guest exclude bits
|
||||
@ -648,8 +651,10 @@ struct x86_perf_task_context {
|
||||
u64 lbr_to[MAX_LBR_ENTRIES];
|
||||
u64 lbr_info[MAX_LBR_ENTRIES];
|
||||
int tos;
|
||||
int valid_lbrs;
|
||||
int lbr_callstack_users;
|
||||
int lbr_stack_state;
|
||||
int log_id;
|
||||
};
|
||||
|
||||
#define x86_add_quirk(func_) \
|
||||
@ -668,6 +673,7 @@ do { \
|
||||
#define PMU_FL_HAS_RSP_1 0x2 /* has 2 equivalent offcore_rsp regs */
|
||||
#define PMU_FL_EXCL_CNTRS 0x4 /* has exclusive counter requirements */
|
||||
#define PMU_FL_EXCL_ENABLED 0x8 /* exclusive counter active */
|
||||
#define PMU_FL_PEBS_ALL 0x10 /* all events are valid PEBS events */
|
||||
|
||||
#define EVENT_VAR(_id) event_attr_##_id
|
||||
#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
|
||||
|
@ -49,11 +49,14 @@ static inline int hw_breakpoint_slots(int type)
|
||||
return HBP_NUM;
|
||||
}
|
||||
|
||||
struct perf_event_attr;
|
||||
struct perf_event;
|
||||
struct pmu;
|
||||
|
||||
extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
|
||||
extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
|
||||
extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
|
||||
extern int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw);
|
||||
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
|
||||
unsigned long val, void *data);
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
/* The maximal number of PEBS events: */
|
||||
#define MAX_PEBS_EVENTS 8
|
||||
#define MAX_FIXED_PEBS_EVENTS 3
|
||||
|
||||
/*
|
||||
* A debug store configuration.
|
||||
@ -23,7 +24,7 @@ struct debug_store {
|
||||
u64 pebs_index;
|
||||
u64 pebs_absolute_maximum;
|
||||
u64 pebs_interrupt_threshold;
|
||||
u64 pebs_event_reset[MAX_PEBS_EVENTS];
|
||||
u64 pebs_event_reset[MAX_PEBS_EVENTS + MAX_FIXED_PEBS_EVENTS];
|
||||
} __aligned(PAGE_SIZE);
|
||||
|
||||
DECLARE_PER_CPU_PAGE_ALIGNED(struct debug_store, cpu_debug_store);
|
||||
|
@ -78,7 +78,7 @@ struct arch_specific_insn {
|
||||
* boostable = true: This instruction has been boosted: we have
|
||||
* added a relative jump after the instruction copy in insn,
|
||||
* so no single-step and fixup are needed (unless there's
|
||||
* a post_handler or break_handler).
|
||||
* a post_handler).
|
||||
*/
|
||||
bool boostable;
|
||||
bool if_modifier;
|
||||
@ -111,9 +111,6 @@ struct kprobe_ctlblk {
|
||||
unsigned long kprobe_status;
|
||||
unsigned long kprobe_old_flags;
|
||||
unsigned long kprobe_saved_flags;
|
||||
unsigned long *jprobe_saved_sp;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
|
||||
struct prev_kprobe prev_kprobe;
|
||||
};
|
||||
|
||||
|
@ -169,28 +169,29 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
|
||||
set_dr_addr_mask(0, i);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for virtual address in kernel space.
|
||||
*/
|
||||
int arch_check_bp_in_kernelspace(struct perf_event *bp)
|
||||
static int arch_bp_generic_len(int x86_len)
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned long va;
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
va = info->address;
|
||||
len = bp->attr.bp_len;
|
||||
|
||||
/*
|
||||
* We don't need to worry about va + len - 1 overflowing:
|
||||
* we already require that va is aligned to a multiple of len.
|
||||
*/
|
||||
return (va >= TASK_SIZE_MAX) || ((va + len - 1) >= TASK_SIZE_MAX);
|
||||
switch (x86_len) {
|
||||
case X86_BREAKPOINT_LEN_1:
|
||||
return HW_BREAKPOINT_LEN_1;
|
||||
case X86_BREAKPOINT_LEN_2:
|
||||
return HW_BREAKPOINT_LEN_2;
|
||||
case X86_BREAKPOINT_LEN_4:
|
||||
return HW_BREAKPOINT_LEN_4;
|
||||
#ifdef CONFIG_X86_64
|
||||
case X86_BREAKPOINT_LEN_8:
|
||||
return HW_BREAKPOINT_LEN_8;
|
||||
#endif
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int arch_bp_generic_fields(int x86_len, int x86_type,
|
||||
int *gen_len, int *gen_type)
|
||||
{
|
||||
int len;
|
||||
|
||||
/* Type */
|
||||
switch (x86_type) {
|
||||
case X86_BREAKPOINT_EXECUTE:
|
||||
@ -211,42 +212,47 @@ int arch_bp_generic_fields(int x86_len, int x86_type,
|
||||
}
|
||||
|
||||
/* Len */
|
||||
switch (x86_len) {
|
||||
case X86_BREAKPOINT_LEN_1:
|
||||
*gen_len = HW_BREAKPOINT_LEN_1;
|
||||
break;
|
||||
case X86_BREAKPOINT_LEN_2:
|
||||
*gen_len = HW_BREAKPOINT_LEN_2;
|
||||
break;
|
||||
case X86_BREAKPOINT_LEN_4:
|
||||
*gen_len = HW_BREAKPOINT_LEN_4;
|
||||
break;
|
||||
#ifdef CONFIG_X86_64
|
||||
case X86_BREAKPOINT_LEN_8:
|
||||
*gen_len = HW_BREAKPOINT_LEN_8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
len = arch_bp_generic_len(x86_len);
|
||||
if (len < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
*gen_len = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int arch_build_bp_info(struct perf_event *bp)
|
||||
/*
|
||||
* Check for virtual address in kernel space.
|
||||
*/
|
||||
int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
unsigned long va;
|
||||
int len;
|
||||
|
||||
info->address = bp->attr.bp_addr;
|
||||
va = hw->address;
|
||||
len = arch_bp_generic_len(hw->len);
|
||||
WARN_ON_ONCE(len < 0);
|
||||
|
||||
/*
|
||||
* We don't need to worry about va + len - 1 overflowing:
|
||||
* we already require that va is aligned to a multiple of len.
|
||||
*/
|
||||
return (va >= TASK_SIZE_MAX) || ((va + len - 1) >= TASK_SIZE_MAX);
|
||||
}
|
||||
|
||||
static int arch_build_bp_info(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
hw->address = attr->bp_addr;
|
||||
hw->mask = 0;
|
||||
|
||||
/* Type */
|
||||
switch (bp->attr.bp_type) {
|
||||
switch (attr->bp_type) {
|
||||
case HW_BREAKPOINT_W:
|
||||
info->type = X86_BREAKPOINT_WRITE;
|
||||
hw->type = X86_BREAKPOINT_WRITE;
|
||||
break;
|
||||
case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
|
||||
info->type = X86_BREAKPOINT_RW;
|
||||
hw->type = X86_BREAKPOINT_RW;
|
||||
break;
|
||||
case HW_BREAKPOINT_X:
|
||||
/*
|
||||
@ -254,23 +260,23 @@ static int arch_build_bp_info(struct perf_event *bp)
|
||||
* acceptable for kprobes. On non-kprobes kernels, we don't
|
||||
* allow kernel breakpoints at all.
|
||||
*/
|
||||
if (bp->attr.bp_addr >= TASK_SIZE_MAX) {
|
||||
if (attr->bp_addr >= TASK_SIZE_MAX) {
|
||||
#ifdef CONFIG_KPROBES
|
||||
if (within_kprobe_blacklist(bp->attr.bp_addr))
|
||||
if (within_kprobe_blacklist(attr->bp_addr))
|
||||
return -EINVAL;
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
info->type = X86_BREAKPOINT_EXECUTE;
|
||||
hw->type = X86_BREAKPOINT_EXECUTE;
|
||||
/*
|
||||
* x86 inst breakpoints need to have a specific undefined len.
|
||||
* But we still need to check userspace is not trying to setup
|
||||
* an unsupported length, to get a range breakpoint for example.
|
||||
*/
|
||||
if (bp->attr.bp_len == sizeof(long)) {
|
||||
info->len = X86_BREAKPOINT_LEN_X;
|
||||
if (attr->bp_len == sizeof(long)) {
|
||||
hw->len = X86_BREAKPOINT_LEN_X;
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
@ -278,28 +284,26 @@ static int arch_build_bp_info(struct perf_event *bp)
|
||||
}
|
||||
|
||||
/* Len */
|
||||
info->mask = 0;
|
||||
|
||||
switch (bp->attr.bp_len) {
|
||||
switch (attr->bp_len) {
|
||||
case HW_BREAKPOINT_LEN_1:
|
||||
info->len = X86_BREAKPOINT_LEN_1;
|
||||
hw->len = X86_BREAKPOINT_LEN_1;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_2:
|
||||
info->len = X86_BREAKPOINT_LEN_2;
|
||||
hw->len = X86_BREAKPOINT_LEN_2;
|
||||
break;
|
||||
case HW_BREAKPOINT_LEN_4:
|
||||
info->len = X86_BREAKPOINT_LEN_4;
|
||||
hw->len = X86_BREAKPOINT_LEN_4;
|
||||
break;
|
||||
#ifdef CONFIG_X86_64
|
||||
case HW_BREAKPOINT_LEN_8:
|
||||
info->len = X86_BREAKPOINT_LEN_8;
|
||||
hw->len = X86_BREAKPOINT_LEN_8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* AMD range breakpoint */
|
||||
if (!is_power_of_2(bp->attr.bp_len))
|
||||
if (!is_power_of_2(attr->bp_len))
|
||||
return -EINVAL;
|
||||
if (bp->attr.bp_addr & (bp->attr.bp_len - 1))
|
||||
if (attr->bp_addr & (attr->bp_len - 1))
|
||||
return -EINVAL;
|
||||
|
||||
if (!boot_cpu_has(X86_FEATURE_BPEXT))
|
||||
@ -312,8 +316,8 @@ static int arch_build_bp_info(struct perf_event *bp)
|
||||
* breakpoints, then we'll have to check for kprobe-blacklisted
|
||||
* addresses anywhere in the range.
|
||||
*/
|
||||
info->mask = bp->attr.bp_len - 1;
|
||||
info->len = X86_BREAKPOINT_LEN_1;
|
||||
hw->mask = attr->bp_len - 1;
|
||||
hw->len = X86_BREAKPOINT_LEN_1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -322,22 +326,23 @@ static int arch_build_bp_info(struct perf_event *bp)
|
||||
/*
|
||||
* Validate the arch-specific HW Breakpoint register settings
|
||||
*/
|
||||
int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
unsigned int align;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = arch_build_bp_info(bp);
|
||||
ret = arch_build_bp_info(bp, attr, hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (info->len) {
|
||||
switch (hw->len) {
|
||||
case X86_BREAKPOINT_LEN_1:
|
||||
align = 0;
|
||||
if (info->mask)
|
||||
align = info->mask;
|
||||
if (hw->mask)
|
||||
align = hw->mask;
|
||||
break;
|
||||
case X86_BREAKPOINT_LEN_2:
|
||||
align = 1;
|
||||
@ -358,7 +363,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
* Check that the low-order bits of the address are appropriate
|
||||
* for the alignment implied by len.
|
||||
*/
|
||||
if (info->address & align)
|
||||
if (hw->address & align)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
@ -105,14 +105,4 @@ static inline unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsig
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KPROBES_ON_FTRACE
|
||||
extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
|
||||
struct kprobe_ctlblk *kcb);
|
||||
#else
|
||||
static inline int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
|
||||
struct kprobe_ctlblk *kcb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -66,8 +66,6 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void jprobe_return_end(void);
|
||||
|
||||
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
|
||||
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
|
||||
|
||||
@ -395,8 +393,6 @@ int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn)
|
||||
- (u8 *) real;
|
||||
if ((s64) (s32) newdisp != newdisp) {
|
||||
pr_err("Kprobes error: new displacement does not fit into s32 (%llx)\n", newdisp);
|
||||
pr_err("\tSrc: %p, Dest: %p, old disp: %x\n",
|
||||
src, real, insn->displacement.value);
|
||||
return 0;
|
||||
}
|
||||
disp = (u8 *) dest + insn_offset_displacement(insn);
|
||||
@ -596,7 +592,6 @@ static void setup_singlestep(struct kprobe *p, struct pt_regs *regs,
|
||||
* stepping.
|
||||
*/
|
||||
regs->ip = (unsigned long)p->ainsn.insn;
|
||||
preempt_enable_no_resched();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -640,8 +635,7 @@ static int reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
|
||||
* Raise a BUG or we'll continue in an endless reentering loop
|
||||
* and eventually a stack overflow.
|
||||
*/
|
||||
printk(KERN_WARNING "Unrecoverable kprobe detected at %p.\n",
|
||||
p->addr);
|
||||
pr_err("Unrecoverable kprobe detected.\n");
|
||||
dump_kprobe(p);
|
||||
BUG();
|
||||
default:
|
||||
@ -669,12 +663,10 @@ int kprobe_int3_handler(struct pt_regs *regs)
|
||||
|
||||
addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
|
||||
/*
|
||||
* We don't want to be preempted for the entire
|
||||
* duration of kprobe processing. We conditionally
|
||||
* re-enable preemption at the end of this function,
|
||||
* and also in reenter_kprobe() and setup_singlestep().
|
||||
* We don't want to be preempted for the entire duration of kprobe
|
||||
* processing. Since int3 and debug trap disables irqs and we clear
|
||||
* IF while singlestepping, it must be no preemptible.
|
||||
*/
|
||||
preempt_disable();
|
||||
|
||||
kcb = get_kprobe_ctlblk();
|
||||
p = get_kprobe(addr);
|
||||
@ -690,13 +682,14 @@ int kprobe_int3_handler(struct pt_regs *regs)
|
||||
/*
|
||||
* If we have no pre-handler or it returned 0, we
|
||||
* continue with normal processing. If we have a
|
||||
* pre-handler and it returned non-zero, it prepped
|
||||
* for calling the break_handler below on re-entry
|
||||
* for jprobe processing, so get out doing nothing
|
||||
* more here.
|
||||
* pre-handler and it returned non-zero, that means
|
||||
* user handler setup registers to exit to another
|
||||
* instruction, we must skip the single stepping.
|
||||
*/
|
||||
if (!p->pre_handler || !p->pre_handler(p, regs))
|
||||
setup_singlestep(p, regs, kcb, 0);
|
||||
else
|
||||
reset_current_kprobe();
|
||||
return 1;
|
||||
}
|
||||
} else if (*addr != BREAKPOINT_INSTRUCTION) {
|
||||
@ -710,18 +703,9 @@ int kprobe_int3_handler(struct pt_regs *regs)
|
||||
* the original instruction.
|
||||
*/
|
||||
regs->ip = (unsigned long)addr;
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
} else if (kprobe_running()) {
|
||||
p = __this_cpu_read(current_kprobe);
|
||||
if (p->break_handler && p->break_handler(p, regs)) {
|
||||
if (!skip_singlestep(p, regs, kcb))
|
||||
setup_singlestep(p, regs, kcb, 0);
|
||||
return 1;
|
||||
}
|
||||
} /* else: not a kprobe fault; let the kernel handle it */
|
||||
|
||||
preempt_enable_no_resched();
|
||||
return 0;
|
||||
}
|
||||
NOKPROBE_SYMBOL(kprobe_int3_handler);
|
||||
@ -972,8 +956,6 @@ int kprobe_debug_handler(struct pt_regs *regs)
|
||||
}
|
||||
reset_current_kprobe();
|
||||
out:
|
||||
preempt_enable_no_resched();
|
||||
|
||||
/*
|
||||
* if somebody else is singlestepping across a probe point, flags
|
||||
* will have TF set, in which case, continue the remaining processing
|
||||
@ -1020,7 +1002,6 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
||||
restore_previous_kprobe(kcb);
|
||||
else
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
} else if (kcb->kprobe_status == KPROBE_HIT_ACTIVE ||
|
||||
kcb->kprobe_status == KPROBE_HIT_SSDONE) {
|
||||
/*
|
||||
@ -1083,93 +1064,6 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
|
||||
}
|
||||
NOKPROBE_SYMBOL(kprobe_exceptions_notify);
|
||||
|
||||
int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
unsigned long addr;
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
kcb->jprobe_saved_regs = *regs;
|
||||
kcb->jprobe_saved_sp = stack_addr(regs);
|
||||
addr = (unsigned long)(kcb->jprobe_saved_sp);
|
||||
|
||||
/*
|
||||
* As Linus pointed out, gcc assumes that the callee
|
||||
* owns the argument space and could overwrite it, e.g.
|
||||
* tailcall optimization. So, to be absolutely safe
|
||||
* we also save and restore enough stack bytes to cover
|
||||
* the argument area.
|
||||
* Use __memcpy() to avoid KASAN stack out-of-bounds reports as we copy
|
||||
* raw stack chunk with redzones:
|
||||
*/
|
||||
__memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr, MIN_STACK_SIZE(addr));
|
||||
regs->ip = (unsigned long)(jp->entry);
|
||||
|
||||
/*
|
||||
* jprobes use jprobe_return() which skips the normal return
|
||||
* path of the function, and this messes up the accounting of the
|
||||
* function graph tracer to get messed up.
|
||||
*
|
||||
* Pause function graph tracing while performing the jprobe function.
|
||||
*/
|
||||
pause_graph_tracing();
|
||||
return 1;
|
||||
}
|
||||
NOKPROBE_SYMBOL(setjmp_pre_handler);
|
||||
|
||||
void jprobe_return(void)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
/* Unpoison stack redzones in the frames we are going to jump over. */
|
||||
kasan_unpoison_stack_above_sp_to(kcb->jprobe_saved_sp);
|
||||
|
||||
asm volatile (
|
||||
#ifdef CONFIG_X86_64
|
||||
" xchg %%rbx,%%rsp \n"
|
||||
#else
|
||||
" xchgl %%ebx,%%esp \n"
|
||||
#endif
|
||||
" int3 \n"
|
||||
" .globl jprobe_return_end\n"
|
||||
" jprobe_return_end: \n"
|
||||
" nop \n"::"b"
|
||||
(kcb->jprobe_saved_sp):"memory");
|
||||
}
|
||||
NOKPROBE_SYMBOL(jprobe_return);
|
||||
NOKPROBE_SYMBOL(jprobe_return_end);
|
||||
|
||||
int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
u8 *addr = (u8 *) (regs->ip - 1);
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
void *saved_sp = kcb->jprobe_saved_sp;
|
||||
|
||||
if ((addr > (u8 *) jprobe_return) &&
|
||||
(addr < (u8 *) jprobe_return_end)) {
|
||||
if (stack_addr(regs) != saved_sp) {
|
||||
struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
|
||||
printk(KERN_ERR
|
||||
"current sp %p does not match saved sp %p\n",
|
||||
stack_addr(regs), saved_sp);
|
||||
printk(KERN_ERR "Saved registers for jprobe %p\n", jp);
|
||||
show_regs(saved_regs);
|
||||
printk(KERN_ERR "Current registers\n");
|
||||
show_regs(regs);
|
||||
BUG();
|
||||
}
|
||||
/* It's OK to start function graph tracing again */
|
||||
unpause_graph_tracing();
|
||||
*regs = kcb->jprobe_saved_regs;
|
||||
__memcpy(saved_sp, kcb->jprobes_stack, MIN_STACK_SIZE(saved_sp));
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
NOKPROBE_SYMBOL(longjmp_break_handler);
|
||||
|
||||
bool arch_within_kprobe_blacklist(unsigned long addr)
|
||||
{
|
||||
bool is_in_entry_trampoline_section = false;
|
||||
|
@ -25,36 +25,6 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static nokprobe_inline
|
||||
void __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
|
||||
struct kprobe_ctlblk *kcb, unsigned long orig_ip)
|
||||
{
|
||||
/*
|
||||
* Emulate singlestep (and also recover regs->ip)
|
||||
* as if there is a 5byte nop
|
||||
*/
|
||||
regs->ip = (unsigned long)p->addr + MCOUNT_INSN_SIZE;
|
||||
if (unlikely(p->post_handler)) {
|
||||
kcb->kprobe_status = KPROBE_HIT_SSDONE;
|
||||
p->post_handler(p, regs, 0);
|
||||
}
|
||||
__this_cpu_write(current_kprobe, NULL);
|
||||
if (orig_ip)
|
||||
regs->ip = orig_ip;
|
||||
}
|
||||
|
||||
int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
|
||||
struct kprobe_ctlblk *kcb)
|
||||
{
|
||||
if (kprobe_ftrace(p)) {
|
||||
__skip_singlestep(p, regs, kcb, 0);
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
NOKPROBE_SYMBOL(skip_singlestep);
|
||||
|
||||
/* Ftrace callback handler for kprobes -- called under preepmt disabed */
|
||||
void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
|
||||
struct ftrace_ops *ops, struct pt_regs *regs)
|
||||
@ -75,18 +45,25 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
|
||||
/* Kprobe handler expects regs->ip = ip + 1 as breakpoint hit */
|
||||
regs->ip = ip + sizeof(kprobe_opcode_t);
|
||||
|
||||
/* To emulate trap based kprobes, preempt_disable here */
|
||||
preempt_disable();
|
||||
__this_cpu_write(current_kprobe, p);
|
||||
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
if (!p->pre_handler || !p->pre_handler(p, regs)) {
|
||||
__skip_singlestep(p, regs, kcb, orig_ip);
|
||||
preempt_enable_no_resched();
|
||||
/*
|
||||
* Emulate singlestep (and also recover regs->ip)
|
||||
* as if there is a 5byte nop
|
||||
*/
|
||||
regs->ip = (unsigned long)p->addr + MCOUNT_INSN_SIZE;
|
||||
if (unlikely(p->post_handler)) {
|
||||
kcb->kprobe_status = KPROBE_HIT_SSDONE;
|
||||
p->post_handler(p, regs, 0);
|
||||
}
|
||||
regs->ip = orig_ip;
|
||||
}
|
||||
/*
|
||||
* If pre_handler returns !0, it sets regs->ip and
|
||||
* resets current kprobe, and keep preempt count +1.
|
||||
* If pre_handler returns !0, it changes regs->ip. We have to
|
||||
* skip emulating post_handler.
|
||||
*/
|
||||
__this_cpu_write(current_kprobe, NULL);
|
||||
}
|
||||
}
|
||||
NOKPROBE_SYMBOL(kprobe_ftrace_handler);
|
||||
|
@ -491,7 +491,6 @@ int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter)
|
||||
regs->ip = (unsigned long)op->optinsn.insn + TMPL_END_IDX;
|
||||
if (!reenter)
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -30,13 +30,16 @@ struct arch_hw_breakpoint {
|
||||
u16 type;
|
||||
};
|
||||
|
||||
struct perf_event_attr;
|
||||
struct perf_event;
|
||||
struct pt_regs;
|
||||
struct task_struct;
|
||||
|
||||
int hw_breakpoint_slots(int type);
|
||||
int arch_check_bp_in_kernelspace(struct perf_event *bp);
|
||||
int arch_validate_hwbkpt_settings(struct perf_event *bp);
|
||||
int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
|
||||
int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw);
|
||||
int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
|
||||
unsigned long val, void *data);
|
||||
|
||||
|
@ -33,14 +33,13 @@ int hw_breakpoint_slots(int type)
|
||||
}
|
||||
}
|
||||
|
||||
int arch_check_bp_in_kernelspace(struct perf_event *bp)
|
||||
int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned long va;
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
va = info->address;
|
||||
len = bp->attr.bp_len;
|
||||
va = hw->address;
|
||||
len = hw->len;
|
||||
|
||||
return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
|
||||
}
|
||||
@ -48,50 +47,41 @@ int arch_check_bp_in_kernelspace(struct perf_event *bp)
|
||||
/*
|
||||
* Construct an arch_hw_breakpoint from a perf_event.
|
||||
*/
|
||||
static int arch_build_bp_info(struct perf_event *bp)
|
||||
int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
|
||||
|
||||
/* Type */
|
||||
switch (bp->attr.bp_type) {
|
||||
switch (attr->bp_type) {
|
||||
case HW_BREAKPOINT_X:
|
||||
info->type = XTENSA_BREAKPOINT_EXECUTE;
|
||||
hw->type = XTENSA_BREAKPOINT_EXECUTE;
|
||||
break;
|
||||
case HW_BREAKPOINT_R:
|
||||
info->type = XTENSA_BREAKPOINT_LOAD;
|
||||
hw->type = XTENSA_BREAKPOINT_LOAD;
|
||||
break;
|
||||
case HW_BREAKPOINT_W:
|
||||
info->type = XTENSA_BREAKPOINT_STORE;
|
||||
hw->type = XTENSA_BREAKPOINT_STORE;
|
||||
break;
|
||||
case HW_BREAKPOINT_RW:
|
||||
info->type = XTENSA_BREAKPOINT_LOAD | XTENSA_BREAKPOINT_STORE;
|
||||
hw->type = XTENSA_BREAKPOINT_LOAD | XTENSA_BREAKPOINT_STORE;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Len */
|
||||
info->len = bp->attr.bp_len;
|
||||
if (info->len < 1 || info->len > 64 || !is_power_of_2(info->len))
|
||||
hw->len = attr->bp_len;
|
||||
if (hw->len < 1 || hw->len > 64 || !is_power_of_2(hw->len))
|
||||
return -EINVAL;
|
||||
|
||||
/* Address */
|
||||
info->address = bp->attr.bp_addr;
|
||||
if (info->address & (info->len - 1))
|
||||
hw->address = attr->bp_addr;
|
||||
if (hw->address & (hw->len - 1))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Build the arch_hw_breakpoint. */
|
||||
ret = arch_build_bp_info(bp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
|
||||
unsigned long val, void *data)
|
||||
{
|
||||
|
@ -63,7 +63,6 @@ struct pt_regs;
|
||||
struct kretprobe;
|
||||
struct kretprobe_instance;
|
||||
typedef int (*kprobe_pre_handler_t) (struct kprobe *, struct pt_regs *);
|
||||
typedef int (*kprobe_break_handler_t) (struct kprobe *, struct pt_regs *);
|
||||
typedef void (*kprobe_post_handler_t) (struct kprobe *, struct pt_regs *,
|
||||
unsigned long flags);
|
||||
typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *,
|
||||
@ -101,12 +100,6 @@ struct kprobe {
|
||||
*/
|
||||
kprobe_fault_handler_t fault_handler;
|
||||
|
||||
/*
|
||||
* ... called if breakpoint trap occurs in probe handler.
|
||||
* Return 1 if it handled break, otherwise kernel will see it.
|
||||
*/
|
||||
kprobe_break_handler_t break_handler;
|
||||
|
||||
/* Saved opcode (which has been replaced with breakpoint) */
|
||||
kprobe_opcode_t opcode;
|
||||
|
||||
@ -154,24 +147,6 @@ static inline int kprobe_ftrace(struct kprobe *p)
|
||||
return p->flags & KPROBE_FLAG_FTRACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special probe type that uses setjmp-longjmp type tricks to resume
|
||||
* execution at a specified entry with a matching prototype corresponding
|
||||
* to the probed function - a trick to enable arguments to become
|
||||
* accessible seamlessly by probe handling logic.
|
||||
* Note:
|
||||
* Because of the way compilers allocate stack space for local variables
|
||||
* etc upfront, regardless of sub-scopes within a function, this mirroring
|
||||
* principle currently works only for probes placed on function entry points.
|
||||
*/
|
||||
struct jprobe {
|
||||
struct kprobe kp;
|
||||
void *entry; /* probe handling code to jump to */
|
||||
};
|
||||
|
||||
/* For backward compatibility with old code using JPROBE_ENTRY() */
|
||||
#define JPROBE_ENTRY(handler) (handler)
|
||||
|
||||
/*
|
||||
* Function-return probe -
|
||||
* Note:
|
||||
@ -389,9 +364,6 @@ int register_kprobe(struct kprobe *p);
|
||||
void unregister_kprobe(struct kprobe *p);
|
||||
int register_kprobes(struct kprobe **kps, int num);
|
||||
void unregister_kprobes(struct kprobe **kps, int num);
|
||||
int setjmp_pre_handler(struct kprobe *, struct pt_regs *);
|
||||
int longjmp_break_handler(struct kprobe *, struct pt_regs *);
|
||||
void jprobe_return(void);
|
||||
unsigned long arch_deref_entry_point(void *);
|
||||
|
||||
int register_kretprobe(struct kretprobe *rp);
|
||||
@ -439,9 +411,6 @@ static inline void unregister_kprobe(struct kprobe *p)
|
||||
static inline void unregister_kprobes(struct kprobe **kps, int num)
|
||||
{
|
||||
}
|
||||
static inline void jprobe_return(void)
|
||||
{
|
||||
}
|
||||
static inline int register_kretprobe(struct kretprobe *rp)
|
||||
{
|
||||
return -ENOSYS;
|
||||
@ -468,20 +437,6 @@ static inline int enable_kprobe(struct kprobe *kp)
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_KPROBES */
|
||||
static inline int register_jprobe(struct jprobe *p)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
static inline int register_jprobes(struct jprobe **jps, int num)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
static inline void unregister_jprobe(struct jprobe *p)
|
||||
{
|
||||
}
|
||||
static inline void unregister_jprobes(struct jprobe **jps, int num)
|
||||
{
|
||||
}
|
||||
static inline int disable_kretprobe(struct kretprobe *rp)
|
||||
{
|
||||
return disable_kprobe(&rp->kp);
|
||||
@ -490,14 +445,6 @@ static inline int enable_kretprobe(struct kretprobe *rp)
|
||||
{
|
||||
return enable_kprobe(&rp->kp);
|
||||
}
|
||||
static inline int disable_jprobe(struct jprobe *jp)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
static inline int enable_jprobe(struct jprobe *jp)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_KPROBES
|
||||
static inline bool is_kprobe_insn_slot(unsigned long addr)
|
||||
|
@ -490,7 +490,7 @@ struct perf_addr_filters_head {
|
||||
};
|
||||
|
||||
/**
|
||||
* enum perf_event_state - the states of a event
|
||||
* enum perf_event_state - the states of an event:
|
||||
*/
|
||||
enum perf_event_state {
|
||||
PERF_EVENT_STATE_DEAD = -4,
|
||||
|
@ -1656,7 +1656,7 @@ perf_event_groups_next(struct perf_event *event)
|
||||
typeof(*event), group_node))
|
||||
|
||||
/*
|
||||
* Add a event from the lists for its context.
|
||||
* Add an event from the lists for its context.
|
||||
* Must be called with ctx->mutex and ctx->lock held.
|
||||
*/
|
||||
static void
|
||||
@ -1844,7 +1844,7 @@ static void perf_group_attach(struct perf_event *event)
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a event from the lists for its context.
|
||||
* Remove an event from the lists for its context.
|
||||
* Must be called with ctx->mutex and ctx->lock held.
|
||||
*/
|
||||
static void
|
||||
@ -2148,7 +2148,7 @@ static void __perf_event_disable(struct perf_event *event,
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable a event.
|
||||
* Disable an event.
|
||||
*
|
||||
* If event->ctx is a cloned context, callers must make sure that
|
||||
* every task struct that event->ctx->task could possibly point to
|
||||
@ -2677,7 +2677,7 @@ static void __perf_event_enable(struct perf_event *event,
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable a event.
|
||||
* Enable an event.
|
||||
*
|
||||
* If event->ctx is a cloned context, callers must make sure that
|
||||
* every task struct that event->ctx->task could possibly point to
|
||||
@ -2755,7 +2755,7 @@ static int __perf_event_stop(void *info)
|
||||
* events will refuse to restart because of rb::aux_mmap_count==0,
|
||||
* see comments in perf_aux_output_begin().
|
||||
*
|
||||
* Since this is happening on a event-local CPU, no trace is lost
|
||||
* Since this is happening on an event-local CPU, no trace is lost
|
||||
* while restarting.
|
||||
*/
|
||||
if (sd->restart)
|
||||
@ -4827,7 +4827,7 @@ __perf_read(struct perf_event *event, char __user *buf, size_t count)
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Return end-of-file for a read on a event that is in
|
||||
* Return end-of-file for a read on an event that is in
|
||||
* error state (i.e. because it was pinned but it couldn't be
|
||||
* scheduled on to the CPU at some point).
|
||||
*/
|
||||
@ -5273,11 +5273,11 @@ unlock:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(perf_event_update_userpage);
|
||||
|
||||
static int perf_mmap_fault(struct vm_fault *vmf)
|
||||
static vm_fault_t perf_mmap_fault(struct vm_fault *vmf)
|
||||
{
|
||||
struct perf_event *event = vmf->vma->vm_file->private_data;
|
||||
struct ring_buffer *rb;
|
||||
int ret = VM_FAULT_SIGBUS;
|
||||
vm_fault_t ret = VM_FAULT_SIGBUS;
|
||||
|
||||
if (vmf->flags & FAULT_FLAG_MKWRITE) {
|
||||
if (vmf->pgoff == 0)
|
||||
@ -9904,7 +9904,7 @@ enabled:
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and initialize a event structure
|
||||
* Allocate and initialize an event structure
|
||||
*/
|
||||
static struct perf_event *
|
||||
perf_event_alloc(struct perf_event_attr *attr, int cpu,
|
||||
@ -11235,7 +11235,7 @@ const struct perf_event_attr *perf_event_attrs(struct perf_event *event)
|
||||
}
|
||||
|
||||
/*
|
||||
* Inherit a event from parent task to child task.
|
||||
* Inherit an event from parent task to child task.
|
||||
*
|
||||
* Returns:
|
||||
* - valid pointer on success
|
||||
|
@ -345,13 +345,13 @@ void release_bp_slot(struct perf_event *bp)
|
||||
mutex_unlock(&nr_bp_mutex);
|
||||
}
|
||||
|
||||
static int __modify_bp_slot(struct perf_event *bp, u64 old_type)
|
||||
static int __modify_bp_slot(struct perf_event *bp, u64 old_type, u64 new_type)
|
||||
{
|
||||
int err;
|
||||
|
||||
__release_bp_slot(bp, old_type);
|
||||
|
||||
err = __reserve_bp_slot(bp, bp->attr.bp_type);
|
||||
err = __reserve_bp_slot(bp, new_type);
|
||||
if (err) {
|
||||
/*
|
||||
* Reserve the old_type slot back in case
|
||||
@ -367,12 +367,12 @@ static int __modify_bp_slot(struct perf_event *bp, u64 old_type)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int modify_bp_slot(struct perf_event *bp, u64 old_type)
|
||||
static int modify_bp_slot(struct perf_event *bp, u64 old_type, u64 new_type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&nr_bp_mutex);
|
||||
ret = __modify_bp_slot(bp, old_type);
|
||||
ret = __modify_bp_slot(bp, old_type, new_type);
|
||||
mutex_unlock(&nr_bp_mutex);
|
||||
return ret;
|
||||
}
|
||||
@ -400,16 +400,18 @@ int dbg_release_bp_slot(struct perf_event *bp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int validate_hw_breakpoint(struct perf_event *bp)
|
||||
static int hw_breakpoint_parse(struct perf_event *bp,
|
||||
const struct perf_event_attr *attr,
|
||||
struct arch_hw_breakpoint *hw)
|
||||
{
|
||||
int ret;
|
||||
int err;
|
||||
|
||||
ret = arch_validate_hwbkpt_settings(bp);
|
||||
if (ret)
|
||||
return ret;
|
||||
err = hw_breakpoint_arch_parse(bp, attr, hw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (arch_check_bp_in_kernelspace(bp)) {
|
||||
if (bp->attr.exclude_kernel)
|
||||
if (arch_check_bp_in_kernelspace(hw)) {
|
||||
if (attr->exclude_kernel)
|
||||
return -EINVAL;
|
||||
/*
|
||||
* Don't let unprivileged users set a breakpoint in the trap
|
||||
@ -424,19 +426,22 @@ static int validate_hw_breakpoint(struct perf_event *bp)
|
||||
|
||||
int register_perf_hw_breakpoint(struct perf_event *bp)
|
||||
{
|
||||
int ret;
|
||||
struct arch_hw_breakpoint hw;
|
||||
int err;
|
||||
|
||||
ret = reserve_bp_slot(bp);
|
||||
if (ret)
|
||||
return ret;
|
||||
err = reserve_bp_slot(bp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ret = validate_hw_breakpoint(bp);
|
||||
|
||||
/* if arch_validate_hwbkpt_settings() fails then release bp slot */
|
||||
if (ret)
|
||||
err = hw_breakpoint_parse(bp, &bp->attr, &hw);
|
||||
if (err) {
|
||||
release_bp_slot(bp);
|
||||
return err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
bp->hw.info = hw;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -456,35 +461,44 @@ register_user_hw_breakpoint(struct perf_event_attr *attr,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
|
||||
|
||||
static void hw_breakpoint_copy_attr(struct perf_event_attr *to,
|
||||
struct perf_event_attr *from)
|
||||
{
|
||||
to->bp_addr = from->bp_addr;
|
||||
to->bp_type = from->bp_type;
|
||||
to->bp_len = from->bp_len;
|
||||
to->disabled = from->disabled;
|
||||
}
|
||||
|
||||
int
|
||||
modify_user_hw_breakpoint_check(struct perf_event *bp, struct perf_event_attr *attr,
|
||||
bool check)
|
||||
{
|
||||
u64 old_addr = bp->attr.bp_addr;
|
||||
u64 old_len = bp->attr.bp_len;
|
||||
int old_type = bp->attr.bp_type;
|
||||
bool modify = attr->bp_type != old_type;
|
||||
int err = 0;
|
||||
struct arch_hw_breakpoint hw;
|
||||
int err;
|
||||
|
||||
bp->attr.bp_addr = attr->bp_addr;
|
||||
bp->attr.bp_type = attr->bp_type;
|
||||
bp->attr.bp_len = attr->bp_len;
|
||||
|
||||
if (check && memcmp(&bp->attr, attr, sizeof(*attr)))
|
||||
return -EINVAL;
|
||||
|
||||
err = validate_hw_breakpoint(bp);
|
||||
if (!err && modify)
|
||||
err = modify_bp_slot(bp, old_type);
|
||||
|
||||
if (err) {
|
||||
bp->attr.bp_addr = old_addr;
|
||||
bp->attr.bp_type = old_type;
|
||||
bp->attr.bp_len = old_len;
|
||||
err = hw_breakpoint_parse(bp, attr, &hw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (check) {
|
||||
struct perf_event_attr old_attr;
|
||||
|
||||
old_attr = bp->attr;
|
||||
hw_breakpoint_copy_attr(&old_attr, attr);
|
||||
if (memcmp(&old_attr, attr, sizeof(*attr)))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bp->attr.disabled = attr->disabled;
|
||||
if (bp->attr.bp_type != attr->bp_type) {
|
||||
err = modify_bp_slot(bp, bp->attr.bp_type, attr->bp_type);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
hw_breakpoint_copy_attr(&bp->attr, attr);
|
||||
bp->hw.info = hw;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -918,7 +918,7 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *
|
||||
EXPORT_SYMBOL_GPL(uprobe_register);
|
||||
|
||||
/*
|
||||
* uprobe_apply - unregister a already registered probe.
|
||||
* uprobe_apply - unregister an already registered probe.
|
||||
* @inode: the file in which the probe has to be removed.
|
||||
* @offset: offset from the start of the file.
|
||||
* @uc: consumer which wants to add more or remove some breakpoints
|
||||
@ -947,7 +947,7 @@ int uprobe_apply(struct inode *inode, loff_t offset,
|
||||
}
|
||||
|
||||
/*
|
||||
* uprobe_unregister - unregister a already registered probe.
|
||||
* uprobe_unregister - unregister an already registered probe.
|
||||
* @inode: the file in which the probe has to be removed.
|
||||
* @offset: offset from the start of the file.
|
||||
* @uc: identify which probe if multiple probes are colocated.
|
||||
@ -1403,7 +1403,7 @@ static struct return_instance *free_ret_instance(struct return_instance *ri)
|
||||
|
||||
/*
|
||||
* Called with no locks held.
|
||||
* Called in context of a exiting or a exec-ing thread.
|
||||
* Called in context of an exiting or an exec-ing thread.
|
||||
*/
|
||||
void uprobe_free_utask(struct task_struct *t)
|
||||
{
|
||||
|
@ -184,9 +184,6 @@ static int fei_kprobe_handler(struct kprobe *kp, struct pt_regs *regs)
|
||||
if (should_fail(&fei_fault_attr, 1)) {
|
||||
regs_set_return_value(regs, attr->retval);
|
||||
override_function_with_return(regs);
|
||||
/* Kprobe specific fixup */
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
167
kernel/kprobes.c
167
kernel/kprobes.c
@ -627,8 +627,8 @@ static void optimize_kprobe(struct kprobe *p)
|
||||
(kprobe_disabled(p) || kprobes_all_disarmed))
|
||||
return;
|
||||
|
||||
/* Both of break_handler and post_handler are not supported. */
|
||||
if (p->break_handler || p->post_handler)
|
||||
/* kprobes with post_handler can not be optimized */
|
||||
if (p->post_handler)
|
||||
return;
|
||||
|
||||
op = container_of(p, struct optimized_kprobe, kp);
|
||||
@ -710,9 +710,7 @@ static void reuse_unused_kprobe(struct kprobe *ap)
|
||||
* there is still a relative jump) and disabled.
|
||||
*/
|
||||
op = container_of(ap, struct optimized_kprobe, kp);
|
||||
if (unlikely(list_empty(&op->list)))
|
||||
printk(KERN_WARNING "Warning: found a stray unused "
|
||||
"aggrprobe@%p\n", ap->addr);
|
||||
WARN_ON_ONCE(list_empty(&op->list));
|
||||
/* Enable the probe again */
|
||||
ap->flags &= ~KPROBE_FLAG_DISABLED;
|
||||
/* Optimize it again (remove from op->list) */
|
||||
@ -985,7 +983,8 @@ static int arm_kprobe_ftrace(struct kprobe *p)
|
||||
ret = ftrace_set_filter_ip(&kprobe_ftrace_ops,
|
||||
(unsigned long)p->addr, 0, 0);
|
||||
if (ret) {
|
||||
pr_debug("Failed to arm kprobe-ftrace at %p (%d)\n", p->addr, ret);
|
||||
pr_debug("Failed to arm kprobe-ftrace at %pS (%d)\n",
|
||||
p->addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1025,7 +1024,8 @@ static int disarm_kprobe_ftrace(struct kprobe *p)
|
||||
|
||||
ret = ftrace_set_filter_ip(&kprobe_ftrace_ops,
|
||||
(unsigned long)p->addr, 1, 0);
|
||||
WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)\n", p->addr, ret);
|
||||
WARN_ONCE(ret < 0, "Failed to disarm kprobe-ftrace at %pS (%d)\n",
|
||||
p->addr, ret);
|
||||
return ret;
|
||||
}
|
||||
#else /* !CONFIG_KPROBES_ON_FTRACE */
|
||||
@ -1116,20 +1116,6 @@ static int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
|
||||
}
|
||||
NOKPROBE_SYMBOL(aggr_fault_handler);
|
||||
|
||||
static int aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe *cur = __this_cpu_read(kprobe_instance);
|
||||
int ret = 0;
|
||||
|
||||
if (cur && cur->break_handler) {
|
||||
if (cur->break_handler(cur, regs))
|
||||
ret = 1;
|
||||
}
|
||||
reset_kprobe_instance();
|
||||
return ret;
|
||||
}
|
||||
NOKPROBE_SYMBOL(aggr_break_handler);
|
||||
|
||||
/* Walks the list and increments nmissed count for multiprobe case */
|
||||
void kprobes_inc_nmissed_count(struct kprobe *p)
|
||||
{
|
||||
@ -1270,24 +1256,15 @@ static void cleanup_rp_inst(struct kretprobe *rp)
|
||||
}
|
||||
NOKPROBE_SYMBOL(cleanup_rp_inst);
|
||||
|
||||
/*
|
||||
* Add the new probe to ap->list. Fail if this is the
|
||||
* second jprobe at the address - two jprobes can't coexist
|
||||
*/
|
||||
/* Add the new probe to ap->list */
|
||||
static int add_new_kprobe(struct kprobe *ap, struct kprobe *p)
|
||||
{
|
||||
BUG_ON(kprobe_gone(ap) || kprobe_gone(p));
|
||||
|
||||
if (p->break_handler || p->post_handler)
|
||||
if (p->post_handler)
|
||||
unoptimize_kprobe(ap, true); /* Fall back to normal kprobe */
|
||||
|
||||
if (p->break_handler) {
|
||||
if (ap->break_handler)
|
||||
return -EEXIST;
|
||||
list_add_tail_rcu(&p->list, &ap->list);
|
||||
ap->break_handler = aggr_break_handler;
|
||||
} else
|
||||
list_add_rcu(&p->list, &ap->list);
|
||||
list_add_rcu(&p->list, &ap->list);
|
||||
if (p->post_handler && !ap->post_handler)
|
||||
ap->post_handler = aggr_post_handler;
|
||||
|
||||
@ -1310,8 +1287,6 @@ static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
|
||||
/* We don't care the kprobe which has gone. */
|
||||
if (p->post_handler && !kprobe_gone(p))
|
||||
ap->post_handler = aggr_post_handler;
|
||||
if (p->break_handler && !kprobe_gone(p))
|
||||
ap->break_handler = aggr_break_handler;
|
||||
|
||||
INIT_LIST_HEAD(&ap->list);
|
||||
INIT_HLIST_NODE(&ap->hlist);
|
||||
@ -1706,8 +1681,6 @@ static int __unregister_kprobe_top(struct kprobe *p)
|
||||
goto disarmed;
|
||||
else {
|
||||
/* If disabling probe has special handlers, update aggrprobe */
|
||||
if (p->break_handler && !kprobe_gone(p))
|
||||
ap->break_handler = NULL;
|
||||
if (p->post_handler && !kprobe_gone(p)) {
|
||||
list_for_each_entry_rcu(list_p, &ap->list, list) {
|
||||
if ((list_p != p) && (list_p->post_handler))
|
||||
@ -1812,77 +1785,6 @@ unsigned long __weak arch_deref_entry_point(void *entry)
|
||||
return (unsigned long)entry;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int register_jprobes(struct jprobe **jps, int num)
|
||||
{
|
||||
int ret = 0, i;
|
||||
|
||||
if (num <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ret = register_jprobe(jps[i]);
|
||||
|
||||
if (ret < 0) {
|
||||
if (i > 0)
|
||||
unregister_jprobes(jps, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_jprobes);
|
||||
|
||||
int register_jprobe(struct jprobe *jp)
|
||||
{
|
||||
unsigned long addr, offset;
|
||||
struct kprobe *kp = &jp->kp;
|
||||
|
||||
/*
|
||||
* Verify probepoint as well as the jprobe handler are
|
||||
* valid function entry points.
|
||||
*/
|
||||
addr = arch_deref_entry_point(jp->entry);
|
||||
|
||||
if (kallsyms_lookup_size_offset(addr, NULL, &offset) && offset == 0 &&
|
||||
kprobe_on_func_entry(kp->addr, kp->symbol_name, kp->offset)) {
|
||||
kp->pre_handler = setjmp_pre_handler;
|
||||
kp->break_handler = longjmp_break_handler;
|
||||
return register_kprobe(kp);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_jprobe);
|
||||
|
||||
void unregister_jprobe(struct jprobe *jp)
|
||||
{
|
||||
unregister_jprobes(&jp, 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_jprobe);
|
||||
|
||||
void unregister_jprobes(struct jprobe **jps, int num)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
mutex_lock(&kprobe_mutex);
|
||||
for (i = 0; i < num; i++)
|
||||
if (__unregister_kprobe_top(&jps[i]->kp) < 0)
|
||||
jps[i]->kp.addr = NULL;
|
||||
mutex_unlock(&kprobe_mutex);
|
||||
|
||||
synchronize_sched();
|
||||
for (i = 0; i < num; i++) {
|
||||
if (jps[i]->kp.addr)
|
||||
__unregister_kprobe_bottom(&jps[i]->kp);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_jprobes);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KRETPROBES
|
||||
/*
|
||||
* This kprobe pre_handler is registered with every kretprobe. When probe
|
||||
@ -1982,7 +1884,6 @@ int register_kretprobe(struct kretprobe *rp)
|
||||
rp->kp.pre_handler = pre_handler_kretprobe;
|
||||
rp->kp.post_handler = NULL;
|
||||
rp->kp.fault_handler = NULL;
|
||||
rp->kp.break_handler = NULL;
|
||||
|
||||
/* Pre-allocate memory for max kretprobe instances */
|
||||
if (rp->maxactive <= 0) {
|
||||
@ -2105,7 +2006,6 @@ static void kill_kprobe(struct kprobe *p)
|
||||
list_for_each_entry_rcu(kp, &p->list, list)
|
||||
kp->flags |= KPROBE_FLAG_GONE;
|
||||
p->post_handler = NULL;
|
||||
p->break_handler = NULL;
|
||||
kill_optimized_kprobe(p);
|
||||
}
|
||||
/*
|
||||
@ -2169,11 +2069,12 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(enable_kprobe);
|
||||
|
||||
/* Caller must NOT call this in usual path. This is only for critical case */
|
||||
void dump_kprobe(struct kprobe *kp)
|
||||
{
|
||||
printk(KERN_WARNING "Dumping kprobe:\n");
|
||||
printk(KERN_WARNING "Name: %s\nAddress: %p\nOffset: %x\n",
|
||||
kp->symbol_name, kp->addr, kp->offset);
|
||||
pr_err("Dumping kprobe:\n");
|
||||
pr_err("Name: %s\nOffset: %x\nAddress: %pS\n",
|
||||
kp->symbol_name, kp->offset, kp->addr);
|
||||
}
|
||||
NOKPROBE_SYMBOL(dump_kprobe);
|
||||
|
||||
@ -2196,11 +2097,8 @@ static int __init populate_kprobe_blacklist(unsigned long *start,
|
||||
entry = arch_deref_entry_point((void *)*iter);
|
||||
|
||||
if (!kernel_text_address(entry) ||
|
||||
!kallsyms_lookup_size_offset(entry, &size, &offset)) {
|
||||
pr_err("Failed to find blacklist at %p\n",
|
||||
(void *)entry);
|
||||
!kallsyms_lookup_size_offset(entry, &size, &offset))
|
||||
continue;
|
||||
}
|
||||
|
||||
ent = kmalloc(sizeof(*ent), GFP_KERNEL);
|
||||
if (!ent)
|
||||
@ -2326,21 +2224,23 @@ static void report_probe(struct seq_file *pi, struct kprobe *p,
|
||||
const char *sym, int offset, char *modname, struct kprobe *pp)
|
||||
{
|
||||
char *kprobe_type;
|
||||
void *addr = p->addr;
|
||||
|
||||
if (p->pre_handler == pre_handler_kretprobe)
|
||||
kprobe_type = "r";
|
||||
else if (p->pre_handler == setjmp_pre_handler)
|
||||
kprobe_type = "j";
|
||||
else
|
||||
kprobe_type = "k";
|
||||
|
||||
if (!kallsyms_show_value())
|
||||
addr = NULL;
|
||||
|
||||
if (sym)
|
||||
seq_printf(pi, "%p %s %s+0x%x %s ",
|
||||
p->addr, kprobe_type, sym, offset,
|
||||
seq_printf(pi, "%px %s %s+0x%x %s ",
|
||||
addr, kprobe_type, sym, offset,
|
||||
(modname ? modname : " "));
|
||||
else
|
||||
seq_printf(pi, "%p %s %p ",
|
||||
p->addr, kprobe_type, p->addr);
|
||||
else /* try to use %pS */
|
||||
seq_printf(pi, "%px %s %pS ",
|
||||
addr, kprobe_type, p->addr);
|
||||
|
||||
if (!pp)
|
||||
pp = p;
|
||||
@ -2428,8 +2328,16 @@ static int kprobe_blacklist_seq_show(struct seq_file *m, void *v)
|
||||
struct kprobe_blacklist_entry *ent =
|
||||
list_entry(v, struct kprobe_blacklist_entry, list);
|
||||
|
||||
seq_printf(m, "0x%px-0x%px\t%ps\n", (void *)ent->start_addr,
|
||||
(void *)ent->end_addr, (void *)ent->start_addr);
|
||||
/*
|
||||
* If /proc/kallsyms is not showing kernel address, we won't
|
||||
* show them here either.
|
||||
*/
|
||||
if (!kallsyms_show_value())
|
||||
seq_printf(m, "0x%px-0x%px\t%ps\n", NULL, NULL,
|
||||
(void *)ent->start_addr);
|
||||
else
|
||||
seq_printf(m, "0x%px-0x%px\t%ps\n", (void *)ent->start_addr,
|
||||
(void *)ent->end_addr, (void *)ent->start_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2611,7 +2519,7 @@ static int __init debugfs_kprobe_init(void)
|
||||
if (!dir)
|
||||
return -ENOMEM;
|
||||
|
||||
file = debugfs_create_file("list", 0444, dir, NULL,
|
||||
file = debugfs_create_file("list", 0400, dir, NULL,
|
||||
&debugfs_kprobes_operations);
|
||||
if (!file)
|
||||
goto error;
|
||||
@ -2621,7 +2529,7 @@ static int __init debugfs_kprobe_init(void)
|
||||
if (!file)
|
||||
goto error;
|
||||
|
||||
file = debugfs_create_file("blacklist", 0444, dir, NULL,
|
||||
file = debugfs_create_file("blacklist", 0400, dir, NULL,
|
||||
&debugfs_kprobe_blacklist_ops);
|
||||
if (!file)
|
||||
goto error;
|
||||
@ -2637,6 +2545,3 @@ late_initcall(debugfs_kprobe_init);
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
module_init(init_kprobes);
|
||||
|
||||
/* defined in arch/.../kernel/kprobes.c */
|
||||
EXPORT_SYMBOL_GPL(jprobe_return);
|
||||
|
@ -162,90 +162,6 @@ static int test_kprobes(void)
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
static u32 jph_val;
|
||||
|
||||
static u32 j_kprobe_target(u32 value)
|
||||
{
|
||||
if (preemptible()) {
|
||||
handler_errors++;
|
||||
pr_err("jprobe-handler is preemptible\n");
|
||||
}
|
||||
if (value != rand1) {
|
||||
handler_errors++;
|
||||
pr_err("incorrect value in jprobe handler\n");
|
||||
}
|
||||
|
||||
jph_val = rand1;
|
||||
jprobe_return();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct jprobe jp = {
|
||||
.entry = j_kprobe_target,
|
||||
.kp.symbol_name = "kprobe_target"
|
||||
};
|
||||
|
||||
static int test_jprobe(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = register_jprobe(&jp);
|
||||
if (ret < 0) {
|
||||
pr_err("register_jprobe returned %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = target(rand1);
|
||||
unregister_jprobe(&jp);
|
||||
if (jph_val == 0) {
|
||||
pr_err("jprobe handler not called\n");
|
||||
handler_errors++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct jprobe jp2 = {
|
||||
.entry = j_kprobe_target,
|
||||
.kp.symbol_name = "kprobe_target2"
|
||||
};
|
||||
|
||||
static int test_jprobes(void)
|
||||
{
|
||||
int ret;
|
||||
struct jprobe *jps[2] = {&jp, &jp2};
|
||||
|
||||
/* addr and flags should be cleard for reusing kprobe. */
|
||||
jp.kp.addr = NULL;
|
||||
jp.kp.flags = 0;
|
||||
ret = register_jprobes(jps, 2);
|
||||
if (ret < 0) {
|
||||
pr_err("register_jprobes returned %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
jph_val = 0;
|
||||
ret = target(rand1);
|
||||
if (jph_val == 0) {
|
||||
pr_err("jprobe handler not called\n");
|
||||
handler_errors++;
|
||||
}
|
||||
|
||||
jph_val = 0;
|
||||
ret = target2(rand1);
|
||||
if (jph_val == 0) {
|
||||
pr_err("jprobe handler2 not called\n");
|
||||
handler_errors++;
|
||||
}
|
||||
unregister_jprobes(jps, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define test_jprobe() (0)
|
||||
#define test_jprobes() (0)
|
||||
#endif
|
||||
#ifdef CONFIG_KRETPROBES
|
||||
static u32 krph_val;
|
||||
|
||||
@ -383,16 +299,6 @@ int init_test_probes(void)
|
||||
if (ret < 0)
|
||||
errors++;
|
||||
|
||||
num_tests++;
|
||||
ret = test_jprobe();
|
||||
if (ret < 0)
|
||||
errors++;
|
||||
|
||||
num_tests++;
|
||||
ret = test_jprobes();
|
||||
if (ret < 0)
|
||||
errors++;
|
||||
|
||||
#ifdef CONFIG_KRETPROBES
|
||||
num_tests++;
|
||||
ret = test_kretprobe();
|
||||
|
@ -1228,16 +1228,11 @@ kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs)
|
||||
|
||||
/*
|
||||
* We need to check and see if we modified the pc of the
|
||||
* pt_regs, and if so clear the kprobe and return 1 so that we
|
||||
* don't do the single stepping.
|
||||
* The ftrace kprobe handler leaves it up to us to re-enable
|
||||
* preemption here before returning if we've modified the ip.
|
||||
* pt_regs, and if so return 1 so that we don't do the
|
||||
* single stepping.
|
||||
*/
|
||||
if (orig_ip != instruction_pointer(regs)) {
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
if (orig_ip != instruction_pointer(regs))
|
||||
return 1;
|
||||
}
|
||||
if (!ret)
|
||||
return 0;
|
||||
}
|
||||
|
@ -1718,7 +1718,7 @@ config KPROBES_SANITY_TEST
|
||||
default n
|
||||
help
|
||||
This option provides for testing basic kprobes functionality on
|
||||
boot. A sample kprobe, jprobe and kretprobe are inserted and
|
||||
boot. Samples of kprobe and kretprobe are inserted and
|
||||
verified for functionality.
|
||||
|
||||
Say N if you are unsure.
|
||||
|
20
tools/arch/arm64/include/uapi/asm/unistd.h
Normal file
20
tools/arch/arm64/include/uapi/asm/unistd.h
Normal file
@ -0,0 +1,20 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (C) 2012 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define __ARCH_WANT_RENAMEAT
|
||||
|
||||
#include <asm-generic/unistd.h>
|
783
tools/include/uapi/asm-generic/unistd.h
Normal file
783
tools/include/uapi/asm-generic/unistd.h
Normal file
@ -0,0 +1,783 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#include <asm/bitsperlong.h>
|
||||
|
||||
/*
|
||||
* This file contains the system call numbers, based on the
|
||||
* layout of the x86-64 architecture, which embeds the
|
||||
* pointer to the syscall in the table.
|
||||
*
|
||||
* As a basic principle, no duplication of functionality
|
||||
* should be added, e.g. we don't use lseek when llseek
|
||||
* is present. New architectures should use this file
|
||||
* and implement the less feature-full calls in user space.
|
||||
*/
|
||||
|
||||
#ifndef __SYSCALL
|
||||
#define __SYSCALL(x, y)
|
||||
#endif
|
||||
|
||||
#if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)
|
||||
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
|
||||
#else
|
||||
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
|
||||
#endif
|
||||
|
||||
#ifdef __SYSCALL_COMPAT
|
||||
#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp)
|
||||
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
|
||||
#else
|
||||
#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys)
|
||||
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
|
||||
#endif
|
||||
|
||||
#define __NR_io_setup 0
|
||||
__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
|
||||
#define __NR_io_destroy 1
|
||||
__SYSCALL(__NR_io_destroy, sys_io_destroy)
|
||||
#define __NR_io_submit 2
|
||||
__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
|
||||
#define __NR_io_cancel 3
|
||||
__SYSCALL(__NR_io_cancel, sys_io_cancel)
|
||||
#define __NR_io_getevents 4
|
||||
__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents)
|
||||
|
||||
/* fs/xattr.c */
|
||||
#define __NR_setxattr 5
|
||||
__SYSCALL(__NR_setxattr, sys_setxattr)
|
||||
#define __NR_lsetxattr 6
|
||||
__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
|
||||
#define __NR_fsetxattr 7
|
||||
__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
|
||||
#define __NR_getxattr 8
|
||||
__SYSCALL(__NR_getxattr, sys_getxattr)
|
||||
#define __NR_lgetxattr 9
|
||||
__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
|
||||
#define __NR_fgetxattr 10
|
||||
__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
|
||||
#define __NR_listxattr 11
|
||||
__SYSCALL(__NR_listxattr, sys_listxattr)
|
||||
#define __NR_llistxattr 12
|
||||
__SYSCALL(__NR_llistxattr, sys_llistxattr)
|
||||
#define __NR_flistxattr 13
|
||||
__SYSCALL(__NR_flistxattr, sys_flistxattr)
|
||||
#define __NR_removexattr 14
|
||||
__SYSCALL(__NR_removexattr, sys_removexattr)
|
||||
#define __NR_lremovexattr 15
|
||||
__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
|
||||
#define __NR_fremovexattr 16
|
||||
__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
|
||||
|
||||
/* fs/dcache.c */
|
||||
#define __NR_getcwd 17
|
||||
__SYSCALL(__NR_getcwd, sys_getcwd)
|
||||
|
||||
/* fs/cookies.c */
|
||||
#define __NR_lookup_dcookie 18
|
||||
__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
|
||||
|
||||
/* fs/eventfd.c */
|
||||
#define __NR_eventfd2 19
|
||||
__SYSCALL(__NR_eventfd2, sys_eventfd2)
|
||||
|
||||
/* fs/eventpoll.c */
|
||||
#define __NR_epoll_create1 20
|
||||
__SYSCALL(__NR_epoll_create1, sys_epoll_create1)
|
||||
#define __NR_epoll_ctl 21
|
||||
__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
|
||||
#define __NR_epoll_pwait 22
|
||||
__SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait)
|
||||
|
||||
/* fs/fcntl.c */
|
||||
#define __NR_dup 23
|
||||
__SYSCALL(__NR_dup, sys_dup)
|
||||
#define __NR_dup3 24
|
||||
__SYSCALL(__NR_dup3, sys_dup3)
|
||||
#define __NR3264_fcntl 25
|
||||
__SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64)
|
||||
|
||||
/* fs/inotify_user.c */
|
||||
#define __NR_inotify_init1 26
|
||||
__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
|
||||
#define __NR_inotify_add_watch 27
|
||||
__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
|
||||
#define __NR_inotify_rm_watch 28
|
||||
__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
|
||||
|
||||
/* fs/ioctl.c */
|
||||
#define __NR_ioctl 29
|
||||
__SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl)
|
||||
|
||||
/* fs/ioprio.c */
|
||||
#define __NR_ioprio_set 30
|
||||
__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
|
||||
#define __NR_ioprio_get 31
|
||||
__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
|
||||
|
||||
/* fs/locks.c */
|
||||
#define __NR_flock 32
|
||||
__SYSCALL(__NR_flock, sys_flock)
|
||||
|
||||
/* fs/namei.c */
|
||||
#define __NR_mknodat 33
|
||||
__SYSCALL(__NR_mknodat, sys_mknodat)
|
||||
#define __NR_mkdirat 34
|
||||
__SYSCALL(__NR_mkdirat, sys_mkdirat)
|
||||
#define __NR_unlinkat 35
|
||||
__SYSCALL(__NR_unlinkat, sys_unlinkat)
|
||||
#define __NR_symlinkat 36
|
||||
__SYSCALL(__NR_symlinkat, sys_symlinkat)
|
||||
#define __NR_linkat 37
|
||||
__SYSCALL(__NR_linkat, sys_linkat)
|
||||
#ifdef __ARCH_WANT_RENAMEAT
|
||||
/* renameat is superseded with flags by renameat2 */
|
||||
#define __NR_renameat 38
|
||||
__SYSCALL(__NR_renameat, sys_renameat)
|
||||
#endif /* __ARCH_WANT_RENAMEAT */
|
||||
|
||||
/* fs/namespace.c */
|
||||
#define __NR_umount2 39
|
||||
__SYSCALL(__NR_umount2, sys_umount)
|
||||
#define __NR_mount 40
|
||||
__SC_COMP(__NR_mount, sys_mount, compat_sys_mount)
|
||||
#define __NR_pivot_root 41
|
||||
__SYSCALL(__NR_pivot_root, sys_pivot_root)
|
||||
|
||||
/* fs/nfsctl.c */
|
||||
#define __NR_nfsservctl 42
|
||||
__SYSCALL(__NR_nfsservctl, sys_ni_syscall)
|
||||
|
||||
/* fs/open.c */
|
||||
#define __NR3264_statfs 43
|
||||
__SC_COMP_3264(__NR3264_statfs, sys_statfs64, sys_statfs, \
|
||||
compat_sys_statfs64)
|
||||
#define __NR3264_fstatfs 44
|
||||
__SC_COMP_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs, \
|
||||
compat_sys_fstatfs64)
|
||||
#define __NR3264_truncate 45
|
||||
__SC_COMP_3264(__NR3264_truncate, sys_truncate64, sys_truncate, \
|
||||
compat_sys_truncate64)
|
||||
#define __NR3264_ftruncate 46
|
||||
__SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \
|
||||
compat_sys_ftruncate64)
|
||||
|
||||
#define __NR_fallocate 47
|
||||
__SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate)
|
||||
#define __NR_faccessat 48
|
||||
__SYSCALL(__NR_faccessat, sys_faccessat)
|
||||
#define __NR_chdir 49
|
||||
__SYSCALL(__NR_chdir, sys_chdir)
|
||||
#define __NR_fchdir 50
|
||||
__SYSCALL(__NR_fchdir, sys_fchdir)
|
||||
#define __NR_chroot 51
|
||||
__SYSCALL(__NR_chroot, sys_chroot)
|
||||
#define __NR_fchmod 52
|
||||
__SYSCALL(__NR_fchmod, sys_fchmod)
|
||||
#define __NR_fchmodat 53
|
||||
__SYSCALL(__NR_fchmodat, sys_fchmodat)
|
||||
#define __NR_fchownat 54
|
||||
__SYSCALL(__NR_fchownat, sys_fchownat)
|
||||
#define __NR_fchown 55
|
||||
__SYSCALL(__NR_fchown, sys_fchown)
|
||||
#define __NR_openat 56
|
||||
__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)
|
||||
#define __NR_close 57
|
||||
__SYSCALL(__NR_close, sys_close)
|
||||
#define __NR_vhangup 58
|
||||
__SYSCALL(__NR_vhangup, sys_vhangup)
|
||||
|
||||
/* fs/pipe.c */
|
||||
#define __NR_pipe2 59
|
||||
__SYSCALL(__NR_pipe2, sys_pipe2)
|
||||
|
||||
/* fs/quota.c */
|
||||
#define __NR_quotactl 60
|
||||
__SYSCALL(__NR_quotactl, sys_quotactl)
|
||||
|
||||
/* fs/readdir.c */
|
||||
#define __NR_getdents64 61
|
||||
__SYSCALL(__NR_getdents64, sys_getdents64)
|
||||
|
||||
/* fs/read_write.c */
|
||||
#define __NR3264_lseek 62
|
||||
__SC_3264(__NR3264_lseek, sys_llseek, sys_lseek)
|
||||
#define __NR_read 63
|
||||
__SYSCALL(__NR_read, sys_read)
|
||||
#define __NR_write 64
|
||||
__SYSCALL(__NR_write, sys_write)
|
||||
#define __NR_readv 65
|
||||
__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
|
||||
#define __NR_writev 66
|
||||
__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
|
||||
#define __NR_pread64 67
|
||||
__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
|
||||
#define __NR_pwrite64 68
|
||||
__SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64)
|
||||
#define __NR_preadv 69
|
||||
__SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv)
|
||||
#define __NR_pwritev 70
|
||||
__SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev)
|
||||
|
||||
/* fs/sendfile.c */
|
||||
#define __NR3264_sendfile 71
|
||||
__SYSCALL(__NR3264_sendfile, sys_sendfile64)
|
||||
|
||||
/* fs/select.c */
|
||||
#define __NR_pselect6 72
|
||||
__SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6)
|
||||
#define __NR_ppoll 73
|
||||
__SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll)
|
||||
|
||||
/* fs/signalfd.c */
|
||||
#define __NR_signalfd4 74
|
||||
__SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
|
||||
|
||||
/* fs/splice.c */
|
||||
#define __NR_vmsplice 75
|
||||
__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
|
||||
#define __NR_splice 76
|
||||
__SYSCALL(__NR_splice, sys_splice)
|
||||
#define __NR_tee 77
|
||||
__SYSCALL(__NR_tee, sys_tee)
|
||||
|
||||
/* fs/stat.c */
|
||||
#define __NR_readlinkat 78
|
||||
__SYSCALL(__NR_readlinkat, sys_readlinkat)
|
||||
#define __NR3264_fstatat 79
|
||||
__SC_3264(__NR3264_fstatat, sys_fstatat64, sys_newfstatat)
|
||||
#define __NR3264_fstat 80
|
||||
__SC_3264(__NR3264_fstat, sys_fstat64, sys_newfstat)
|
||||
|
||||
/* fs/sync.c */
|
||||
#define __NR_sync 81
|
||||
__SYSCALL(__NR_sync, sys_sync)
|
||||
#define __NR_fsync 82
|
||||
__SYSCALL(__NR_fsync, sys_fsync)
|
||||
#define __NR_fdatasync 83
|
||||
__SYSCALL(__NR_fdatasync, sys_fdatasync)
|
||||
#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
|
||||
#define __NR_sync_file_range2 84
|
||||
__SC_COMP(__NR_sync_file_range2, sys_sync_file_range2, \
|
||||
compat_sys_sync_file_range2)
|
||||
#else
|
||||
#define __NR_sync_file_range 84
|
||||
__SC_COMP(__NR_sync_file_range, sys_sync_file_range, \
|
||||
compat_sys_sync_file_range)
|
||||
#endif
|
||||
|
||||
/* fs/timerfd.c */
|
||||
#define __NR_timerfd_create 85
|
||||
__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
|
||||
#define __NR_timerfd_settime 86
|
||||
__SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \
|
||||
compat_sys_timerfd_settime)
|
||||
#define __NR_timerfd_gettime 87
|
||||
__SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \
|
||||
compat_sys_timerfd_gettime)
|
||||
|
||||
/* fs/utimes.c */
|
||||
#define __NR_utimensat 88
|
||||
__SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat)
|
||||
|
||||
/* kernel/acct.c */
|
||||
#define __NR_acct 89
|
||||
__SYSCALL(__NR_acct, sys_acct)
|
||||
|
||||
/* kernel/capability.c */
|
||||
#define __NR_capget 90
|
||||
__SYSCALL(__NR_capget, sys_capget)
|
||||
#define __NR_capset 91
|
||||
__SYSCALL(__NR_capset, sys_capset)
|
||||
|
||||
/* kernel/exec_domain.c */
|
||||
#define __NR_personality 92
|
||||
__SYSCALL(__NR_personality, sys_personality)
|
||||
|
||||
/* kernel/exit.c */
|
||||
#define __NR_exit 93
|
||||
__SYSCALL(__NR_exit, sys_exit)
|
||||
#define __NR_exit_group 94
|
||||
__SYSCALL(__NR_exit_group, sys_exit_group)
|
||||
#define __NR_waitid 95
|
||||
__SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid)
|
||||
|
||||
/* kernel/fork.c */
|
||||
#define __NR_set_tid_address 96
|
||||
__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
|
||||
#define __NR_unshare 97
|
||||
__SYSCALL(__NR_unshare, sys_unshare)
|
||||
|
||||
/* kernel/futex.c */
|
||||
#define __NR_futex 98
|
||||
__SC_COMP(__NR_futex, sys_futex, compat_sys_futex)
|
||||
#define __NR_set_robust_list 99
|
||||
__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \
|
||||
compat_sys_set_robust_list)
|
||||
#define __NR_get_robust_list 100
|
||||
__SC_COMP(__NR_get_robust_list, sys_get_robust_list, \
|
||||
compat_sys_get_robust_list)
|
||||
|
||||
/* kernel/hrtimer.c */
|
||||
#define __NR_nanosleep 101
|
||||
__SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep)
|
||||
|
||||
/* kernel/itimer.c */
|
||||
#define __NR_getitimer 102
|
||||
__SC_COMP(__NR_getitimer, sys_getitimer, compat_sys_getitimer)
|
||||
#define __NR_setitimer 103
|
||||
__SC_COMP(__NR_setitimer, sys_setitimer, compat_sys_setitimer)
|
||||
|
||||
/* kernel/kexec.c */
|
||||
#define __NR_kexec_load 104
|
||||
__SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load)
|
||||
|
||||
/* kernel/module.c */
|
||||
#define __NR_init_module 105
|
||||
__SYSCALL(__NR_init_module, sys_init_module)
|
||||
#define __NR_delete_module 106
|
||||
__SYSCALL(__NR_delete_module, sys_delete_module)
|
||||
|
||||
/* kernel/posix-timers.c */
|
||||
#define __NR_timer_create 107
|
||||
__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create)
|
||||
#define __NR_timer_gettime 108
|
||||
__SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime)
|
||||
#define __NR_timer_getoverrun 109
|
||||
__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
|
||||
#define __NR_timer_settime 110
|
||||
__SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime)
|
||||
#define __NR_timer_delete 111
|
||||
__SYSCALL(__NR_timer_delete, sys_timer_delete)
|
||||
#define __NR_clock_settime 112
|
||||
__SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime)
|
||||
#define __NR_clock_gettime 113
|
||||
__SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime)
|
||||
#define __NR_clock_getres 114
|
||||
__SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres)
|
||||
#define __NR_clock_nanosleep 115
|
||||
__SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \
|
||||
compat_sys_clock_nanosleep)
|
||||
|
||||
/* kernel/printk.c */
|
||||
#define __NR_syslog 116
|
||||
__SYSCALL(__NR_syslog, sys_syslog)
|
||||
|
||||
/* kernel/ptrace.c */
|
||||
#define __NR_ptrace 117
|
||||
__SYSCALL(__NR_ptrace, sys_ptrace)
|
||||
|
||||
/* kernel/sched/core.c */
|
||||
#define __NR_sched_setparam 118
|
||||
__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
|
||||
#define __NR_sched_setscheduler 119
|
||||
__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
|
||||
#define __NR_sched_getscheduler 120
|
||||
__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
|
||||
#define __NR_sched_getparam 121
|
||||
__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
|
||||
#define __NR_sched_setaffinity 122
|
||||
__SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \
|
||||
compat_sys_sched_setaffinity)
|
||||
#define __NR_sched_getaffinity 123
|
||||
__SC_COMP(__NR_sched_getaffinity, sys_sched_getaffinity, \
|
||||
compat_sys_sched_getaffinity)
|
||||
#define __NR_sched_yield 124
|
||||
__SYSCALL(__NR_sched_yield, sys_sched_yield)
|
||||
#define __NR_sched_get_priority_max 125
|
||||
__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
|
||||
#define __NR_sched_get_priority_min 126
|
||||
__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
|
||||
#define __NR_sched_rr_get_interval 127
|
||||
__SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \
|
||||
compat_sys_sched_rr_get_interval)
|
||||
|
||||
/* kernel/signal.c */
|
||||
#define __NR_restart_syscall 128
|
||||
__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
|
||||
#define __NR_kill 129
|
||||
__SYSCALL(__NR_kill, sys_kill)
|
||||
#define __NR_tkill 130
|
||||
__SYSCALL(__NR_tkill, sys_tkill)
|
||||
#define __NR_tgkill 131
|
||||
__SYSCALL(__NR_tgkill, sys_tgkill)
|
||||
#define __NR_sigaltstack 132
|
||||
__SC_COMP(__NR_sigaltstack, sys_sigaltstack, compat_sys_sigaltstack)
|
||||
#define __NR_rt_sigsuspend 133
|
||||
__SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend)
|
||||
#define __NR_rt_sigaction 134
|
||||
__SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction)
|
||||
#define __NR_rt_sigprocmask 135
|
||||
__SC_COMP(__NR_rt_sigprocmask, sys_rt_sigprocmask, compat_sys_rt_sigprocmask)
|
||||
#define __NR_rt_sigpending 136
|
||||
__SC_COMP(__NR_rt_sigpending, sys_rt_sigpending, compat_sys_rt_sigpending)
|
||||
#define __NR_rt_sigtimedwait 137
|
||||
__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \
|
||||
compat_sys_rt_sigtimedwait)
|
||||
#define __NR_rt_sigqueueinfo 138
|
||||
__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \
|
||||
compat_sys_rt_sigqueueinfo)
|
||||
#define __NR_rt_sigreturn 139
|
||||
__SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn)
|
||||
|
||||
/* kernel/sys.c */
|
||||
#define __NR_setpriority 140
|
||||
__SYSCALL(__NR_setpriority, sys_setpriority)
|
||||
#define __NR_getpriority 141
|
||||
__SYSCALL(__NR_getpriority, sys_getpriority)
|
||||
#define __NR_reboot 142
|
||||
__SYSCALL(__NR_reboot, sys_reboot)
|
||||
#define __NR_setregid 143
|
||||
__SYSCALL(__NR_setregid, sys_setregid)
|
||||
#define __NR_setgid 144
|
||||
__SYSCALL(__NR_setgid, sys_setgid)
|
||||
#define __NR_setreuid 145
|
||||
__SYSCALL(__NR_setreuid, sys_setreuid)
|
||||
#define __NR_setuid 146
|
||||
__SYSCALL(__NR_setuid, sys_setuid)
|
||||
#define __NR_setresuid 147
|
||||
__SYSCALL(__NR_setresuid, sys_setresuid)
|
||||
#define __NR_getresuid 148
|
||||
__SYSCALL(__NR_getresuid, sys_getresuid)
|
||||
#define __NR_setresgid 149
|
||||
__SYSCALL(__NR_setresgid, sys_setresgid)
|
||||
#define __NR_getresgid 150
|
||||
__SYSCALL(__NR_getresgid, sys_getresgid)
|
||||
#define __NR_setfsuid 151
|
||||
__SYSCALL(__NR_setfsuid, sys_setfsuid)
|
||||
#define __NR_setfsgid 152
|
||||
__SYSCALL(__NR_setfsgid, sys_setfsgid)
|
||||
#define __NR_times 153
|
||||
__SC_COMP(__NR_times, sys_times, compat_sys_times)
|
||||
#define __NR_setpgid 154
|
||||
__SYSCALL(__NR_setpgid, sys_setpgid)
|
||||
#define __NR_getpgid 155
|
||||
__SYSCALL(__NR_getpgid, sys_getpgid)
|
||||
#define __NR_getsid 156
|
||||
__SYSCALL(__NR_getsid, sys_getsid)
|
||||
#define __NR_setsid 157
|
||||
__SYSCALL(__NR_setsid, sys_setsid)
|
||||
#define __NR_getgroups 158
|
||||
__SYSCALL(__NR_getgroups, sys_getgroups)
|
||||
#define __NR_setgroups 159
|
||||
__SYSCALL(__NR_setgroups, sys_setgroups)
|
||||
#define __NR_uname 160
|
||||
__SYSCALL(__NR_uname, sys_newuname)
|
||||
#define __NR_sethostname 161
|
||||
__SYSCALL(__NR_sethostname, sys_sethostname)
|
||||
#define __NR_setdomainname 162
|
||||
__SYSCALL(__NR_setdomainname, sys_setdomainname)
|
||||
#define __NR_getrlimit 163
|
||||
__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit)
|
||||
#define __NR_setrlimit 164
|
||||
__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit)
|
||||
#define __NR_getrusage 165
|
||||
__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage)
|
||||
#define __NR_umask 166
|
||||
__SYSCALL(__NR_umask, sys_umask)
|
||||
#define __NR_prctl 167
|
||||
__SYSCALL(__NR_prctl, sys_prctl)
|
||||
#define __NR_getcpu 168
|
||||
__SYSCALL(__NR_getcpu, sys_getcpu)
|
||||
|
||||
/* kernel/time.c */
|
||||
#define __NR_gettimeofday 169
|
||||
__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday)
|
||||
#define __NR_settimeofday 170
|
||||
__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday)
|
||||
#define __NR_adjtimex 171
|
||||
__SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex)
|
||||
|
||||
/* kernel/timer.c */
|
||||
#define __NR_getpid 172
|
||||
__SYSCALL(__NR_getpid, sys_getpid)
|
||||
#define __NR_getppid 173
|
||||
__SYSCALL(__NR_getppid, sys_getppid)
|
||||
#define __NR_getuid 174
|
||||
__SYSCALL(__NR_getuid, sys_getuid)
|
||||
#define __NR_geteuid 175
|
||||
__SYSCALL(__NR_geteuid, sys_geteuid)
|
||||
#define __NR_getgid 176
|
||||
__SYSCALL(__NR_getgid, sys_getgid)
|
||||
#define __NR_getegid 177
|
||||
__SYSCALL(__NR_getegid, sys_getegid)
|
||||
#define __NR_gettid 178
|
||||
__SYSCALL(__NR_gettid, sys_gettid)
|
||||
#define __NR_sysinfo 179
|
||||
__SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
|
||||
|
||||
/* ipc/mqueue.c */
|
||||
#define __NR_mq_open 180
|
||||
__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open)
|
||||
#define __NR_mq_unlink 181
|
||||
__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
|
||||
#define __NR_mq_timedsend 182
|
||||
__SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend)
|
||||
#define __NR_mq_timedreceive 183
|
||||
__SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \
|
||||
compat_sys_mq_timedreceive)
|
||||
#define __NR_mq_notify 184
|
||||
__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify)
|
||||
#define __NR_mq_getsetattr 185
|
||||
__SC_COMP(__NR_mq_getsetattr, sys_mq_getsetattr, compat_sys_mq_getsetattr)
|
||||
|
||||
/* ipc/msg.c */
|
||||
#define __NR_msgget 186
|
||||
__SYSCALL(__NR_msgget, sys_msgget)
|
||||
#define __NR_msgctl 187
|
||||
__SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl)
|
||||
#define __NR_msgrcv 188
|
||||
__SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv)
|
||||
#define __NR_msgsnd 189
|
||||
__SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
|
||||
|
||||
/* ipc/sem.c */
|
||||
#define __NR_semget 190
|
||||
__SYSCALL(__NR_semget, sys_semget)
|
||||
#define __NR_semctl 191
|
||||
__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
|
||||
#define __NR_semtimedop 192
|
||||
__SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop)
|
||||
#define __NR_semop 193
|
||||
__SYSCALL(__NR_semop, sys_semop)
|
||||
|
||||
/* ipc/shm.c */
|
||||
#define __NR_shmget 194
|
||||
__SYSCALL(__NR_shmget, sys_shmget)
|
||||
#define __NR_shmctl 195
|
||||
__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl)
|
||||
#define __NR_shmat 196
|
||||
__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat)
|
||||
#define __NR_shmdt 197
|
||||
__SYSCALL(__NR_shmdt, sys_shmdt)
|
||||
|
||||
/* net/socket.c */
|
||||
#define __NR_socket 198
|
||||
__SYSCALL(__NR_socket, sys_socket)
|
||||
#define __NR_socketpair 199
|
||||
__SYSCALL(__NR_socketpair, sys_socketpair)
|
||||
#define __NR_bind 200
|
||||
__SYSCALL(__NR_bind, sys_bind)
|
||||
#define __NR_listen 201
|
||||
__SYSCALL(__NR_listen, sys_listen)
|
||||
#define __NR_accept 202
|
||||
__SYSCALL(__NR_accept, sys_accept)
|
||||
#define __NR_connect 203
|
||||
__SYSCALL(__NR_connect, sys_connect)
|
||||
#define __NR_getsockname 204
|
||||
__SYSCALL(__NR_getsockname, sys_getsockname)
|
||||
#define __NR_getpeername 205
|
||||
__SYSCALL(__NR_getpeername, sys_getpeername)
|
||||
#define __NR_sendto 206
|
||||
__SYSCALL(__NR_sendto, sys_sendto)
|
||||
#define __NR_recvfrom 207
|
||||
__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
|
||||
#define __NR_setsockopt 208
|
||||
__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt)
|
||||
#define __NR_getsockopt 209
|
||||
__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt)
|
||||
#define __NR_shutdown 210
|
||||
__SYSCALL(__NR_shutdown, sys_shutdown)
|
||||
#define __NR_sendmsg 211
|
||||
__SC_COMP(__NR_sendmsg, sys_sendmsg, compat_sys_sendmsg)
|
||||
#define __NR_recvmsg 212
|
||||
__SC_COMP(__NR_recvmsg, sys_recvmsg, compat_sys_recvmsg)
|
||||
|
||||
/* mm/filemap.c */
|
||||
#define __NR_readahead 213
|
||||
__SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead)
|
||||
|
||||
/* mm/nommu.c, also with MMU */
|
||||
#define __NR_brk 214
|
||||
__SYSCALL(__NR_brk, sys_brk)
|
||||
#define __NR_munmap 215
|
||||
__SYSCALL(__NR_munmap, sys_munmap)
|
||||
#define __NR_mremap 216
|
||||
__SYSCALL(__NR_mremap, sys_mremap)
|
||||
|
||||
/* security/keys/keyctl.c */
|
||||
#define __NR_add_key 217
|
||||
__SYSCALL(__NR_add_key, sys_add_key)
|
||||
#define __NR_request_key 218
|
||||
__SYSCALL(__NR_request_key, sys_request_key)
|
||||
#define __NR_keyctl 219
|
||||
__SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl)
|
||||
|
||||
/* arch/example/kernel/sys_example.c */
|
||||
#define __NR_clone 220
|
||||
__SYSCALL(__NR_clone, sys_clone)
|
||||
#define __NR_execve 221
|
||||
__SC_COMP(__NR_execve, sys_execve, compat_sys_execve)
|
||||
|
||||
#define __NR3264_mmap 222
|
||||
__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
|
||||
/* mm/fadvise.c */
|
||||
#define __NR3264_fadvise64 223
|
||||
__SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64)
|
||||
|
||||
/* mm/, CONFIG_MMU only */
|
||||
#ifndef __ARCH_NOMMU
|
||||
#define __NR_swapon 224
|
||||
__SYSCALL(__NR_swapon, sys_swapon)
|
||||
#define __NR_swapoff 225
|
||||
__SYSCALL(__NR_swapoff, sys_swapoff)
|
||||
#define __NR_mprotect 226
|
||||
__SYSCALL(__NR_mprotect, sys_mprotect)
|
||||
#define __NR_msync 227
|
||||
__SYSCALL(__NR_msync, sys_msync)
|
||||
#define __NR_mlock 228
|
||||
__SYSCALL(__NR_mlock, sys_mlock)
|
||||
#define __NR_munlock 229
|
||||
__SYSCALL(__NR_munlock, sys_munlock)
|
||||
#define __NR_mlockall 230
|
||||
__SYSCALL(__NR_mlockall, sys_mlockall)
|
||||
#define __NR_munlockall 231
|
||||
__SYSCALL(__NR_munlockall, sys_munlockall)
|
||||
#define __NR_mincore 232
|
||||
__SYSCALL(__NR_mincore, sys_mincore)
|
||||
#define __NR_madvise 233
|
||||
__SYSCALL(__NR_madvise, sys_madvise)
|
||||
#define __NR_remap_file_pages 234
|
||||
__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
|
||||
#define __NR_mbind 235
|
||||
__SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind)
|
||||
#define __NR_get_mempolicy 236
|
||||
__SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy)
|
||||
#define __NR_set_mempolicy 237
|
||||
__SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy)
|
||||
#define __NR_migrate_pages 238
|
||||
__SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages)
|
||||
#define __NR_move_pages 239
|
||||
__SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages)
|
||||
#endif
|
||||
|
||||
#define __NR_rt_tgsigqueueinfo 240
|
||||
__SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \
|
||||
compat_sys_rt_tgsigqueueinfo)
|
||||
#define __NR_perf_event_open 241
|
||||
__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
|
||||
#define __NR_accept4 242
|
||||
__SYSCALL(__NR_accept4, sys_accept4)
|
||||
#define __NR_recvmmsg 243
|
||||
__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
|
||||
|
||||
/*
|
||||
* Architectures may provide up to 16 syscalls of their own
|
||||
* starting with this value.
|
||||
*/
|
||||
#define __NR_arch_specific_syscall 244
|
||||
|
||||
#define __NR_wait4 260
|
||||
__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
|
||||
#define __NR_prlimit64 261
|
||||
__SYSCALL(__NR_prlimit64, sys_prlimit64)
|
||||
#define __NR_fanotify_init 262
|
||||
__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
|
||||
#define __NR_fanotify_mark 263
|
||||
__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
|
||||
#define __NR_name_to_handle_at 264
|
||||
__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
|
||||
#define __NR_open_by_handle_at 265
|
||||
__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \
|
||||
compat_sys_open_by_handle_at)
|
||||
#define __NR_clock_adjtime 266
|
||||
__SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime)
|
||||
#define __NR_syncfs 267
|
||||
__SYSCALL(__NR_syncfs, sys_syncfs)
|
||||
#define __NR_setns 268
|
||||
__SYSCALL(__NR_setns, sys_setns)
|
||||
#define __NR_sendmmsg 269
|
||||
__SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
|
||||
#define __NR_process_vm_readv 270
|
||||
__SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
|
||||
compat_sys_process_vm_readv)
|
||||
#define __NR_process_vm_writev 271
|
||||
__SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
|
||||
compat_sys_process_vm_writev)
|
||||
#define __NR_kcmp 272
|
||||
__SYSCALL(__NR_kcmp, sys_kcmp)
|
||||
#define __NR_finit_module 273
|
||||
__SYSCALL(__NR_finit_module, sys_finit_module)
|
||||
#define __NR_sched_setattr 274
|
||||
__SYSCALL(__NR_sched_setattr, sys_sched_setattr)
|
||||
#define __NR_sched_getattr 275
|
||||
__SYSCALL(__NR_sched_getattr, sys_sched_getattr)
|
||||
#define __NR_renameat2 276
|
||||
__SYSCALL(__NR_renameat2, sys_renameat2)
|
||||
#define __NR_seccomp 277
|
||||
__SYSCALL(__NR_seccomp, sys_seccomp)
|
||||
#define __NR_getrandom 278
|
||||
__SYSCALL(__NR_getrandom, sys_getrandom)
|
||||
#define __NR_memfd_create 279
|
||||
__SYSCALL(__NR_memfd_create, sys_memfd_create)
|
||||
#define __NR_bpf 280
|
||||
__SYSCALL(__NR_bpf, sys_bpf)
|
||||
#define __NR_execveat 281
|
||||
__SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
|
||||
#define __NR_userfaultfd 282
|
||||
__SYSCALL(__NR_userfaultfd, sys_userfaultfd)
|
||||
#define __NR_membarrier 283
|
||||
__SYSCALL(__NR_membarrier, sys_membarrier)
|
||||
#define __NR_mlock2 284
|
||||
__SYSCALL(__NR_mlock2, sys_mlock2)
|
||||
#define __NR_copy_file_range 285
|
||||
__SYSCALL(__NR_copy_file_range, sys_copy_file_range)
|
||||
#define __NR_preadv2 286
|
||||
__SC_COMP(__NR_preadv2, sys_preadv2, compat_sys_preadv2)
|
||||
#define __NR_pwritev2 287
|
||||
__SC_COMP(__NR_pwritev2, sys_pwritev2, compat_sys_pwritev2)
|
||||
#define __NR_pkey_mprotect 288
|
||||
__SYSCALL(__NR_pkey_mprotect, sys_pkey_mprotect)
|
||||
#define __NR_pkey_alloc 289
|
||||
__SYSCALL(__NR_pkey_alloc, sys_pkey_alloc)
|
||||
#define __NR_pkey_free 290
|
||||
__SYSCALL(__NR_pkey_free, sys_pkey_free)
|
||||
#define __NR_statx 291
|
||||
__SYSCALL(__NR_statx, sys_statx)
|
||||
#define __NR_io_pgetevents 292
|
||||
__SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents)
|
||||
|
||||
#undef __NR_syscalls
|
||||
#define __NR_syscalls 293
|
||||
|
||||
/*
|
||||
* 32 bit systems traditionally used different
|
||||
* syscalls for off_t and loff_t arguments, while
|
||||
* 64 bit systems only need the off_t version.
|
||||
* For new 32 bit platforms, there is no need to
|
||||
* implement the old 32 bit off_t syscalls, so
|
||||
* they take different names.
|
||||
* Here we map the numbers so that both versions
|
||||
* use the same syscall table layout.
|
||||
*/
|
||||
#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
|
||||
#define __NR_fcntl __NR3264_fcntl
|
||||
#define __NR_statfs __NR3264_statfs
|
||||
#define __NR_fstatfs __NR3264_fstatfs
|
||||
#define __NR_truncate __NR3264_truncate
|
||||
#define __NR_ftruncate __NR3264_ftruncate
|
||||
#define __NR_lseek __NR3264_lseek
|
||||
#define __NR_sendfile __NR3264_sendfile
|
||||
#define __NR_newfstatat __NR3264_fstatat
|
||||
#define __NR_fstat __NR3264_fstat
|
||||
#define __NR_mmap __NR3264_mmap
|
||||
#define __NR_fadvise64 __NR3264_fadvise64
|
||||
#ifdef __NR3264_stat
|
||||
#define __NR_stat __NR3264_stat
|
||||
#define __NR_lstat __NR3264_lstat
|
||||
#endif
|
||||
#else
|
||||
#define __NR_fcntl64 __NR3264_fcntl
|
||||
#define __NR_statfs64 __NR3264_statfs
|
||||
#define __NR_fstatfs64 __NR3264_fstatfs
|
||||
#define __NR_truncate64 __NR3264_truncate
|
||||
#define __NR_ftruncate64 __NR3264_ftruncate
|
||||
#define __NR_llseek __NR3264_lseek
|
||||
#define __NR_sendfile64 __NR3264_sendfile
|
||||
#define __NR_fstatat64 __NR3264_fstatat
|
||||
#define __NR_fstat64 __NR3264_fstat
|
||||
#define __NR_mmap2 __NR3264_mmap
|
||||
#define __NR_fadvise64_64 __NR3264_fadvise64
|
||||
#ifdef __NR3264_stat
|
||||
#define __NR_stat64 __NR3264_stat
|
||||
#define __NR_lstat64 __NR3264_lstat
|
||||
#endif
|
||||
#endif
|
301
tools/include/uapi/linux/in.h
Normal file
301
tools/include/uapi/linux/in.h
Normal file
@ -0,0 +1,301 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
|
||||
/*
|
||||
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
||||
* operating system. INET is implemented using the BSD Socket
|
||||
* interface as the means of communication with the user level.
|
||||
*
|
||||
* Definitions of the Internet Protocol.
|
||||
*
|
||||
* Version: @(#)in.h 1.0.1 04/21/93
|
||||
*
|
||||
* Authors: Original taken from the GNU Project <netinet/in.h> file.
|
||||
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
#ifndef _UAPI_LINUX_IN_H
|
||||
#define _UAPI_LINUX_IN_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/libc-compat.h>
|
||||
#include <linux/socket.h>
|
||||
|
||||
#if __UAPI_DEF_IN_IPPROTO
|
||||
/* Standard well-defined IP protocols. */
|
||||
enum {
|
||||
IPPROTO_IP = 0, /* Dummy protocol for TCP */
|
||||
#define IPPROTO_IP IPPROTO_IP
|
||||
IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
|
||||
#define IPPROTO_ICMP IPPROTO_ICMP
|
||||
IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
|
||||
#define IPPROTO_IGMP IPPROTO_IGMP
|
||||
IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
|
||||
#define IPPROTO_IPIP IPPROTO_IPIP
|
||||
IPPROTO_TCP = 6, /* Transmission Control Protocol */
|
||||
#define IPPROTO_TCP IPPROTO_TCP
|
||||
IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
|
||||
#define IPPROTO_EGP IPPROTO_EGP
|
||||
IPPROTO_PUP = 12, /* PUP protocol */
|
||||
#define IPPROTO_PUP IPPROTO_PUP
|
||||
IPPROTO_UDP = 17, /* User Datagram Protocol */
|
||||
#define IPPROTO_UDP IPPROTO_UDP
|
||||
IPPROTO_IDP = 22, /* XNS IDP protocol */
|
||||
#define IPPROTO_IDP IPPROTO_IDP
|
||||
IPPROTO_TP = 29, /* SO Transport Protocol Class 4 */
|
||||
#define IPPROTO_TP IPPROTO_TP
|
||||
IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
|
||||
#define IPPROTO_DCCP IPPROTO_DCCP
|
||||
IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
|
||||
#define IPPROTO_IPV6 IPPROTO_IPV6
|
||||
IPPROTO_RSVP = 46, /* RSVP Protocol */
|
||||
#define IPPROTO_RSVP IPPROTO_RSVP
|
||||
IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
|
||||
#define IPPROTO_GRE IPPROTO_GRE
|
||||
IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
|
||||
#define IPPROTO_ESP IPPROTO_ESP
|
||||
IPPROTO_AH = 51, /* Authentication Header protocol */
|
||||
#define IPPROTO_AH IPPROTO_AH
|
||||
IPPROTO_MTP = 92, /* Multicast Transport Protocol */
|
||||
#define IPPROTO_MTP IPPROTO_MTP
|
||||
IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
|
||||
#define IPPROTO_BEETPH IPPROTO_BEETPH
|
||||
IPPROTO_ENCAP = 98, /* Encapsulation Header */
|
||||
#define IPPROTO_ENCAP IPPROTO_ENCAP
|
||||
IPPROTO_PIM = 103, /* Protocol Independent Multicast */
|
||||
#define IPPROTO_PIM IPPROTO_PIM
|
||||
IPPROTO_COMP = 108, /* Compression Header Protocol */
|
||||
#define IPPROTO_COMP IPPROTO_COMP
|
||||
IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
|
||||
#define IPPROTO_SCTP IPPROTO_SCTP
|
||||
IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
|
||||
#define IPPROTO_UDPLITE IPPROTO_UDPLITE
|
||||
IPPROTO_MPLS = 137, /* MPLS in IP (RFC 4023) */
|
||||
#define IPPROTO_MPLS IPPROTO_MPLS
|
||||
IPPROTO_RAW = 255, /* Raw IP packets */
|
||||
#define IPPROTO_RAW IPPROTO_RAW
|
||||
IPPROTO_MAX
|
||||
};
|
||||
#endif
|
||||
|
||||
#if __UAPI_DEF_IN_ADDR
|
||||
/* Internet address. */
|
||||
struct in_addr {
|
||||
__be32 s_addr;
|
||||
};
|
||||
#endif
|
||||
|
||||
#define IP_TOS 1
|
||||
#define IP_TTL 2
|
||||
#define IP_HDRINCL 3
|
||||
#define IP_OPTIONS 4
|
||||
#define IP_ROUTER_ALERT 5
|
||||
#define IP_RECVOPTS 6
|
||||
#define IP_RETOPTS 7
|
||||
#define IP_PKTINFO 8
|
||||
#define IP_PKTOPTIONS 9
|
||||
#define IP_MTU_DISCOVER 10
|
||||
#define IP_RECVERR 11
|
||||
#define IP_RECVTTL 12
|
||||
#define IP_RECVTOS 13
|
||||
#define IP_MTU 14
|
||||
#define IP_FREEBIND 15
|
||||
#define IP_IPSEC_POLICY 16
|
||||
#define IP_XFRM_POLICY 17
|
||||
#define IP_PASSSEC 18
|
||||
#define IP_TRANSPARENT 19
|
||||
|
||||
/* BSD compatibility */
|
||||
#define IP_RECVRETOPTS IP_RETOPTS
|
||||
|
||||
/* TProxy original addresses */
|
||||
#define IP_ORIGDSTADDR 20
|
||||
#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
|
||||
|
||||
#define IP_MINTTL 21
|
||||
#define IP_NODEFRAG 22
|
||||
#define IP_CHECKSUM 23
|
||||
#define IP_BIND_ADDRESS_NO_PORT 24
|
||||
#define IP_RECVFRAGSIZE 25
|
||||
|
||||
/* IP_MTU_DISCOVER values */
|
||||
#define IP_PMTUDISC_DONT 0 /* Never send DF frames */
|
||||
#define IP_PMTUDISC_WANT 1 /* Use per route hints */
|
||||
#define IP_PMTUDISC_DO 2 /* Always DF */
|
||||
#define IP_PMTUDISC_PROBE 3 /* Ignore dst pmtu */
|
||||
/* Always use interface mtu (ignores dst pmtu) but don't set DF flag.
|
||||
* Also incoming ICMP frag_needed notifications will be ignored on
|
||||
* this socket to prevent accepting spoofed ones.
|
||||
*/
|
||||
#define IP_PMTUDISC_INTERFACE 4
|
||||
/* weaker version of IP_PMTUDISC_INTERFACE, which allos packets to get
|
||||
* fragmented if they exeed the interface mtu
|
||||
*/
|
||||
#define IP_PMTUDISC_OMIT 5
|
||||
|
||||
#define IP_MULTICAST_IF 32
|
||||
#define IP_MULTICAST_TTL 33
|
||||
#define IP_MULTICAST_LOOP 34
|
||||
#define IP_ADD_MEMBERSHIP 35
|
||||
#define IP_DROP_MEMBERSHIP 36
|
||||
#define IP_UNBLOCK_SOURCE 37
|
||||
#define IP_BLOCK_SOURCE 38
|
||||
#define IP_ADD_SOURCE_MEMBERSHIP 39
|
||||
#define IP_DROP_SOURCE_MEMBERSHIP 40
|
||||
#define IP_MSFILTER 41
|
||||
#define MCAST_JOIN_GROUP 42
|
||||
#define MCAST_BLOCK_SOURCE 43
|
||||
#define MCAST_UNBLOCK_SOURCE 44
|
||||
#define MCAST_LEAVE_GROUP 45
|
||||
#define MCAST_JOIN_SOURCE_GROUP 46
|
||||
#define MCAST_LEAVE_SOURCE_GROUP 47
|
||||
#define MCAST_MSFILTER 48
|
||||
#define IP_MULTICAST_ALL 49
|
||||
#define IP_UNICAST_IF 50
|
||||
|
||||
#define MCAST_EXCLUDE 0
|
||||
#define MCAST_INCLUDE 1
|
||||
|
||||
/* These need to appear somewhere around here */
|
||||
#define IP_DEFAULT_MULTICAST_TTL 1
|
||||
#define IP_DEFAULT_MULTICAST_LOOP 1
|
||||
|
||||
/* Request struct for multicast socket ops */
|
||||
|
||||
#if __UAPI_DEF_IP_MREQ
|
||||
struct ip_mreq {
|
||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||
struct in_addr imr_interface; /* local IP address of interface */
|
||||
};
|
||||
|
||||
struct ip_mreqn {
|
||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||
struct in_addr imr_address; /* local IP address of interface */
|
||||
int imr_ifindex; /* Interface index */
|
||||
};
|
||||
|
||||
struct ip_mreq_source {
|
||||
__be32 imr_multiaddr;
|
||||
__be32 imr_interface;
|
||||
__be32 imr_sourceaddr;
|
||||
};
|
||||
|
||||
struct ip_msfilter {
|
||||
__be32 imsf_multiaddr;
|
||||
__be32 imsf_interface;
|
||||
__u32 imsf_fmode;
|
||||
__u32 imsf_numsrc;
|
||||
__be32 imsf_slist[1];
|
||||
};
|
||||
|
||||
#define IP_MSFILTER_SIZE(numsrc) \
|
||||
(sizeof(struct ip_msfilter) - sizeof(__u32) \
|
||||
+ (numsrc) * sizeof(__u32))
|
||||
|
||||
struct group_req {
|
||||
__u32 gr_interface; /* interface index */
|
||||
struct __kernel_sockaddr_storage gr_group; /* group address */
|
||||
};
|
||||
|
||||
struct group_source_req {
|
||||
__u32 gsr_interface; /* interface index */
|
||||
struct __kernel_sockaddr_storage gsr_group; /* group address */
|
||||
struct __kernel_sockaddr_storage gsr_source; /* source address */
|
||||
};
|
||||
|
||||
struct group_filter {
|
||||
__u32 gf_interface; /* interface index */
|
||||
struct __kernel_sockaddr_storage gf_group; /* multicast address */
|
||||
__u32 gf_fmode; /* filter mode */
|
||||
__u32 gf_numsrc; /* number of sources */
|
||||
struct __kernel_sockaddr_storage gf_slist[1]; /* interface index */
|
||||
};
|
||||
|
||||
#define GROUP_FILTER_SIZE(numsrc) \
|
||||
(sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \
|
||||
+ (numsrc) * sizeof(struct __kernel_sockaddr_storage))
|
||||
#endif
|
||||
|
||||
#if __UAPI_DEF_IN_PKTINFO
|
||||
struct in_pktinfo {
|
||||
int ipi_ifindex;
|
||||
struct in_addr ipi_spec_dst;
|
||||
struct in_addr ipi_addr;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Structure describing an Internet (IP) socket address. */
|
||||
#if __UAPI_DEF_SOCKADDR_IN
|
||||
#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
|
||||
struct sockaddr_in {
|
||||
__kernel_sa_family_t sin_family; /* Address family */
|
||||
__be16 sin_port; /* Port number */
|
||||
struct in_addr sin_addr; /* Internet address */
|
||||
|
||||
/* Pad to size of `struct sockaddr'. */
|
||||
unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
|
||||
sizeof(unsigned short int) - sizeof(struct in_addr)];
|
||||
};
|
||||
#define sin_zero __pad /* for BSD UNIX comp. -FvK */
|
||||
#endif
|
||||
|
||||
#if __UAPI_DEF_IN_CLASS
|
||||
/*
|
||||
* Definitions of the bits in an Internet address integer.
|
||||
* On subnets, host and network parts are found according
|
||||
* to the subnet mask, not these masks.
|
||||
*/
|
||||
#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
|
||||
#define IN_CLASSA_NET 0xff000000
|
||||
#define IN_CLASSA_NSHIFT 24
|
||||
#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
|
||||
#define IN_CLASSA_MAX 128
|
||||
|
||||
#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000)
|
||||
#define IN_CLASSB_NET 0xffff0000
|
||||
#define IN_CLASSB_NSHIFT 16
|
||||
#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
|
||||
#define IN_CLASSB_MAX 65536
|
||||
|
||||
#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000)
|
||||
#define IN_CLASSC_NET 0xffffff00
|
||||
#define IN_CLASSC_NSHIFT 8
|
||||
#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
|
||||
|
||||
#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
|
||||
#define IN_MULTICAST(a) IN_CLASSD(a)
|
||||
#define IN_MULTICAST_NET 0xF0000000
|
||||
|
||||
#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
|
||||
#define IN_BADCLASS(a) IN_EXPERIMENTAL((a))
|
||||
|
||||
/* Address to accept any incoming messages. */
|
||||
#define INADDR_ANY ((unsigned long int) 0x00000000)
|
||||
|
||||
/* Address to send to all hosts. */
|
||||
#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
|
||||
|
||||
/* Address indicating an error return. */
|
||||
#define INADDR_NONE ((unsigned long int) 0xffffffff)
|
||||
|
||||
/* Network number for local host loopback. */
|
||||
#define IN_LOOPBACKNET 127
|
||||
|
||||
/* Address to loopback in software to local host. */
|
||||
#define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */
|
||||
#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
|
||||
|
||||
/* Defines for Multicast INADDR */
|
||||
#define INADDR_UNSPEC_GROUP 0xe0000000U /* 224.0.0.0 */
|
||||
#define INADDR_ALLHOSTS_GROUP 0xe0000001U /* 224.0.0.1 */
|
||||
#define INADDR_ALLRTRS_GROUP 0xe0000002U /* 224.0.0.2 */
|
||||
#define INADDR_MAX_LOCAL_GROUP 0xe00000ffU /* 224.0.0.255 */
|
||||
#endif
|
||||
|
||||
/* <asm/byteorder.h> contains the htonl type stuff.. */
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
|
||||
#endif /* _UAPI_LINUX_IN_H */
|
@ -18,6 +18,10 @@ various perf commands with the -e option.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
-d::
|
||||
--desc::
|
||||
Print extra event descriptions. (default)
|
||||
|
||||
--no-desc::
|
||||
Don't print descriptions.
|
||||
|
||||
@ -25,11 +29,13 @@ Don't print descriptions.
|
||||
--long-desc::
|
||||
Print longer event descriptions.
|
||||
|
||||
--debug::
|
||||
Enable debugging output.
|
||||
|
||||
--details::
|
||||
Print how named events are resolved internally into perf events, and also
|
||||
any extra expressions computed by perf stat.
|
||||
|
||||
|
||||
[[EVENT_MODIFIERS]]
|
||||
EVENT MODIFIERS
|
||||
---------------
|
||||
@ -234,7 +240,7 @@ perf also supports group leader sampling using the :S specifier.
|
||||
perf record -e '{cycles,instructions}:S' ...
|
||||
perf report --group
|
||||
|
||||
Normally all events in a event group sample, but with :S only
|
||||
Normally all events in an event group sample, but with :S only
|
||||
the first event (the leader) samples, and it only reads the values of the
|
||||
other events in the group.
|
||||
|
||||
|
@ -94,7 +94,7 @@ OPTIONS
|
||||
"perf report" to view group events together.
|
||||
|
||||
--filter=<filter>::
|
||||
Event filter. This option should follow a event selector (-e) which
|
||||
Event filter. This option should follow an event selector (-e) which
|
||||
selects either tracepoint event(s) or a hardware trace PMU
|
||||
(e.g. Intel PT or CoreSight).
|
||||
|
||||
@ -153,7 +153,7 @@ OPTIONS
|
||||
|
||||
--exclude-perf::
|
||||
Don't record events issued by perf itself. This option should follow
|
||||
a event selector (-e) which selects tracepoint event(s). It adds a
|
||||
an event selector (-e) which selects tracepoint event(s). It adds a
|
||||
filter expression 'common_pid != $PERFPID' to filters. If other
|
||||
'--filter' exists, the new filter expression will be combined with
|
||||
them by '&&'.
|
||||
|
@ -54,6 +54,8 @@ endif
|
||||
|
||||
ifeq ($(SRCARCH),arm64)
|
||||
NO_PERF_REGS := 0
|
||||
NO_SYSCALL_TABLE := 0
|
||||
CFLAGS += -I$(OUTPUT)arch/arm64/include/generated
|
||||
LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
|
||||
endif
|
||||
|
||||
@ -905,8 +907,8 @@ bindir = $(abspath $(prefix)/$(bindir_relative))
|
||||
mandir = share/man
|
||||
infodir = share/info
|
||||
perfexecdir = libexec/perf-core
|
||||
perf_include_dir = lib/include/perf
|
||||
perf_examples_dir = lib/examples/perf
|
||||
perf_include_dir = lib/perf/include
|
||||
perf_examples_dir = lib/perf/examples
|
||||
sharedir = $(prefix)/share
|
||||
template_dir = share/perf-core/templates
|
||||
STRACE_GROUPS_DIR = share/perf-core/strace/groups
|
||||
|
@ -384,6 +384,8 @@ export INSTALL SHELL_PATH
|
||||
|
||||
SHELL = $(SHELL_PATH)
|
||||
|
||||
linux_uapi_dir := $(srctree)/tools/include/uapi/linux
|
||||
|
||||
beauty_outdir := $(OUTPUT)trace/beauty/generated
|
||||
beauty_ioctl_outdir := $(beauty_outdir)/ioctl
|
||||
drm_ioctl_array := $(beauty_ioctl_outdir)/drm_ioctl_array.c
|
||||
@ -431,6 +433,12 @@ kvm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/kvm_ioctl.sh
|
||||
$(kvm_ioctl_array): $(kvm_hdr_dir)/kvm.h $(kvm_ioctl_tbl)
|
||||
$(Q)$(SHELL) '$(kvm_ioctl_tbl)' $(kvm_hdr_dir) > $@
|
||||
|
||||
socket_ipproto_array := $(beauty_outdir)/socket_ipproto_array.c
|
||||
socket_ipproto_tbl := $(srctree)/tools/perf/trace/beauty/socket_ipproto.sh
|
||||
|
||||
$(socket_ipproto_array): $(linux_uapi_dir)/in.h $(socket_ipproto_tbl)
|
||||
$(Q)$(SHELL) '$(socket_ipproto_tbl)' $(linux_uapi_dir) > $@
|
||||
|
||||
vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c
|
||||
vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux
|
||||
vhost_virtio_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/vhost_virtio_ioctl.sh
|
||||
@ -566,6 +574,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc
|
||||
$(sndrv_ctl_ioctl_array) \
|
||||
$(kcmp_type_array) \
|
||||
$(kvm_ioctl_array) \
|
||||
$(socket_ipproto_array) \
|
||||
$(vhost_virtio_ioctl_array) \
|
||||
$(madvise_behavior_array) \
|
||||
$(perf_ioctl_array) \
|
||||
@ -860,6 +869,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea
|
||||
$(OUTPUT)$(sndrv_pcm_ioctl_array) \
|
||||
$(OUTPUT)$(kvm_ioctl_array) \
|
||||
$(OUTPUT)$(kcmp_type_array) \
|
||||
$(OUTPUT)$(socket_ipproto_array) \
|
||||
$(OUTPUT)$(vhost_virtio_ioctl_array) \
|
||||
$(OUTPUT)$(perf_ioctl_array) \
|
||||
$(OUTPUT)$(prctl_option_array) \
|
||||
|
@ -4,3 +4,24 @@ PERF_HAVE_DWARF_REGS := 1
|
||||
endif
|
||||
PERF_HAVE_JITDUMP := 1
|
||||
PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
|
||||
|
||||
#
|
||||
# Syscall table generation for perf
|
||||
#
|
||||
|
||||
out := $(OUTPUT)arch/arm64/include/generated/asm
|
||||
header := $(out)/syscalls.c
|
||||
sysdef := $(srctree)/tools/include/uapi/asm-generic/unistd.h
|
||||
sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/
|
||||
systbl := $(sysprf)/mksyscalltbl
|
||||
|
||||
# Create output directory if not already present
|
||||
_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
|
||||
|
||||
$(header): $(sysdef) $(systbl)
|
||||
$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(sysdef) > $@
|
||||
|
||||
clean::
|
||||
$(call QUIET_CLEAN, arm64) $(RM) $(header)
|
||||
|
||||
archheaders: $(header)
|
||||
|
62
tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
Executable file
62
tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
Executable file
@ -0,0 +1,62 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Generate system call table for perf. Derived from
|
||||
# powerpc script.
|
||||
#
|
||||
# Copyright IBM Corp. 2017
|
||||
# Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
# Changed by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
|
||||
# Changed by: Kim Phillips <kim.phillips@arm.com>
|
||||
|
||||
gcc=$1
|
||||
hostcc=$2
|
||||
input=$3
|
||||
|
||||
if ! test -r $input; then
|
||||
echo "Could not read input file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
create_table_from_c()
|
||||
{
|
||||
local sc nr last_sc
|
||||
|
||||
create_table_exe=`mktemp /tmp/create-table-XXXXXX`
|
||||
|
||||
{
|
||||
|
||||
cat <<-_EoHEADER
|
||||
#include <stdio.h>
|
||||
#define __ARCH_WANT_RENAMEAT
|
||||
#include "$input"
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
_EoHEADER
|
||||
|
||||
while read sc nr; do
|
||||
printf "%s\n" " printf(\"\\t[%d] = \\\"$sc\\\",\\n\", __NR_$sc);"
|
||||
last_sc=$sc
|
||||
done
|
||||
|
||||
printf "%s\n" " printf(\"#define SYSCALLTBL_ARM64_MAX_ID %d\\n\", __NR_$last_sc);"
|
||||
printf "}\n"
|
||||
|
||||
} | $hostcc -o $create_table_exe -x c -
|
||||
|
||||
$create_table_exe
|
||||
|
||||
rm -f $create_table_exe
|
||||
}
|
||||
|
||||
create_table()
|
||||
{
|
||||
echo "static const char *syscalltbl_arm64[] = {"
|
||||
create_table_from_c
|
||||
echo "};"
|
||||
}
|
||||
|
||||
$gcc -E -dM -x c $input \
|
||||
|sed -ne 's/^#define __NR_//p' \
|
||||
|sort -t' ' -k2 -nu \
|
||||
|create_table
|
@ -58,9 +58,13 @@ static int check_return_reg(int ra_regno, Dwarf_Frame *frame)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if return address is on the stack.
|
||||
* Check if return address is on the stack. If return address
|
||||
* is in a register (typically R0), it is yet to be saved on
|
||||
* the stack.
|
||||
*/
|
||||
if (nops != 0 || ops != NULL)
|
||||
if ((nops != 0 || ops != NULL) &&
|
||||
!(nops == 1 && ops[0].atom == DW_OP_regx &&
|
||||
ops[0].number2 == 0 && ops[0].offset == 0))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@ -246,7 +250,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain)
|
||||
if (!chain || chain->nr < 3)
|
||||
return skip_slot;
|
||||
|
||||
ip = chain->ips[2];
|
||||
ip = chain->ips[1];
|
||||
|
||||
thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
|
||||
|
||||
|
@ -102,7 +102,7 @@ const char * const kvm_skip_events[] = {
|
||||
|
||||
int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
|
||||
{
|
||||
if (strstr(cpuid, "IBM/S390")) {
|
||||
if (strstr(cpuid, "IBM")) {
|
||||
kvm->exit_reasons = sie_exit_reasons;
|
||||
kvm->exit_reasons_isa = "SIE";
|
||||
} else
|
||||
|
@ -2193,7 +2193,7 @@ static void print_cacheline(struct c2c_hists *c2c_hists,
|
||||
fprintf(out, "%s\n", bf);
|
||||
fprintf(out, " -------------------------------------------------------------\n");
|
||||
|
||||
hists__fprintf(&c2c_hists->hists, false, 0, 0, 0, out, true);
|
||||
hists__fprintf(&c2c_hists->hists, false, 0, 0, 0, out, false);
|
||||
}
|
||||
|
||||
static void print_pareto(FILE *out)
|
||||
@ -2268,7 +2268,7 @@ static void perf_c2c__hists_fprintf(FILE *out, struct perf_session *session)
|
||||
fprintf(out, "=================================================\n");
|
||||
fprintf(out, "#\n");
|
||||
|
||||
hists__fprintf(&c2c.hists.hists, true, 0, 0, 0, stdout, false);
|
||||
hists__fprintf(&c2c.hists.hists, true, 0, 0, 0, stdout, true);
|
||||
|
||||
fprintf(out, "\n");
|
||||
fprintf(out, "=================================================\n");
|
||||
@ -2349,6 +2349,9 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he)
|
||||
" s Toggle full length of symbol and source line columns \n"
|
||||
" q Return back to cacheline list \n";
|
||||
|
||||
if (!he)
|
||||
return 0;
|
||||
|
||||
/* Display compact version first. */
|
||||
c2c.symbol_full = false;
|
||||
|
||||
|
@ -696,7 +696,7 @@ static void hists__process(struct hists *hists)
|
||||
hists__output_resort(hists, NULL);
|
||||
|
||||
hists__fprintf(hists, !quiet, 0, 0, 0, stdout,
|
||||
symbol_conf.use_callchain);
|
||||
!symbol_conf.use_callchain);
|
||||
}
|
||||
|
||||
static void data__fprintf(void)
|
||||
|
@ -478,8 +478,8 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
|
||||
|
||||
hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
|
||||
hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
|
||||
symbol_conf.use_callchain ||
|
||||
symbol_conf.show_branchflag_count);
|
||||
!(symbol_conf.use_callchain ||
|
||||
symbol_conf.show_branchflag_count));
|
||||
fprintf(stdout, "\n\n");
|
||||
}
|
||||
|
||||
|
@ -296,18 +296,6 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
|
||||
return perf_evsel__open_per_thread(evsel, evsel_list->threads);
|
||||
}
|
||||
|
||||
/*
|
||||
* Does the counter have nsecs as a unit?
|
||||
*/
|
||||
static inline int nsec_counter(struct perf_evsel *evsel)
|
||||
{
|
||||
if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
|
||||
perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample __maybe_unused,
|
||||
@ -1058,34 +1046,6 @@ static void print_metric_header(void *ctx, const char *color __maybe_unused,
|
||||
fprintf(os->fh, "%*s ", metric_only_len, unit);
|
||||
}
|
||||
|
||||
static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
|
||||
{
|
||||
FILE *output = stat_config.output;
|
||||
double msecs = avg / NSEC_PER_MSEC;
|
||||
const char *fmt_v, *fmt_n;
|
||||
char name[25];
|
||||
|
||||
fmt_v = csv_output ? "%.6f%s" : "%18.6f%s";
|
||||
fmt_n = csv_output ? "%s" : "%-25s";
|
||||
|
||||
aggr_printout(evsel, id, nr);
|
||||
|
||||
scnprintf(name, sizeof(name), "%s%s",
|
||||
perf_evsel__name(evsel), csv_output ? "" : " (msec)");
|
||||
|
||||
fprintf(output, fmt_v, msecs, csv_sep);
|
||||
|
||||
if (csv_output)
|
||||
fprintf(output, "%s%s", evsel->unit, csv_sep);
|
||||
else
|
||||
fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep);
|
||||
|
||||
fprintf(output, fmt_n, name);
|
||||
|
||||
if (evsel->cgrp)
|
||||
fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
|
||||
}
|
||||
|
||||
static int first_shadow_cpu(struct perf_evsel *evsel, int id)
|
||||
{
|
||||
int i;
|
||||
@ -1241,11 +1201,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
|
||||
return;
|
||||
}
|
||||
|
||||
if (metric_only)
|
||||
/* nothing */;
|
||||
else if (nsec_counter(counter))
|
||||
nsec_printout(id, nr, counter, uval);
|
||||
else
|
||||
if (!metric_only)
|
||||
abs_printout(id, nr, counter, uval);
|
||||
|
||||
out.print_metric = pm;
|
||||
@ -1331,7 +1287,7 @@ static void collect_all_aliases(struct perf_evsel *counter,
|
||||
alias->scale != counter->scale ||
|
||||
alias->cgrp != counter->cgrp ||
|
||||
strcmp(alias->unit, counter->unit) ||
|
||||
nsec_counter(alias) != nsec_counter(counter))
|
||||
perf_evsel__is_clock(alias) != perf_evsel__is_clock(counter))
|
||||
break;
|
||||
alias->merged_stat = true;
|
||||
cb(alias, data, false);
|
||||
@ -2449,6 +2405,18 @@ static int add_default_attributes(void)
|
||||
return 0;
|
||||
|
||||
if (transaction_run) {
|
||||
/* Handle -T as -M transaction. Once platform specific metrics
|
||||
* support has been added to the json files, all archictures
|
||||
* will use this approach. To determine transaction support
|
||||
* on an architecture test for such a metric name.
|
||||
*/
|
||||
if (metricgroup__has_metric("transaction")) {
|
||||
struct option opt = { .value = &evsel_list };
|
||||
|
||||
return metricgroup__parse_groups(&opt, "transaction",
|
||||
&metric_events);
|
||||
}
|
||||
|
||||
if (pmu_have_event("cpu", "cycles-ct") &&
|
||||
pmu_have_event("cpu", "el-start"))
|
||||
err = parse_events(evsel_list, transaction_attrs,
|
||||
|
@ -307,7 +307,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
|
||||
hists__output_recalc_col_len(hists, top->print_entries - printed);
|
||||
putchar('\n');
|
||||
hists__fprintf(hists, false, top->print_entries - printed, win_width,
|
||||
top->min_percent, stdout, symbol_conf.use_callchain);
|
||||
top->min_percent, stdout, !symbol_conf.use_callchain);
|
||||
}
|
||||
|
||||
static void prompt_integer(int *target, const char *msg)
|
||||
|
@ -291,7 +291,7 @@ size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const cha
|
||||
{
|
||||
int idx = val - sa->offset;
|
||||
|
||||
if (idx < 0 || idx >= sa->nr_entries)
|
||||
if (idx < 0 || idx >= sa->nr_entries || sa->entries[idx] == NULL)
|
||||
return scnprintf(bf, size, intfmt, val);
|
||||
|
||||
return scnprintf(bf, size, "%s", sa->entries[idx]);
|
||||
@ -761,10 +761,12 @@ static struct syscall_fmt {
|
||||
.arg = { [0] = STRARRAY(resource, rlimit_resources), }, },
|
||||
{ .name = "socket",
|
||||
.arg = { [0] = STRARRAY(family, socket_families),
|
||||
[1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, }, },
|
||||
[1] = { .scnprintf = SCA_SK_TYPE, /* type */ },
|
||||
[2] = { .scnprintf = SCA_SK_PROTO, /* protocol */ }, }, },
|
||||
{ .name = "socketpair",
|
||||
.arg = { [0] = STRARRAY(family, socket_families),
|
||||
[1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, }, },
|
||||
[1] = { .scnprintf = SCA_SK_TYPE, /* type */ },
|
||||
[2] = { .scnprintf = SCA_SK_PROTO, /* protocol */ }, }, },
|
||||
{ .name = "stat", .alias = "newstat", },
|
||||
{ .name = "statx",
|
||||
.arg = { [0] = { .scnprintf = SCA_FDAT, /* fdat */ },
|
||||
@ -2990,6 +2992,7 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
|
||||
|
||||
if (trace__validate_ev_qualifier(trace))
|
||||
goto out;
|
||||
trace->trace_syscalls = true;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
@ -3045,7 +3048,7 @@ int cmd_trace(int argc, const char **argv)
|
||||
},
|
||||
.output = stderr,
|
||||
.show_comm = true,
|
||||
.trace_syscalls = true,
|
||||
.trace_syscalls = false,
|
||||
.kernel_syscallchains = false,
|
||||
.max_stack = UINT_MAX,
|
||||
};
|
||||
@ -3191,13 +3194,7 @@ int cmd_trace(int argc, const char **argv)
|
||||
|
||||
if (!trace.trace_syscalls && !trace.trace_pgfaults &&
|
||||
trace.evlist->nr_entries == 0 /* Was --events used? */) {
|
||||
pr_err("Please specify something to trace.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!trace.trace_syscalls && trace.ev_qualifier) {
|
||||
pr_err("The -e option can't be used with --no-syscalls.\n");
|
||||
goto out;
|
||||
trace.trace_syscalls = true;
|
||||
}
|
||||
|
||||
if (output_name != NULL) {
|
||||
|
@ -7,6 +7,7 @@ include/uapi/drm/i915_drm.h
|
||||
include/uapi/linux/fcntl.h
|
||||
include/uapi/linux/kcmp.h
|
||||
include/uapi/linux/kvm.h
|
||||
include/uapi/linux/in.h
|
||||
include/uapi/linux/perf_event.h
|
||||
include/uapi/linux/prctl.h
|
||||
include/uapi/linux/sched.h
|
||||
@ -35,6 +36,7 @@ arch/s390/include/uapi/asm/ptrace.h
|
||||
arch/s390/include/uapi/asm/sie.h
|
||||
arch/arm/include/uapi/asm/kvm.h
|
||||
arch/arm64/include/uapi/asm/kvm.h
|
||||
arch/arm64/include/uapi/asm/unistd.h
|
||||
arch/alpha/include/uapi/asm/errno.h
|
||||
arch/mips/include/asm/errno.h
|
||||
arch/mips/include/uapi/asm/errno.h
|
||||
@ -53,6 +55,7 @@ include/uapi/asm-generic/errno.h
|
||||
include/uapi/asm-generic/errno-base.h
|
||||
include/uapi/asm-generic/ioctls.h
|
||||
include/uapi/asm-generic/mman-common.h
|
||||
include/uapi/asm-generic/unistd.h
|
||||
'
|
||||
|
||||
check_2 () {
|
||||
|
@ -1,6 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#ifndef _PERF_BPF_H
|
||||
#define _PERF_BPF_H
|
||||
|
||||
#include <uapi/linux/bpf.h>
|
||||
|
||||
#define SEC(NAME) __attribute__((section(NAME), used))
|
||||
|
||||
#define probe(function, vars) \
|
||||
|
@ -25,7 +25,9 @@ static inline unsigned long long rdclock(void)
|
||||
return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
|
||||
}
|
||||
|
||||
#ifndef MAX_NR_CPUS
|
||||
#define MAX_NR_CPUS 1024
|
||||
#endif
|
||||
|
||||
extern const char *input_name;
|
||||
extern bool perf_host, perf_guest;
|
||||
|
@ -11,6 +11,21 @@
|
||||
{
|
||||
"ArchStdEvent": "L1D_CACHE_REFILL_WR",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "L1D_CACHE_REFILL_INNER",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "L1D_CACHE_REFILL_OUTER",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "L1D_CACHE_WB_VICTIM",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "L1D_CACHE_WB_CLEAN",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "L1D_CACHE_INVAL",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "L1D_TLB_REFILL_RD",
|
||||
},
|
||||
@ -23,10 +38,76 @@
|
||||
{
|
||||
"ArchStdEvent": "L1D_TLB_WR",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "L2D_TLB_REFILL_RD",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "L2D_TLB_REFILL_WR",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "L2D_TLB_RD",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "L2D_TLB_WR",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "BUS_ACCESS_RD",
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "BUS_ACCESS_WR",
|
||||
}
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "MEM_ACCESS_RD",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "MEM_ACCESS_WR",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "UNALIGNED_LD_SPEC",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "UNALIGNED_ST_SPEC",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "UNALIGNED_LDST_SPEC",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_UNDEF",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_SVC",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_PABORT",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_DABORT",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_IRQ",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_FIQ",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_SMC",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_HVC",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_TRAP_PABORT",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_TRAP_DABORT",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_TRAP_OTHER",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_TRAP_IRQ",
|
||||
},
|
||||
{
|
||||
"ArchStdEvent": "EXC_TRAP_FIQ",
|
||||
}
|
||||
]
|
||||
|
@ -1,71 +1,83 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "0",
|
||||
"EventName": "CPU_CYCLES",
|
||||
"BriefDescription": "CPU Cycles",
|
||||
"PublicDescription": "Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "1",
|
||||
"EventName": "INSTRUCTIONS",
|
||||
"BriefDescription": "Instructions",
|
||||
"PublicDescription": "Instruction Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "2",
|
||||
"EventName": "L1I_DIR_WRITES",
|
||||
"BriefDescription": "L1I Directory Writes",
|
||||
"PublicDescription": "Level-1 I-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "3",
|
||||
"EventName": "L1I_PENALTY_CYCLES",
|
||||
"BriefDescription": "L1I Penalty Cycles",
|
||||
"PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "4",
|
||||
"EventName": "L1D_DIR_WRITES",
|
||||
"BriefDescription": "L1D Directory Writes",
|
||||
"PublicDescription": "Level-1 D-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "5",
|
||||
"EventName": "L1D_PENALTY_CYCLES",
|
||||
"BriefDescription": "L1D Penalty Cycles",
|
||||
"PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "32",
|
||||
"EventName": "PROBLEM_STATE_CPU_CYCLES",
|
||||
"BriefDescription": "Problem-State CPU Cycles",
|
||||
"PublicDescription": "Problem-State Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "33",
|
||||
"EventName": "PROBLEM_STATE_INSTRUCTIONS",
|
||||
"BriefDescription": "Problem-State Instructions",
|
||||
"PublicDescription": "Problem-State Instruction Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "34",
|
||||
"EventName": "PROBLEM_STATE_L1I_DIR_WRITES",
|
||||
"BriefDescription": "Problem-State L1I Directory Writes",
|
||||
"PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "35",
|
||||
"EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES",
|
||||
"BriefDescription": "Problem-State L1I Penalty Cycles",
|
||||
"PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "36",
|
||||
"EventName": "PROBLEM_STATE_L1D_DIR_WRITES",
|
||||
"BriefDescription": "Problem-State L1D Directory Writes",
|
||||
"PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "37",
|
||||
"EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES",
|
||||
"BriefDescription": "Problem-State L1D Penalty Cycles",
|
||||
|
@ -1,95 +1,111 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "64",
|
||||
"EventName": "PRNG_FUNCTIONS",
|
||||
"BriefDescription": "PRNG Functions",
|
||||
"PublicDescription": "Total number of the PRNG functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "65",
|
||||
"EventName": "PRNG_CYCLES",
|
||||
"BriefDescription": "PRNG Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "66",
|
||||
"EventName": "PRNG_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "PRNG Blocked Functions",
|
||||
"PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "67",
|
||||
"EventName": "PRNG_BLOCKED_CYCLES",
|
||||
"BriefDescription": "PRNG Blocked Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "68",
|
||||
"EventName": "SHA_FUNCTIONS",
|
||||
"BriefDescription": "SHA Functions",
|
||||
"PublicDescription": "Total number of SHA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "69",
|
||||
"EventName": "SHA_CYCLES",
|
||||
"BriefDescription": "SHA Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "70",
|
||||
"EventName": "SHA_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "SHA Blocked Functions",
|
||||
"PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "71",
|
||||
"EventName": "SHA_BLOCKED_CYCLES",
|
||||
"BriefDescription": "SHA Bloced Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "72",
|
||||
"EventName": "DEA_FUNCTIONS",
|
||||
"BriefDescription": "DEA Functions",
|
||||
"PublicDescription": "Total number of the DEA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "73",
|
||||
"EventName": "DEA_CYCLES",
|
||||
"BriefDescription": "DEA Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "74",
|
||||
"EventName": "DEA_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "DEA Blocked Functions",
|
||||
"PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "75",
|
||||
"EventName": "DEA_BLOCKED_CYCLES",
|
||||
"BriefDescription": "DEA Blocked Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "76",
|
||||
"EventName": "AES_FUNCTIONS",
|
||||
"BriefDescription": "AES Functions",
|
||||
"PublicDescription": "Total number of AES functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "77",
|
||||
"EventName": "AES_CYCLES",
|
||||
"BriefDescription": "AES Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "78",
|
||||
"EventName": "AES_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "AES Blocked Functions",
|
||||
"PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "79",
|
||||
"EventName": "AES_BLOCKED_CYCLES",
|
||||
"BriefDescription": "AES Blocked Cycles",
|
||||
|
@ -1,107 +1,125 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "128",
|
||||
"EventName": "L1I_L2_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I L2 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from the Level-2 (L1.5) cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "129",
|
||||
"EventName": "L1D_L2_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D L2 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from the Level-2 (L1.5) cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "130",
|
||||
"EventName": "L1I_L3_LOCAL_WRITES",
|
||||
"BriefDescription": "L1I L3 Local Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 I-Cache directory where the installed cache line was sourced from the Level-3 cache that is on the same book as the Instruction cache (Local L2 cache)"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "131",
|
||||
"EventName": "L1D_L3_LOCAL_WRITES",
|
||||
"BriefDescription": "L1D L3 Local Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache directory where the installtion cache line was source from the Level-3 cache that is on the same book as the Data cache (Local L2 cache)"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "132",
|
||||
"EventName": "L1I_L3_REMOTE_WRITES",
|
||||
"BriefDescription": "L1I L3 Remote Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 I-Cache directory where the installed cache line was sourced from a Level-3 cache that is not on the same book as the Instruction cache (Remote L2 cache)"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "133",
|
||||
"EventName": "L1D_L3_REMOTE_WRITES",
|
||||
"BriefDescription": "L1D L3 Remote Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from a Level-3 cache that is not on the same book as the Data cache (Remote L2 cache)"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "134",
|
||||
"EventName": "L1D_LMEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Local Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "135",
|
||||
"EventName": "L1I_LMEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Local Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 I-Cache where the installed cache line was sourced from memory that is attached to the s ame book as the Instruction cache (Local Memory)"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "136",
|
||||
"EventName": "L1D_RO_EXCL_WRITES",
|
||||
"BriefDescription": "L1D Read-only Exclusive Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "137",
|
||||
"EventName": "L1I_CACHELINE_INVALIDATES",
|
||||
"BriefDescription": "L1I Cacheline Invalidates",
|
||||
"PublicDescription": "A cache line in the Level-1 I-Cache has been invalidated by a store on the same CPU as the Level-1 I-Cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "138",
|
||||
"EventName": "ITLB1_WRITES",
|
||||
"BriefDescription": "ITLB1 Writes",
|
||||
"PublicDescription": "A translation entry has been written into the Level-1 Instruction Translation Lookaside Buffer"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "139",
|
||||
"EventName": "DTLB1_WRITES",
|
||||
"BriefDescription": "DTLB1 Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "140",
|
||||
"EventName": "TLB2_PTE_WRITES",
|
||||
"BriefDescription": "TLB2 PTE Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "141",
|
||||
"EventName": "TLB2_CRSTE_WRITES",
|
||||
"BriefDescription": "TLB2 CRSTE Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "142",
|
||||
"EventName": "TLB2_CRSTE_HPAGE_WRITES",
|
||||
"BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "145",
|
||||
"EventName": "ITLB1_MISSES",
|
||||
"BriefDescription": "ITLB1 Misses",
|
||||
"PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle an ITLB1 miss is in progress"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "146",
|
||||
"EventName": "DTLB1_MISSES",
|
||||
"BriefDescription": "DTLB1 Misses",
|
||||
"PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle an DTLB1 miss is in progress"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "147",
|
||||
"EventName": "L2C_STORES_SENT",
|
||||
"BriefDescription": "L2C Stores Sent",
|
||||
|
@ -1,71 +1,83 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "0",
|
||||
"EventName": "CPU_CYCLES",
|
||||
"BriefDescription": "CPU Cycles",
|
||||
"PublicDescription": "Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "1",
|
||||
"EventName": "INSTRUCTIONS",
|
||||
"BriefDescription": "Instructions",
|
||||
"PublicDescription": "Instruction Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "2",
|
||||
"EventName": "L1I_DIR_WRITES",
|
||||
"BriefDescription": "L1I Directory Writes",
|
||||
"PublicDescription": "Level-1 I-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "3",
|
||||
"EventName": "L1I_PENALTY_CYCLES",
|
||||
"BriefDescription": "L1I Penalty Cycles",
|
||||
"PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "4",
|
||||
"EventName": "L1D_DIR_WRITES",
|
||||
"BriefDescription": "L1D Directory Writes",
|
||||
"PublicDescription": "Level-1 D-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "5",
|
||||
"EventName": "L1D_PENALTY_CYCLES",
|
||||
"BriefDescription": "L1D Penalty Cycles",
|
||||
"PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "32",
|
||||
"EventName": "PROBLEM_STATE_CPU_CYCLES",
|
||||
"BriefDescription": "Problem-State CPU Cycles",
|
||||
"PublicDescription": "Problem-State Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "33",
|
||||
"EventName": "PROBLEM_STATE_INSTRUCTIONS",
|
||||
"BriefDescription": "Problem-State Instructions",
|
||||
"PublicDescription": "Problem-State Instruction Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "34",
|
||||
"EventName": "PROBLEM_STATE_L1I_DIR_WRITES",
|
||||
"BriefDescription": "Problem-State L1I Directory Writes",
|
||||
"PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "35",
|
||||
"EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES",
|
||||
"BriefDescription": "Problem-State L1I Penalty Cycles",
|
||||
"PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "36",
|
||||
"EventName": "PROBLEM_STATE_L1D_DIR_WRITES",
|
||||
"BriefDescription": "Problem-State L1D Directory Writes",
|
||||
"PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "37",
|
||||
"EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES",
|
||||
"BriefDescription": "Problem-State L1D Penalty Cycles",
|
||||
|
@ -1,95 +1,111 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "64",
|
||||
"EventName": "PRNG_FUNCTIONS",
|
||||
"BriefDescription": "PRNG Functions",
|
||||
"PublicDescription": "Total number of the PRNG functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "65",
|
||||
"EventName": "PRNG_CYCLES",
|
||||
"BriefDescription": "PRNG Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "66",
|
||||
"EventName": "PRNG_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "PRNG Blocked Functions",
|
||||
"PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "67",
|
||||
"EventName": "PRNG_BLOCKED_CYCLES",
|
||||
"BriefDescription": "PRNG Blocked Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "68",
|
||||
"EventName": "SHA_FUNCTIONS",
|
||||
"BriefDescription": "SHA Functions",
|
||||
"PublicDescription": "Total number of SHA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "69",
|
||||
"EventName": "SHA_CYCLES",
|
||||
"BriefDescription": "SHA Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "70",
|
||||
"EventName": "SHA_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "SHA Blocked Functions",
|
||||
"PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "71",
|
||||
"EventName": "SHA_BLOCKED_CYCLES",
|
||||
"BriefDescription": "SHA Bloced Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "72",
|
||||
"EventName": "DEA_FUNCTIONS",
|
||||
"BriefDescription": "DEA Functions",
|
||||
"PublicDescription": "Total number of the DEA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "73",
|
||||
"EventName": "DEA_CYCLES",
|
||||
"BriefDescription": "DEA Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "74",
|
||||
"EventName": "DEA_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "DEA Blocked Functions",
|
||||
"PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "75",
|
||||
"EventName": "DEA_BLOCKED_CYCLES",
|
||||
"BriefDescription": "DEA Blocked Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "76",
|
||||
"EventName": "AES_FUNCTIONS",
|
||||
"BriefDescription": "AES Functions",
|
||||
"PublicDescription": "Total number of AES functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "77",
|
||||
"EventName": "AES_CYCLES",
|
||||
"BriefDescription": "AES Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "78",
|
||||
"EventName": "AES_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "AES Blocked Functions",
|
||||
"PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "79",
|
||||
"EventName": "AES_BLOCKED_CYCLES",
|
||||
"BriefDescription": "AES Blocked Cycles",
|
||||
|
@ -1,335 +1,391 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "128",
|
||||
"EventName": "L1D_RO_EXCL_WRITES",
|
||||
"BriefDescription": "L1D Read-only Exclusive Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line."
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "129",
|
||||
"EventName": "DTLB1_WRITES",
|
||||
"BriefDescription": "DTLB1 Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "130",
|
||||
"EventName": "DTLB1_MISSES",
|
||||
"BriefDescription": "DTLB1 Misses",
|
||||
"PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress."
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "131",
|
||||
"EventName": "DTLB1_HPAGE_WRITES",
|
||||
"BriefDescription": "DTLB1 One-Megabyte Page Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "132",
|
||||
"EventName": "DTLB1_GPAGE_WRITES",
|
||||
"BriefDescription": "DTLB1 Two-Gigabyte Page Writes",
|
||||
"PublicDescription": "Counter:132 Name:DTLB1_GPAGE_WRITES A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a two-gigabyte page."
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "133",
|
||||
"EventName": "L1D_L2D_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D L2D Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "134",
|
||||
"EventName": "ITLB1_WRITES",
|
||||
"BriefDescription": "ITLB1 Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "135",
|
||||
"EventName": "ITLB1_MISSES",
|
||||
"BriefDescription": "ITLB1 Misses",
|
||||
"PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle an ITLB1 miss is in progress"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "136",
|
||||
"EventName": "L1I_L2I_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I L2I Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "137",
|
||||
"EventName": "TLB2_PTE_WRITES",
|
||||
"BriefDescription": "TLB2 PTE Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "138",
|
||||
"EventName": "TLB2_CRSTE_HPAGE_WRITES",
|
||||
"BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Combined Region Segment Table Entry arrays for a one-megabyte large page translation"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "139",
|
||||
"EventName": "TLB2_CRSTE_WRITES",
|
||||
"BriefDescription": "TLB2 CRSTE Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Combined Region Segment Table Entry arrays"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "140",
|
||||
"EventName": "TX_C_TEND",
|
||||
"BriefDescription": "Completed TEND instructions in constrained TX mode",
|
||||
"PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "141",
|
||||
"EventName": "TX_NC_TEND",
|
||||
"BriefDescription": "Completed TEND instructions in non-constrained TX mode",
|
||||
"PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "143",
|
||||
"EventName": "L1C_TLB1_MISSES",
|
||||
"BriefDescription": "L1C TLB1 Misses",
|
||||
"PublicDescription": "Increments by one for any cycle where a Level-1 cache or Level-1 TLB miss is in progress."
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "144",
|
||||
"EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "145",
|
||||
"EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "146",
|
||||
"EventName": "L1D_ONNODE_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Node L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "147",
|
||||
"EventName": "L1D_ONNODE_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D On-Node L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "148",
|
||||
"EventName": "L1D_ONNODE_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Node L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "149",
|
||||
"EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Drawer L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "150",
|
||||
"EventName": "L1D_ONDRAWER_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D On-Drawer L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "151",
|
||||
"EventName": "L1D_ONDRAWER_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Drawer L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "152",
|
||||
"EventName": "L1D_OFFDRAWER_SCOL_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Drawer Same-Column L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "153",
|
||||
"EventName": "L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D Off-Drawer Same-Column L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "154",
|
||||
"EventName": "L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Drawer Same-Column L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "155",
|
||||
"EventName": "L1D_OFFDRAWER_FCOL_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "156",
|
||||
"EventName": "L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "157",
|
||||
"EventName": "L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "158",
|
||||
"EventName": "L1D_ONNODE_MEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Node Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Node memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "159",
|
||||
"EventName": "L1D_ONDRAWER_MEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Drawer Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "160",
|
||||
"EventName": "L1D_OFFDRAWER_MEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Drawer Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "161",
|
||||
"EventName": "L1D_ONCHIP_MEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Chip Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "162",
|
||||
"EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "163",
|
||||
"EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "164",
|
||||
"EventName": "L1I_ONNODE_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Chip L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "165",
|
||||
"EventName": "L1I_ONNODE_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I On-Node L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "166",
|
||||
"EventName": "L1I_ONNODE_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Node L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "167",
|
||||
"EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Drawer L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "168",
|
||||
"EventName": "L1I_ONDRAWER_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I On-Drawer L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "169",
|
||||
"EventName": "L1I_ONDRAWER_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Drawer L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "170",
|
||||
"EventName": "L1I_OFFDRAWER_SCOL_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Drawer Same-Column L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "171",
|
||||
"EventName": "L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I Off-Drawer Same-Column L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "172",
|
||||
"EventName": "L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Drawer Same-Column L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "173",
|
||||
"EventName": "L1I_OFFDRAWER_FCOL_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Drawer Far-Column L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "174",
|
||||
"EventName": "L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I Off-Drawer Far-Column L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "175",
|
||||
"EventName": "L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Drawer Far-Column L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "176",
|
||||
"EventName": "L1I_ONNODE_MEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Node Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Node memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "177",
|
||||
"EventName": "L1I_ONDRAWER_MEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Drawer Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "178",
|
||||
"EventName": "L1I_OFFDRAWER_MEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Drawer Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "179",
|
||||
"EventName": "L1I_ONCHIP_MEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Chip Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Chip memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "218",
|
||||
"EventName": "TX_NC_TABORT",
|
||||
"BriefDescription": "Aborted transactions in non-constrained TX mode",
|
||||
"PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "219",
|
||||
"EventName": "TX_C_TABORT_NO_SPECIAL",
|
||||
"BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic",
|
||||
"PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "220",
|
||||
"EventName": "TX_C_TABORT_SPECIAL",
|
||||
"BriefDescription": "Aborted transactions in constrained TX mode using special completion logic",
|
||||
"PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "448",
|
||||
"EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE",
|
||||
"BriefDescription": "Cycle count with one thread active",
|
||||
"PublicDescription": "Cycle count with one thread active"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "449",
|
||||
"EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE",
|
||||
"BriefDescription": "Cycle count with two threads active",
|
||||
|
7
tools/perf/pmu-events/arch/s390/cf_z13/transaction.json
Normal file
7
tools/perf/pmu-events/arch/s390/cf_z13/transaction.json
Normal file
@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"BriefDescription": "Transaction count",
|
||||
"MetricName": "transaction",
|
||||
"MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL"
|
||||
}
|
||||
]
|
@ -1,47 +1,55 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "0",
|
||||
"EventName": "CPU_CYCLES",
|
||||
"BriefDescription": "CPU Cycles",
|
||||
"PublicDescription": "Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "1",
|
||||
"EventName": "INSTRUCTIONS",
|
||||
"BriefDescription": "Instructions",
|
||||
"PublicDescription": "Instruction Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "2",
|
||||
"EventName": "L1I_DIR_WRITES",
|
||||
"BriefDescription": "L1I Directory Writes",
|
||||
"PublicDescription": "Level-1 I-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "3",
|
||||
"EventName": "L1I_PENALTY_CYCLES",
|
||||
"BriefDescription": "L1I Penalty Cycles",
|
||||
"PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "4",
|
||||
"EventName": "L1D_DIR_WRITES",
|
||||
"BriefDescription": "L1D Directory Writes",
|
||||
"PublicDescription": "Level-1 D-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "5",
|
||||
"EventName": "L1D_PENALTY_CYCLES",
|
||||
"BriefDescription": "L1D Penalty Cycles",
|
||||
"PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "32",
|
||||
"EventName": "PROBLEM_STATE_CPU_CYCLES",
|
||||
"BriefDescription": "Problem-State CPU Cycles",
|
||||
"PublicDescription": "Problem-State Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "33",
|
||||
"EventName": "PROBLEM_STATE_INSTRUCTIONS",
|
||||
"BriefDescription": "Problem-State Instructions",
|
||||
|
@ -1,95 +1,111 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "64",
|
||||
"EventName": "PRNG_FUNCTIONS",
|
||||
"BriefDescription": "PRNG Functions",
|
||||
"PublicDescription": "Total number of the PRNG functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "65",
|
||||
"EventName": "PRNG_CYCLES",
|
||||
"BriefDescription": "PRNG Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "66",
|
||||
"EventName": "PRNG_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "PRNG Blocked Functions",
|
||||
"PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "67",
|
||||
"EventName": "PRNG_BLOCKED_CYCLES",
|
||||
"BriefDescription": "PRNG Blocked Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "68",
|
||||
"EventName": "SHA_FUNCTIONS",
|
||||
"BriefDescription": "SHA Functions",
|
||||
"PublicDescription": "Total number of SHA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "69",
|
||||
"EventName": "SHA_CYCLES",
|
||||
"BriefDescription": "SHA Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "70",
|
||||
"EventName": "SHA_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "SHA Blocked Functions",
|
||||
"PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "71",
|
||||
"EventName": "SHA_BLOCKED_CYCLES",
|
||||
"BriefDescription": "SHA Bloced Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "72",
|
||||
"EventName": "DEA_FUNCTIONS",
|
||||
"BriefDescription": "DEA Functions",
|
||||
"PublicDescription": "Total number of the DEA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "73",
|
||||
"EventName": "DEA_CYCLES",
|
||||
"BriefDescription": "DEA Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "74",
|
||||
"EventName": "DEA_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "DEA Blocked Functions",
|
||||
"PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "75",
|
||||
"EventName": "DEA_BLOCKED_CYCLES",
|
||||
"BriefDescription": "DEA Blocked Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "76",
|
||||
"EventName": "AES_FUNCTIONS",
|
||||
"BriefDescription": "AES Functions",
|
||||
"PublicDescription": "Total number of AES functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "77",
|
||||
"EventName": "AES_CYCLES",
|
||||
"BriefDescription": "AES Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "78",
|
||||
"EventName": "AES_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "AES Blocked Functions",
|
||||
"PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "79",
|
||||
"EventName": "AES_BLOCKED_CYCLES",
|
||||
"BriefDescription": "AES Blocked Cycles",
|
||||
|
@ -1,317 +1,370 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "128",
|
||||
"EventName": "L1D_RO_EXCL_WRITES",
|
||||
"BriefDescription": "L1D Read-only Exclusive Writes",
|
||||
"PublicDescription": "Counter:128 Name:L1D_RO_EXCL_WRITES A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "129",
|
||||
"EventName": "DTLB2_WRITES",
|
||||
"BriefDescription": "DTLB2 Writes",
|
||||
"PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "130",
|
||||
"EventName": "DTLB2_MISSES",
|
||||
"BriefDescription": "DTLB2 Misses",
|
||||
"PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "131",
|
||||
"EventName": "DTLB2_HPAGE_WRITES",
|
||||
"BriefDescription": "DTLB2 One-Megabyte Page Writes",
|
||||
"PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "132",
|
||||
"EventName": "DTLB2_GPAGE_WRITES",
|
||||
"BriefDescription": "DTLB2 Two-Gigabyte Page Writes",
|
||||
"PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "133",
|
||||
"EventName": "L1D_L2D_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D L2D Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "134",
|
||||
"EventName": "ITLB2_WRITES",
|
||||
"BriefDescription": "ITLB2 Writes",
|
||||
"PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "135",
|
||||
"EventName": "ITLB2_MISSES",
|
||||
"BriefDescription": "ITLB2 Misses",
|
||||
"PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "136",
|
||||
"EventName": "L1I_L2I_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I L2I Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "137",
|
||||
"EventName": "TLB2_PTE_WRITES",
|
||||
"BriefDescription": "TLB2 PTE Writes",
|
||||
"PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "138",
|
||||
"EventName": "TLB2_CRSTE_WRITES",
|
||||
"BriefDescription": "TLB2 CRSTE Writes",
|
||||
"PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "139",
|
||||
"EventName": "TLB2_ENGINES_BUSY",
|
||||
"BriefDescription": "TLB2 Engines Busy",
|
||||
"PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "140",
|
||||
"EventName": "TX_C_TEND",
|
||||
"BriefDescription": "Completed TEND instructions in constrained TX mode",
|
||||
"PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "141",
|
||||
"EventName": "TX_NC_TEND",
|
||||
"BriefDescription": "Completed TEND instructions in non-constrained TX mode",
|
||||
"PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "143",
|
||||
"EventName": "L1C_TLB2_MISSES",
|
||||
"BriefDescription": "L1C TLB2 Misses",
|
||||
"PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "144",
|
||||
"EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "145",
|
||||
"EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Chip Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "146",
|
||||
"EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "147",
|
||||
"EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Cluster L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "148",
|
||||
"EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Cluster Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "149",
|
||||
"EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "150",
|
||||
"EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Cluster L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "151",
|
||||
"EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Cluster Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "152",
|
||||
"EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "153",
|
||||
"EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Drawer L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "154",
|
||||
"EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Drawer Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "155",
|
||||
"EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "156",
|
||||
"EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Drawer L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "157",
|
||||
"EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Drawer L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "158",
|
||||
"EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO",
|
||||
"BriefDescription": "L1D On-Chip L3 Sourced Writes read-only",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "162",
|
||||
"EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "163",
|
||||
"EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Chip Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "164",
|
||||
"EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "165",
|
||||
"EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Cluster L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "166",
|
||||
"EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Cluster Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "167",
|
||||
"EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "168",
|
||||
"EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Cluster L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "169",
|
||||
"EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Cluster Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "170",
|
||||
"EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "171",
|
||||
"EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Drawer L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "172",
|
||||
"EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Drawer Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "173",
|
||||
"EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "174",
|
||||
"EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Drawer L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "175",
|
||||
"EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Drawer L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "224",
|
||||
"EventName": "BCD_DFP_EXECUTION_SLOTS",
|
||||
"BriefDescription": "BCD DFP Execution Slots",
|
||||
"PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "225",
|
||||
"EventName": "VX_BCD_EXECUTION_SLOTS",
|
||||
"BriefDescription": "VX BCD Execution Slots",
|
||||
"PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "226",
|
||||
"EventName": "DECIMAL_INSTRUCTIONS",
|
||||
"BriefDescription": "Decimal Instructions",
|
||||
"PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "232",
|
||||
"EventName": "LAST_HOST_TRANSLATIONS",
|
||||
"BriefDescription": "Last host translation done",
|
||||
"PublicDescription": "Last Host Translation done"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "243",
|
||||
"EventName": "TX_NC_TABORT",
|
||||
"BriefDescription": "Aborted transactions in non-constrained TX mode",
|
||||
"PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "244",
|
||||
"EventName": "TX_C_TABORT_NO_SPECIAL",
|
||||
"BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic",
|
||||
"PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "245",
|
||||
"EventName": "TX_C_TABORT_SPECIAL",
|
||||
"BriefDescription": "Aborted transactions in constrained TX mode using special completion logic",
|
||||
"PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "448",
|
||||
"EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE",
|
||||
"BriefDescription": "Cycle count with one thread active",
|
||||
"PublicDescription": "Cycle count with one thread active"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "449",
|
||||
"EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE",
|
||||
"BriefDescription": "Cycle count with two threads active",
|
||||
|
7
tools/perf/pmu-events/arch/s390/cf_z14/transaction.json
Normal file
7
tools/perf/pmu-events/arch/s390/cf_z14/transaction.json
Normal file
@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"BriefDescription": "Transaction count",
|
||||
"MetricName": "transaction",
|
||||
"MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL"
|
||||
}
|
||||
]
|
@ -1,71 +1,83 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "0",
|
||||
"EventName": "CPU_CYCLES",
|
||||
"BriefDescription": "CPU Cycles",
|
||||
"PublicDescription": "Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "1",
|
||||
"EventName": "INSTRUCTIONS",
|
||||
"BriefDescription": "Instructions",
|
||||
"PublicDescription": "Instruction Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "2",
|
||||
"EventName": "L1I_DIR_WRITES",
|
||||
"BriefDescription": "L1I Directory Writes",
|
||||
"PublicDescription": "Level-1 I-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "3",
|
||||
"EventName": "L1I_PENALTY_CYCLES",
|
||||
"BriefDescription": "L1I Penalty Cycles",
|
||||
"PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "4",
|
||||
"EventName": "L1D_DIR_WRITES",
|
||||
"BriefDescription": "L1D Directory Writes",
|
||||
"PublicDescription": "Level-1 D-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "5",
|
||||
"EventName": "L1D_PENALTY_CYCLES",
|
||||
"BriefDescription": "L1D Penalty Cycles",
|
||||
"PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "32",
|
||||
"EventName": "PROBLEM_STATE_CPU_CYCLES",
|
||||
"BriefDescription": "Problem-State CPU Cycles",
|
||||
"PublicDescription": "Problem-State Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "33",
|
||||
"EventName": "PROBLEM_STATE_INSTRUCTIONS",
|
||||
"BriefDescription": "Problem-State Instructions",
|
||||
"PublicDescription": "Problem-State Instruction Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "34",
|
||||
"EventName": "PROBLEM_STATE_L1I_DIR_WRITES",
|
||||
"BriefDescription": "Problem-State L1I Directory Writes",
|
||||
"PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "35",
|
||||
"EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES",
|
||||
"BriefDescription": "Problem-State L1I Penalty Cycles",
|
||||
"PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "36",
|
||||
"EventName": "PROBLEM_STATE_L1D_DIR_WRITES",
|
||||
"BriefDescription": "Problem-State L1D Directory Writes",
|
||||
"PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "37",
|
||||
"EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES",
|
||||
"BriefDescription": "Problem-State L1D Penalty Cycles",
|
||||
|
@ -1,95 +1,111 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "64",
|
||||
"EventName": "PRNG_FUNCTIONS",
|
||||
"BriefDescription": "PRNG Functions",
|
||||
"PublicDescription": "Total number of the PRNG functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "65",
|
||||
"EventName": "PRNG_CYCLES",
|
||||
"BriefDescription": "PRNG Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "66",
|
||||
"EventName": "PRNG_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "PRNG Blocked Functions",
|
||||
"PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "67",
|
||||
"EventName": "PRNG_BLOCKED_CYCLES",
|
||||
"BriefDescription": "PRNG Blocked Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "68",
|
||||
"EventName": "SHA_FUNCTIONS",
|
||||
"BriefDescription": "SHA Functions",
|
||||
"PublicDescription": "Total number of SHA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "69",
|
||||
"EventName": "SHA_CYCLES",
|
||||
"BriefDescription": "SHA Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "70",
|
||||
"EventName": "SHA_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "SHA Blocked Functions",
|
||||
"PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "71",
|
||||
"EventName": "SHA_BLOCKED_CYCLES",
|
||||
"BriefDescription": "SHA Bloced Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "72",
|
||||
"EventName": "DEA_FUNCTIONS",
|
||||
"BriefDescription": "DEA Functions",
|
||||
"PublicDescription": "Total number of the DEA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "73",
|
||||
"EventName": "DEA_CYCLES",
|
||||
"BriefDescription": "DEA Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "74",
|
||||
"EventName": "DEA_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "DEA Blocked Functions",
|
||||
"PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "75",
|
||||
"EventName": "DEA_BLOCKED_CYCLES",
|
||||
"BriefDescription": "DEA Blocked Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "76",
|
||||
"EventName": "AES_FUNCTIONS",
|
||||
"BriefDescription": "AES Functions",
|
||||
"PublicDescription": "Total number of AES functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "77",
|
||||
"EventName": "AES_CYCLES",
|
||||
"BriefDescription": "AES Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "78",
|
||||
"EventName": "AES_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "AES Blocked Functions",
|
||||
"PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "79",
|
||||
"EventName": "AES_BLOCKED_CYCLES",
|
||||
"BriefDescription": "AES Blocked Cycles",
|
||||
|
@ -1,143 +1,167 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "128",
|
||||
"EventName": "L1D_L2_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D L2 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from the Level-2 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "129",
|
||||
"EventName": "L1I_L2_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I L2 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from the Level-2 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "130",
|
||||
"EventName": "DTLB1_MISSES",
|
||||
"BriefDescription": "DTLB1 Misses",
|
||||
"PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress."
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "131",
|
||||
"EventName": "ITLB1_MISSES",
|
||||
"BriefDescription": "ITLB1 Misses",
|
||||
"PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle a ITLB1 miss is in progress."
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "133",
|
||||
"EventName": "L2C_STORES_SENT",
|
||||
"BriefDescription": "L2C Stores Sent",
|
||||
"PublicDescription": "Incremented by one for every store sent to Level-2 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "134",
|
||||
"EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Book L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Book Level-3 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "135",
|
||||
"EventName": "L1D_ONBOOK_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Book L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an On Book Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "136",
|
||||
"EventName": "L1I_ONBOOK_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Book L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an On Book Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "137",
|
||||
"EventName": "L1D_RO_EXCL_WRITES",
|
||||
"BriefDescription": "L1D Read-only Exclusive Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "138",
|
||||
"EventName": "L1D_OFFBOOK_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Book L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Book Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "139",
|
||||
"EventName": "L1I_OFFBOOK_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Book L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an Off Book Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "140",
|
||||
"EventName": "DTLB1_HPAGE_WRITES",
|
||||
"BriefDescription": "DTLB1 One-Megabyte Page Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "141",
|
||||
"EventName": "L1D_LMEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Local Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "142",
|
||||
"EventName": "L1I_LMEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Local Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 I-Cache where the installed cache line was sourced from memory that is attached to the same book as the Instruction cache (Local Memory)"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "143",
|
||||
"EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Book L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an Off Book Level-3 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "144",
|
||||
"EventName": "DTLB1_WRITES",
|
||||
"BriefDescription": "DTLB1 Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "145",
|
||||
"EventName": "ITLB1_WRITES",
|
||||
"BriefDescription": "ITLB1 Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "146",
|
||||
"EventName": "TLB2_PTE_WRITES",
|
||||
"BriefDescription": "TLB2 PTE Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "147",
|
||||
"EventName": "TLB2_CRSTE_HPAGE_WRITES",
|
||||
"BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "148",
|
||||
"EventName": "TLB2_CRSTE_WRITES",
|
||||
"BriefDescription": "TLB2 CRSTE Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "150",
|
||||
"EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an On Chip Level-3 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "152",
|
||||
"EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "153",
|
||||
"EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an On Chip Level-3 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "155",
|
||||
"EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Chip L3 Sourced Writes",
|
||||
|
@ -1,71 +1,83 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "0",
|
||||
"EventName": "CPU_CYCLES",
|
||||
"BriefDescription": "CPU Cycles",
|
||||
"PublicDescription": "Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "1",
|
||||
"EventName": "INSTRUCTIONS",
|
||||
"BriefDescription": "Instructions",
|
||||
"PublicDescription": "Instruction Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "2",
|
||||
"EventName": "L1I_DIR_WRITES",
|
||||
"BriefDescription": "L1I Directory Writes",
|
||||
"PublicDescription": "Level-1 I-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "3",
|
||||
"EventName": "L1I_PENALTY_CYCLES",
|
||||
"BriefDescription": "L1I Penalty Cycles",
|
||||
"PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "4",
|
||||
"EventName": "L1D_DIR_WRITES",
|
||||
"BriefDescription": "L1D Directory Writes",
|
||||
"PublicDescription": "Level-1 D-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "5",
|
||||
"EventName": "L1D_PENALTY_CYCLES",
|
||||
"BriefDescription": "L1D Penalty Cycles",
|
||||
"PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "32",
|
||||
"EventName": "PROBLEM_STATE_CPU_CYCLES",
|
||||
"BriefDescription": "Problem-State CPU Cycles",
|
||||
"PublicDescription": "Problem-State Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "33",
|
||||
"EventName": "PROBLEM_STATE_INSTRUCTIONS",
|
||||
"BriefDescription": "Problem-State Instructions",
|
||||
"PublicDescription": "Problem-State Instruction Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "34",
|
||||
"EventName": "PROBLEM_STATE_L1I_DIR_WRITES",
|
||||
"BriefDescription": "Problem-State L1I Directory Writes",
|
||||
"PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "35",
|
||||
"EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES",
|
||||
"BriefDescription": "Problem-State L1I Penalty Cycles",
|
||||
"PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "36",
|
||||
"EventName": "PROBLEM_STATE_L1D_DIR_WRITES",
|
||||
"BriefDescription": "Problem-State L1D Directory Writes",
|
||||
"PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "37",
|
||||
"EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES",
|
||||
"BriefDescription": "Problem-State L1D Penalty Cycles",
|
||||
|
@ -1,95 +1,111 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "64",
|
||||
"EventName": "PRNG_FUNCTIONS",
|
||||
"BriefDescription": "PRNG Functions",
|
||||
"PublicDescription": "Total number of the PRNG functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "65",
|
||||
"EventName": "PRNG_CYCLES",
|
||||
"BriefDescription": "PRNG Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "66",
|
||||
"EventName": "PRNG_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "PRNG Blocked Functions",
|
||||
"PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "67",
|
||||
"EventName": "PRNG_BLOCKED_CYCLES",
|
||||
"BriefDescription": "PRNG Blocked Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "68",
|
||||
"EventName": "SHA_FUNCTIONS",
|
||||
"BriefDescription": "SHA Functions",
|
||||
"PublicDescription": "Total number of SHA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "69",
|
||||
"EventName": "SHA_CYCLES",
|
||||
"BriefDescription": "SHA Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "70",
|
||||
"EventName": "SHA_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "SHA Blocked Functions",
|
||||
"PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "71",
|
||||
"EventName": "SHA_BLOCKED_CYCLES",
|
||||
"BriefDescription": "SHA Bloced Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "72",
|
||||
"EventName": "DEA_FUNCTIONS",
|
||||
"BriefDescription": "DEA Functions",
|
||||
"PublicDescription": "Total number of the DEA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "73",
|
||||
"EventName": "DEA_CYCLES",
|
||||
"BriefDescription": "DEA Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "74",
|
||||
"EventName": "DEA_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "DEA Blocked Functions",
|
||||
"PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "75",
|
||||
"EventName": "DEA_BLOCKED_CYCLES",
|
||||
"BriefDescription": "DEA Blocked Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "76",
|
||||
"EventName": "AES_FUNCTIONS",
|
||||
"BriefDescription": "AES Functions",
|
||||
"PublicDescription": "Total number of AES functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "77",
|
||||
"EventName": "AES_CYCLES",
|
||||
"BriefDescription": "AES Cycles",
|
||||
"PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "78",
|
||||
"EventName": "AES_BLOCKED_FUNCTIONS",
|
||||
"BriefDescription": "AES Blocked Functions",
|
||||
"PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "79",
|
||||
"EventName": "AES_BLOCKED_CYCLES",
|
||||
"BriefDescription": "AES Blocked Cycles",
|
||||
|
@ -1,209 +1,244 @@
|
||||
[
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "128",
|
||||
"EventName": "DTLB1_MISSES",
|
||||
"BriefDescription": "DTLB1 Misses",
|
||||
"PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress."
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "129",
|
||||
"EventName": "ITLB1_MISSES",
|
||||
"BriefDescription": "ITLB1 Misses",
|
||||
"PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle a ITLB1 miss is in progress."
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "130",
|
||||
"EventName": "L1D_L2I_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D L2I Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "131",
|
||||
"EventName": "L1I_L2I_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I L2I Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "132",
|
||||
"EventName": "L1D_L2D_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D L2D Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "133",
|
||||
"EventName": "DTLB1_WRITES",
|
||||
"BriefDescription": "DTLB1 Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "135",
|
||||
"EventName": "L1D_LMEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Local Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "137",
|
||||
"EventName": "L1I_LMEM_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Local Memory Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache where the installed cache line was sourced from memory that is attached to the same book as the Instruction cache (Local Memory)"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "138",
|
||||
"EventName": "L1D_RO_EXCL_WRITES",
|
||||
"BriefDescription": "L1D Read-only Exclusive Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "139",
|
||||
"EventName": "DTLB1_HPAGE_WRITES",
|
||||
"BriefDescription": "DTLB1 One-Megabyte Page Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "140",
|
||||
"EventName": "ITLB1_WRITES",
|
||||
"BriefDescription": "ITLB1 Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "141",
|
||||
"EventName": "TLB2_PTE_WRITES",
|
||||
"BriefDescription": "TLB2 PTE Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "142",
|
||||
"EventName": "TLB2_CRSTE_HPAGE_WRITES",
|
||||
"BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "143",
|
||||
"EventName": "TLB2_CRSTE_WRITES",
|
||||
"BriefDescription": "TLB2 CRSTE Writes",
|
||||
"PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "144",
|
||||
"EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On Chip Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "145",
|
||||
"EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "146",
|
||||
"EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Book L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "147",
|
||||
"EventName": "L1D_ONBOOK_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D On-Book L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On Book Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "148",
|
||||
"EventName": "L1D_OFFBOOK_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1D Off-Book L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "149",
|
||||
"EventName": "TX_NC_TEND",
|
||||
"BriefDescription": "Completed TEND instructions in non-constrained TX mode",
|
||||
"PublicDescription": "A TEND instruction has completed in a nonconstrained transactional-execution mode"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "150",
|
||||
"EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from a On Chip Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "151",
|
||||
"EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D Off-Chip L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "152",
|
||||
"EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1D Off-Book L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "153",
|
||||
"EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "154",
|
||||
"EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Chip L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "155",
|
||||
"EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Book L3 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-3 cache without intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "156",
|
||||
"EventName": "L1I_ONBOOK_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I On-Book L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Book Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "157",
|
||||
"EventName": "L1I_OFFBOOK_L4_SOURCED_WRITES",
|
||||
"BriefDescription": "L1I Off-Book L4 Sourced Writes",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-4 cache"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "158",
|
||||
"EventName": "TX_C_TEND",
|
||||
"BriefDescription": "Completed TEND instructions in constrained TX mode",
|
||||
"PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "159",
|
||||
"EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "160",
|
||||
"EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I Off-Chip L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "161",
|
||||
"EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES_IV",
|
||||
"BriefDescription": "L1I Off-Book L3 Sourced Writes with Intervention",
|
||||
"PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-3 cache with intervention"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "177",
|
||||
"EventName": "TX_NC_TABORT",
|
||||
"BriefDescription": "Aborted transactions in non-constrained TX mode",
|
||||
"PublicDescription": "A transaction abort has occurred in a nonconstrained transactional-execution mode"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "178",
|
||||
"EventName": "TX_C_TABORT_NO_SPECIAL",
|
||||
"BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic",
|
||||
"PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete"
|
||||
},
|
||||
{
|
||||
"Unit": "CPU-M-CF",
|
||||
"EventCode": "179",
|
||||
"EventName": "TX_C_TABORT_SPECIAL",
|
||||
"BriefDescription": "Aborted transactions in constrained TX mode using special completion logic",
|
||||
|
@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"BriefDescription": "Transaction count",
|
||||
"MetricName": "transaction",
|
||||
"MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL"
|
||||
}
|
||||
]
|
@ -233,6 +233,8 @@ static struct map {
|
||||
{ "QPI LL", "uncore_qpi" },
|
||||
{ "SBO", "uncore_sbox" },
|
||||
{ "iMPH-U", "uncore_arb" },
|
||||
{ "CPU-M-CF", "cpum_cf" },
|
||||
{ "CPU-M-SF", "cpum_sf" },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -385,7 +385,7 @@ static int test_and_print(struct test *t, bool force_skip, int subtest)
|
||||
if (!t->subtest.get_nr)
|
||||
pr_debug("%s:", t->desc);
|
||||
else
|
||||
pr_debug("%s subtest %d:", t->desc, subtest);
|
||||
pr_debug("%s subtest %d:", t->desc, subtest + 1);
|
||||
|
||||
switch (err) {
|
||||
case TEST_OK:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user