From 7678dcfb310a190aea9bee8cdeb1e14987600737 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 6 May 2013 16:26:01 +0200 Subject: s390/disassembler: prevent endless loop in print_fn_code() If the size of the opcode to be printed is larger than "len" we'll see an overflow of an unsigned long value, which means that the while loop within print_fn_code() will loop quite a long time until there is the next chance for an exit. So add an early exit check. Reported-by: Christian Ehrhardt Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/dis.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index 7f4a4a8..be87d3e 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c @@ -1862,6 +1862,8 @@ void print_fn_code(unsigned char *code, unsigned long len) while (len) { ptr = buffer; opsize = insn_length(*code); + if (opsize > len) + break; ptr += sprintf(ptr, "%p: ", code); for (i = 0; i < opsize; i++) ptr += sprintf(ptr, "%02x", code[i]); -- cgit v1.1 From aca91209775514b5a335e7ef11f1d636618590c7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 13 May 2013 14:48:52 +0200 Subject: s390/ftrace: fix mcount adjustment Tony Jones reported that the ftrace self tests on s390 do not work: <6>Testing dynamic ftrace ops #1: (0 0 0 0 0) FAILED! <6>Testing tracer irqsoff: <3>failed to start irqsoff tracer <4>.. no entries found ..FAILED! <6>Testing tracer wakeup: <3>failed to start wakeup tracer <4>.. no entries found ..FAILED! <6>Testing tracer function_graph: <4>Failed to init function_graph tracer, init returned -19 <4>FAILED! This happens because we forgot to adjust the instruction pointer that gets passed to the ftrace trace function by MCOUNT_INSN_SIZE. In addition change MCOUNT_INSN_SIZE to the correct value on 31 bit. It only worked so far because the to be patched instruction was identical. Reported-by: Tony Jones Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/ftrace.c | 9 ++------- arch/s390/kernel/mcount.S | 2 ++ arch/s390/kernel/mcount64.S | 2 ++ 3 files changed, 6 insertions(+), 7 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 78bdf0e..e3043ae 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -16,12 +16,6 @@ #include #include -#ifdef CONFIG_64BIT -#define MCOUNT_OFFSET_RET 12 -#else -#define MCOUNT_OFFSET_RET 22 -#endif - #ifdef CONFIG_DYNAMIC_FTRACE void ftrace_disable_code(void); @@ -155,9 +149,10 @@ unsigned long __kprobes prepare_ftrace_return(unsigned long parent, if (unlikely(atomic_read(¤t->tracing_graph_pause))) goto out; + ip = (ip & PSW_ADDR_INSN) - MCOUNT_INSN_SIZE; if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) goto out; - trace.func = (ip & PSW_ADDR_INSN) - MCOUNT_OFFSET_RET; + trace.func = ip; /* Only trace if the calling function expects to. */ if (!ftrace_graph_entry(&trace)) { current->curr_ret_stack--; diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 4567ce2..08dcf21 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S @@ -7,6 +7,7 @@ #include #include +#include .section .kprobes.text, "ax" @@ -33,6 +34,7 @@ ENTRY(ftrace_caller) la %r2,0(%r14) st %r0,__SF_BACKCHAIN(%r15) la %r3,0(%r3) + ahi %r2,-MCOUNT_INSN_SIZE l %r14,0b-0b(%r1) l %r14,0(%r14) basr %r14,%r14 diff --git a/arch/s390/kernel/mcount64.S b/arch/s390/kernel/mcount64.S index 1133219..1c52eae 100644 --- a/arch/s390/kernel/mcount64.S +++ b/arch/s390/kernel/mcount64.S @@ -7,6 +7,7 @@ #include #include +#include .section .kprobes.text, "ax" @@ -29,6 +30,7 @@ ENTRY(ftrace_caller) stg %r1,__SF_BACKCHAIN(%r15) lgr %r2,%r14 lg %r3,168(%r15) + aghi %r2,-MCOUNT_INSN_SIZE larl %r14,ftrace_trace_function lg %r14,0(%r14) basr %r14,%r14 -- cgit v1.1 From a4eeea4e530fee26918529eb1b36ae306095eef5 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 15 May 2013 16:53:07 +0200 Subject: s390/smp: fix cpu re-scan vs. cpu state The cpu-info array starts with a list of cpus in configured state, followed by the cpus in standby state. The comparison to decide which state a cpu has is incorrect, this causes configured cpus appear as standby cpus. The correct comparison is the index of the new cpu in the cpu-info array vs. the number of configured cpus. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 8074cb4..05674b6 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -645,7 +645,7 @@ static int __cpuinit __smp_rescan_cpus(struct sclp_cpu_info *info, continue; pcpu = pcpu_devices + cpu; pcpu->address = info->cpu[i].address; - pcpu->state = (cpu >= info->configured) ? + pcpu->state = (i >= info->configured) ? CPU_STATE_STANDBY : CPU_STATE_CONFIGURED; smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); set_cpu_present(cpu, true); -- cgit v1.1