* [patch 2/3] S390-HWBKPT v5: Enabling s390 kernel for kernel PER
@ 2010-05-27 3:55 Mahesh Salgaonkar
2010-07-28 9:07 ` [patch 2/3] S390-HWBKPT v5: Enabling s390 kernel for kernel Heiko Carstens
0 siblings, 1 reply; 2+ messages in thread
From: Mahesh Salgaonkar @ 2010-05-27 3:55 UTC (permalink / raw)
To: linux-s390
Enable kernel PER tracing in the kernel entry point.
A new flag kernel_per_tracing has been added to lowcore for each CPU,
which is checked at every kernel entry point and set the PER bit in
current PSW.
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
arch/s390/include/asm/lowcore.h | 10 ++++++++--
arch/s390/kernel/asm-offsets.c | 2 ++
arch/s390/kernel/entry.S | 12 ++++++++++++
arch/s390/kernel/entry64.S | 12 ++++++++++++
arch/s390/kernel/hw_breakpoint.c | 28 +++++++++++++++++++++-------
5 files changed, 55 insertions(+), 9 deletions(-)
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 05527c0..a9d3c5f 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -135,7 +135,10 @@ struct _lowcore {
__u64 clock_comparator; /* 0x02d0 */
__u32 machine_flags; /* 0x02d8 */
__u32 ftrace_func; /* 0x02dc */
- __u8 pad_0x02e0[0x0300-0x02e0]; /* 0x02e0 */
+
+ /* Kernel PER tracing mask */
+ __u32 kernel_per_tracing_mask; /* 0x02e0 */
+ __u8 pad_0x02e4[0x0300-0x02e4]; /* 0x02e4 */
/* Interrupt response block */
__u8 irb[64]; /* 0x0300 */
@@ -265,7 +268,10 @@ struct _lowcore {
__u64 vdso_per_cpu_data; /* 0x0350 */
__u64 machine_flags; /* 0x0358 */
__u64 ftrace_func; /* 0x0360 */
- __u8 pad_0x0368[0x0380-0x0368]; /* 0x0368 */
+
+ /* Kernel PER tracing mask */
+ __u64 kernel_per_tracing_mask; /* 0x0368 */
+ __u8 pad_0x0370[0x0380-0x0370]; /* 0x0370 */
/* Interrupt response block. */
__u8 irb[64]; /* 0x0380 */
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index a094089..abb33ec 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -130,6 +130,8 @@ int main(void)
DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock));
DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags));
DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func));
+ DEFINE(__LC_KERNEL_PER_TRACING_MASK,
+ offsetof(struct _lowcore, kernel_per_tracing_mask));
DEFINE(__LC_IRB, offsetof(struct _lowcore, irb));
DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area));
DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area));
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 6af7045..2f93424 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -266,6 +266,10 @@ sysc_do_restart:
sth %r7,SP_SVCNR(%r15)
sll %r7,2 # svc number *4
l %r8,BASED(.Lsysc_table)
+ tm __LC_KERNEL_PER_TRACING_MASK,0x40 # kernel per tracing is on?
+ jz sysc_noper
+ stosm __SF_EMPTY(%r15),0x40 # enable per event recording
+sysc_noper:
tm __TI_flags+2(%r9),_TIF_SYSCALL
l %r8,0(%r7,%r8) # get system call addr.
bnz BASED(sysc_tracesys)
@@ -604,6 +608,10 @@ io_int_handler:
io_no_vtime:
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
+ tm __LC_KERNEL_PER_TRACING_MASK,0x40 # kernel per tracing is on?
+ jz io_noper
+ stosm __SF_EMPTY(%r15),0x40 # enable per event recording
+io_noper:
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r1 # branch to standard irq handler
@@ -750,6 +758,10 @@ ext_int_handler:
ext_no_vtime:
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
+ tm __LC_KERNEL_PER_TRACING_MASK,0x40 # kernel per tracing is on?
+ jz ext_noper
+ stosm __SF_EMPTY(%r15),0x40 # enable per event recording
+ext_noper:
la %r2,SP_PTREGS(%r15) # address of register-save area
lh %r3,__LC_EXT_INT_CODE # get interruption code
l %r1,BASED(.Ldo_extint)
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 52106d5..adfb985 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -260,6 +260,10 @@ sysc_do_restart:
larl %r10,sys_call_table_emu # use 31 bit emulation system calls
sysc_noemu:
#endif
+ tm __LC_KERNEL_PER_TRACING_MASK,0x40 # kernel per tracing is on?
+ jz sysc_noper
+ stosm __SF_EMPTY(%r15),0x40 # enable per event recording
+sysc_noper:
tm __TI_flags+6(%r9),_TIF_SYSCALL
lgf %r8,0(%r7,%r10) # load address of system call routine
jnz sysc_tracesys
@@ -579,6 +583,10 @@ io_no_vtime:
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
la %r2,SP_PTREGS(%r15) # address of register-save area
+ tm __LC_KERNEL_PER_TRACING_MASK,0x40 # kernel per tracing is on?
+ jz io_noper
+ stosm __SF_EMPTY(%r15),0x40 # enable per event recording
+io_noper:
brasl %r14,do_IRQ # call standard irq handler
io_return:
tm __TI_flags+7(%r9),_TIF_WORK_INT
@@ -744,6 +752,10 @@ ext_no_vtime:
TRACE_IRQS_OFF
la %r2,SP_PTREGS(%r15) # address of register-save area
llgh %r3,__LC_EXT_INT_CODE # get interruption code
+ tm __LC_KERNEL_PER_TRACING_MASK,0x40 # kernel per tracing is on?
+ jz ext_noper
+ stosm __SF_EMPTY(%r15),0x40 # enable per event recording
+ext_noper:
brasl %r14,do_extint
j io_return
diff --git a/arch/s390/kernel/hw_breakpoint.c b/arch/s390/kernel/hw_breakpoint.c
index 1cce08e..19c5bb5 100644
--- a/arch/s390/kernel/hw_breakpoint.c
+++ b/arch/s390/kernel/hw_breakpoint.c
@@ -82,6 +82,19 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
per_regs[0].starting_addr = info->address;
per_regs[0].ending_addr = info->address + info->len - 1;
+ if (!bp->attr.exclude_kernel
+ && per_regs[0].em_storage_alteration) {
+ /* For kernel wide breakpoints the Storage-Alteration-Space
+ * Control bit as well as the Storage-Alternation-Event bit
+ * in the ASCE needs to be set. Otherwise we might end up
+ * tracing copy_to_user events as well.
+ */
+ per_regs[0].storage_alt_space_ctl = 1;
+ __ctl_set_bit(1, 7);
+ __ctl_set_bit(7, 7);
+ __ctl_set_bit(13, 7);
+ }
+
/* Load the control register 9, 10 and 11 with per info */
__ctl_load(per_regs, 9, 11);
__get_cpu_var(cpu_per_regs[0]) = per_regs[0];
@@ -93,13 +106,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
*/
if (!bp->attr.exclude_kernel) {
/* Enable wide breakpoint in the kernel */
- /* FIXME:
- * It's not good idea to use existing flag in lowcore
- * for turning on/off PER tracing in kernel. instead
- * define a new flag and handle PER tracing checks in
- * entry*.S
- */
-
+ S390_lowcore.kernel_per_tracing_mask |= PSW_MASK_PER;
/* set PER bit int psw_kernel_bits to avoid loosing it
* accidently if someone modifies PSW bit directly.
@@ -148,7 +155,14 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
if (!bp->attr.exclude_kernel) {
/* clear wide breakpoint in the kernel */
+ S390_lowcore.kernel_per_tracing_mask &= ~PSW_MASK_PER;
psw_kernel_bits &= ~PSW_MASK_PER;
+ per_regs[0] = __get_cpu_var(cpu_per_regs[0]);
+ if (per_regs[0].em_storage_alteration) {
+ __ctl_clear_bit(1, 7);
+ __ctl_clear_bit(7, 7);
+ __ctl_clear_bit(13, 7);
+ }
}
if (tsk) {
/* clear breakpoint bound to a task context */
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [patch 2/3] S390-HWBKPT v5: Enabling s390 kernel for kernel
2010-05-27 3:55 [patch 2/3] S390-HWBKPT v5: Enabling s390 kernel for kernel PER Mahesh Salgaonkar
@ 2010-07-28 9:07 ` Heiko Carstens
0 siblings, 0 replies; 2+ messages in thread
From: Heiko Carstens @ 2010-07-28 9:07 UTC (permalink / raw)
To: linux-s390
On Thu, May 27, 2010 at 09:13:01AM +0530, Mahesh Salgaonkar wrote:
> --- a/arch/s390/kernel/hw_breakpoint.c
> +++ b/arch/s390/kernel/hw_breakpoint.c
> @@ -82,6 +82,19 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
> per_regs[0].starting_addr = info->address;
> per_regs[0].ending_addr = info->address + info->len - 1;
>
> + if (!bp->attr.exclude_kernel
> + && per_regs[0].em_storage_alteration) {
> + /* For kernel wide breakpoints the Storage-Alteration-Space
> + * Control bit as well as the Storage-Alternation-Event bit
> + * in the ASCE needs to be set. Otherwise we might end up
> + * tracing copy_to_user events as well.
> + */
> + per_regs[0].storage_alt_space_ctl = 1;
> + __ctl_set_bit(1, 7);
> + __ctl_set_bit(7, 7);
> + __ctl_set_bit(13, 7);
> + }
If !exclude_kernel has the same meaning as "only_kernel" then this could work
if the Storage-Alteration-Event would only be set in the kernel space ASCE.
The corresponding bit in the user space ASCE would be lost on next context
switch. But since that is hopefully irrelevant that shouldn't be a problem.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-07-28 9:07 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-27 3:55 [patch 2/3] S390-HWBKPT v5: Enabling s390 kernel for kernel PER Mahesh Salgaonkar
2010-07-28 9:07 ` [patch 2/3] S390-HWBKPT v5: Enabling s390 kernel for kernel Heiko Carstens
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).