x86, ptrace: support for branch trace store(BTS)
Subsystems (2)
PATCH 1/2 x86, ptrace: support for branch trace store(BTS)
Resend using different mail client
Changes to the last version:
- split implementation into two layers: ds/bts and ptrace
- renamed TIF's
- save/restore ds save area msr in __switch_to_xtra()
- make block-stepping only look at BTF bit
---
arch/x86/kernel/process_32.c +18 -1
@@ -594,11 +594,21 @@ struct tss_struct *tss) {struct thread_struct *prev, *next; +unsigned long debugctl; prev = &prev_p->thread; next = &next_p->thread; -if (next->debugctlmsr != prev->debugctlmsr) + debugctl = prev->debugctlmsr; +if (next->ds_area_msr != prev->ds_area_msr) { +/* we clear debugctl to make sure DS +* is not in use when we change it */ + debugctl =0 ; +wrmsrl (MSR_IA32_DEBUGCTLMSR ,0 ); +wrmsr (MSR_IA32_DS_AREA , next->ds_area_msr,0 ); + } + +if (next->debugctlmsr != debugctl)wrmsr (MSR_IA32_DEBUGCTLMSR , next->debugctlmsr,0 );if (test_tsk_thread_flag (next_p,TIF_DEBUG )) {
@@ -622,6 +632,13 @@ }#endif +if (test_tsk_thread_flag (prev_p,TIF_BTS_TRACE_TS )) +ptrace_bts_take_timestamp (prev_p,BTS_TASK_DEPARTS ); + +if (test_tsk_thread_flag (next_p,TIF_BTS_TRACE_TS )) +ptrace_bts_take_timestamp (next_p,BTS_TASK_ARRIVES ); + +if (!test_tsk_thread_flag (next_p,TIF_IO_BITMAP )) {/* * Disable the bitmap via an invalid offset. We still cache
include/asm-x86/ptrace-abi.h +52 -0
56 lines not on this page · raw message
include/asm-x86/ptrace.h +11 -0
@@ -4,8 +4,19 @@#include <linux/compiler.h> /* For __user */ #include <asm/ptrace-abi.h> +#ifndef __ASSEMBLY__ +#ifdef __KERNEL__ + +#include <asm/ds.h> + +struct task_struct ; +extern void ptrace_bts_take_timestamp (struct task_struct *,enum bts_qualifier ); + +#endif /* __KERNEL__ */ + +#ifdef __i386__/* this struct defines the way the registers are stored on the stack during a system call. */
arch/x86/kernel/Makefile_32 +1 -0
@@ -11,6 +11,7 @@ quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o rtc.o obj-y += ptrace.o +obj-y += ds.o obj-y += tls.o obj-y += step.o obj-$(CONFIG_STACKTRACE) += stacktrace.o
include/asm-x86/thread_info_32.h +10 -2
@@ -139,6 +139,8 @@#define TIF_NOTSC 20/* TSC is not accessible in userland */ #define TIF_FORCED_TF 21/* true if TF in eflags artificially */ #define TIF_DEBUGCTLMSR 22/* uses thread_struct.debugctlmsr */ +#define TIF_DS_AREA_MSR 23/* uses thread_struct.ds_area_msr */ +#define TIF_BTS_TRACE_TS 24/* record scheduling event timestamps */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
@@ -155,6 +157,8 @@#define _TIF_NOTSC (1<<TIF_NOTSC)#define _TIF_FORCED_TF (1<<TIF_FORCED_TF)#define _TIF_DEBUGCTLMSR (1<<TIF_DEBUGCTLMSR) +#define _TIF_DS_AREA_MSR (1<<TIF_DS_AREA_MSR) +#define _TIF_BTS_TRACE_TS (1<<TIF_BTS_TRACE_TS)/* work to do on interrupt/exception return */ #define _TIF_WORK_MASK \
@@ -164,8 +168,12 @@#define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP)/* flags to check in __switch_to() */ -#define _TIF_WORK_CTXSW_NEXT (_TIF_IO_BITMAP | _TIF_NOTSC | _TIF_DEBUG | _TIF_DEBUGCTLMSR) -#define _TIF_WORK_CTXSW_PREV (_TIF_IO_BITMAP | _TIF_NOTSC | _TIF_DEBUGCTLMSR) +#define _TIF_WORK_CTXSW \ + (_TIF_IO_BITMAP | _TIF_NOTSC | _TIF_DEBUGCTLMSR | \ + _TIF_DS_AREA_MSR | _TIF_BTS_TRACE_TS) +#define _TIF_WORK_CTXSW_PREV _TIF_WORK_CTXSW +#define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW | _TIF_DEBUG) +/* * Thread-synchronous status.
include/asm-x86/processor_32.h +3 -0
@@ -360,6 +360,9 @@unsigned long io_bitmap_max;/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ unsigned long debugctlmsr; +/* Debug Store - if not 0 points to a DS Save Area configuration; +* goes into MSR_IA32_DS_AREA */ +unsigned long ds_area_msr; };#define INIT_THREAD { \
arch/x86/kernel/process_64.c +23 -3
@@ -550,11 +550,21 @@ struct tss_struct *tss) {struct thread_struct *prev, *next; +unsigned long debugctl; prev = &prev_p->thread, next = &next_p->thread; -if (next->debugctlmsr != prev->debugctlmsr) + debugctl = prev->debugctlmsr; +if (next->ds_area_msr != prev->ds_area_msr) { +/* we clear debugctl to make sure DS +* is not in use when we change it */ + debugctl =0 ; +wrmsrl (MSR_IA32_DEBUGCTLMSR ,0 ); +wrmsrl (MSR_IA32_DS_AREA , next->ds_area_msr); + } + +if (next->debugctlmsr != debugctl)wrmsrl (MSR_IA32_DEBUGCTLMSR , next->debugctlmsr);if (test_tsk_thread_flag (next_p,TIF_DEBUG )) {
@@ -580,6 +590,16 @@*/ memset (tss->io_bitmap,0xff , prev->io_bitmap_max); } + +/* +* Last branch recording recofiguration of trace hardware and +* disentangling of trace data per task. +*/ +if (test_tsk_thread_flag (prev_p,TIF_BTS_TRACE_TS )) +ptrace_bts_take_timestamp (prev_p,BTS_TASK_DEPARTS ); + +if (test_tsk_thread_flag (next_p,TIF_BTS_TRACE_TS )) +ptrace_bts_take_timestamp (next_p,BTS_TASK_ARRIVES ); }/*
@@ -683,8 +703,8 @@/* * Now maybe reload the debug registers and handle I/O bitmaps */ -if (unlikely ((task_thread_info (next_p)->flags & _TIF_WORK_CTXSW)) - ||test_tsk_thread_flag (prev_p,TIF_IO_BITMAP )) +if (unlikely (task_thread_info (next_p)->flags & _TIF_WORK_CTXSW_NEXT || +task_thread_info (prev_p)->flags & _TIF_WORK_CTXSW_PREV))__switch_to_xtra (prev_p, next_p, tss);/* If the task has used fpu the last 5 timeslices, just do a full
include/asm-x86/processor_64.h +3 -0
@@ -240,6 +240,9 @@unsigned io_bitmap_max;/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ unsigned long debugctlmsr; +/* Debug Store - if not 0 points to a DS Save Area configuration; +* goes into MSR_IA32_DS_AREA */ +unsigned long ds_area_msr;/* cached TLS descriptors. */ u64 tls_array[GDT_ENTRY_TLS_ENTRIES ]; } __attribute__((aligned(16)));
include/asm-x86/thread_info_64.h +8 -1
@@ -121,6 +121,8 @@#define TIF_IO_BITMAP 22/* uses I/O bitmap */ #define TIF_FREEZE 23/* is freezing for suspend */ #define TIF_DEBUGCTLMSR 24/* uses thread_struct.debugctlmsr */ +#define TIF_DS_AREA_MSR 25/* uses thread_struct.ds_area_msr */ +#define TIF_BTS_TRACE_TS 26/* record scheduling event timestamps */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
@@ -139,6 +141,8 @@#define _TIF_IO_BITMAP (1<<TIF_IO_BITMAP)#define _TIF_FREEZE (1<<TIF_FREEZE)#define _TIF_DEBUGCTLMSR (1<<TIF_DEBUGCTLMSR) +#define _TIF_DS_AREA_MSR (1<<TIF_DS_AREA_MSR) +#define _TIF_BTS_TRACE_TS (1<<TIF_BTS_TRACE_TS)/* work to do on interrupt/exception return */ #define _TIF_WORK_MASK \
@@ -147,7 +151,10 @@#define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP)/* flags to check in __switch_to() */ -#define _TIF_WORK_CTXSW (_TIF_DEBUG|_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR) +#define _TIF_WORK_CTXSW \ + (_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_BTS_TRACE_TS) +#define _TIF_WORK_CTXSW_PREV _TIF_WORK_CTXSW +#define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG)#define PREEMPT_ACTIVE 0x10000000
arch/x86/kernel/cpu/intel.c +5 -0
@@ -11,6 +11,8 @@#include <asm/pgtable.h> #include <asm/msr.h> #include <asm/uaccess.h> +#include <asm/ptrace.h> +#include <asm/ds.h> #include "cpu.h"
@@ -219,6 +221,9 @@if (!(l1 & (1 <<12 )))set_bit (X86_FEATURE_PEBS , c->x86_capability); } + +if (cpu_has_bts) +ds_init_intel (c); }static unsigned int __cpuinit intel_size_cache (struct cpuinfo_x86 * c,unsigned int size)
arch/x86/kernel/setup_64.c +5 -0
@@ -60,6 +60,7 @@#include <asm/dmi.h> #include <asm/cacheflush.h> #include <asm/mce.h> +#include <asm/ds.h> /* * Machine setup..
@@ -850,6 +851,10 @@set_cpu_cap (c,X86_FEATURE_PEBS ); } + +if (cpu_has_bts) +ds_init_intel (c); + n = c->extended_cpuid_level;if (n >=0x80000008 ) {unsigned eax =cpuid_eax (0x80000008 );
arch/x86/kernel/ptrace.c +212 -0
248 lines not on this page · raw message
arch/x86/kernel/Makefile_64 +1 -0
@@ -13,6 +13,7 @@ i8253.o rtc.o obj-y += ptrace.o +obj-y += ds.o obj-y += step.o obj-$(CONFIG_IA32_EMULATION) += tls.o
arch/x86/kernel/step.c +13 -5
@@ -169,9 +169,14 @@*/ if (enable_single_step (child) && block) {set_tsk_thread_flag (child,TIF_DEBUGCTLMSR ); -write_debugctlmsr (child,DEBUGCTLMSR_BTF ); - }else if (test_and_clear_tsk_thread_flag (child,TIF_DEBUGCTLMSR )) { -write_debugctlmsr (child,0 ); +write_debugctlmsr (child, + child->thread.debugctlmsr |DEBUGCTLMSR_BTF ); + }else { +write_debugctlmsr (child, + child->thread.debugctlmsr & ~TIF_DEBUGCTLMSR ); + +if (!child->thread.debugctlmsr) +clear_tsk_thread_flag (child,TIF_DEBUGCTLMSR ); } }
@@ -190,8 +195,11 @@/* * Make sure block stepping (BTF) is disabled. */ -if (test_and_clear_tsk_thread_flag (child,TIF_DEBUGCTLMSR )) -write_debugctlmsr (child,0 ); +write_debugctlmsr (child, + child->thread.debugctlmsr & ~TIF_DEBUGCTLMSR ); + +if (!child->thread.debugctlmsr) +clear_tsk_thread_flag (child,TIF_DEBUGCTLMSR );/* Always clear TIF_SINGLESTEP... */ clear_tsk_thread_flag (child,TIF_SINGLESTEP );
arch/x86/kernel/ds.c new file +429 -0
429 lines not on this page · raw message
include/asm-x86/ds.h new file +65 -0
65 lines not on this page · raw message
---------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen Germany
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456 Ust.-IdNr.
VAT Registration No.: DE129385895
Citibank Frankfurt (BLZ 502 109 00) 600119052
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
Quoted 1 line · Markus Metzger
Resend using different mail client
thanks, this one applied fine to x86.git.
Ingo