Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky: "A couple of bug fixes for s390. The ftrace comile fix is quite large for a -rc6 release, but it would be nice to have it in 4.0" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/smp: reenable smt after resume s390/mm: limit STACK_RND_MASK for compat tasks s390/ftrace: fix compile error if CONFIG_KPROBES is disabled s390/cpum_sf: add diagnostic sampling event only if it is authorized
This commit is contained in:
commit
d6702d840c
4 changed files with 62 additions and 19 deletions
|
@ -211,7 +211,7 @@ do { \
|
||||||
|
|
||||||
extern unsigned long mmap_rnd_mask;
|
extern unsigned long mmap_rnd_mask;
|
||||||
|
|
||||||
#define STACK_RND_MASK (mmap_rnd_mask)
|
#define STACK_RND_MASK (test_thread_flag(TIF_31BIT) ? 0x7ff : mmap_rnd_mask)
|
||||||
|
|
||||||
#define ARCH_DLINFO \
|
#define ARCH_DLINFO \
|
||||||
do { \
|
do { \
|
||||||
|
|
|
@ -57,6 +57,44 @@
|
||||||
|
|
||||||
unsigned long ftrace_plt;
|
unsigned long ftrace_plt;
|
||||||
|
|
||||||
|
static inline void ftrace_generate_orig_insn(struct ftrace_insn *insn)
|
||||||
|
{
|
||||||
|
#ifdef CC_USING_HOTPATCH
|
||||||
|
/* brcl 0,0 */
|
||||||
|
insn->opc = 0xc004;
|
||||||
|
insn->disp = 0;
|
||||||
|
#else
|
||||||
|
/* stg r14,8(r15) */
|
||||||
|
insn->opc = 0xe3e0;
|
||||||
|
insn->disp = 0xf0080024;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int is_kprobe_on_ftrace(struct ftrace_insn *insn)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_KPROBES
|
||||||
|
if (insn->opc == BREAKPOINT_INSTRUCTION)
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ftrace_generate_kprobe_nop_insn(struct ftrace_insn *insn)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_KPROBES
|
||||||
|
insn->opc = BREAKPOINT_INSTRUCTION;
|
||||||
|
insn->disp = KPROBE_ON_FTRACE_NOP;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ftrace_generate_kprobe_call_insn(struct ftrace_insn *insn)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_KPROBES
|
||||||
|
insn->opc = BREAKPOINT_INSTRUCTION;
|
||||||
|
insn->disp = KPROBE_ON_FTRACE_CALL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
|
int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
|
||||||
unsigned long addr)
|
unsigned long addr)
|
||||||
{
|
{
|
||||||
|
@ -72,16 +110,9 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (addr == MCOUNT_ADDR) {
|
if (addr == MCOUNT_ADDR) {
|
||||||
/* Initial code replacement */
|
/* Initial code replacement */
|
||||||
#ifdef CC_USING_HOTPATCH
|
ftrace_generate_orig_insn(&orig);
|
||||||
/* We expect to see brcl 0,0 */
|
|
||||||
ftrace_generate_nop_insn(&orig);
|
|
||||||
#else
|
|
||||||
/* We expect to see stg r14,8(r15) */
|
|
||||||
orig.opc = 0xe3e0;
|
|
||||||
orig.disp = 0xf0080024;
|
|
||||||
#endif
|
|
||||||
ftrace_generate_nop_insn(&new);
|
ftrace_generate_nop_insn(&new);
|
||||||
} else if (old.opc == BREAKPOINT_INSTRUCTION) {
|
} else if (is_kprobe_on_ftrace(&old)) {
|
||||||
/*
|
/*
|
||||||
* If we find a breakpoint instruction, a kprobe has been
|
* If we find a breakpoint instruction, a kprobe has been
|
||||||
* placed at the beginning of the function. We write the
|
* placed at the beginning of the function. We write the
|
||||||
|
@ -89,9 +120,8 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
|
||||||
* bytes of the original instruction so that the kprobes
|
* bytes of the original instruction so that the kprobes
|
||||||
* handler can execute a nop, if it reaches this breakpoint.
|
* handler can execute a nop, if it reaches this breakpoint.
|
||||||
*/
|
*/
|
||||||
new.opc = orig.opc = BREAKPOINT_INSTRUCTION;
|
ftrace_generate_kprobe_call_insn(&orig);
|
||||||
orig.disp = KPROBE_ON_FTRACE_CALL;
|
ftrace_generate_kprobe_nop_insn(&new);
|
||||||
new.disp = KPROBE_ON_FTRACE_NOP;
|
|
||||||
} else {
|
} else {
|
||||||
/* Replace ftrace call with a nop. */
|
/* Replace ftrace call with a nop. */
|
||||||
ftrace_generate_call_insn(&orig, rec->ip);
|
ftrace_generate_call_insn(&orig, rec->ip);
|
||||||
|
@ -111,7 +141,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
||||||
|
|
||||||
if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old)))
|
if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (old.opc == BREAKPOINT_INSTRUCTION) {
|
if (is_kprobe_on_ftrace(&old)) {
|
||||||
/*
|
/*
|
||||||
* If we find a breakpoint instruction, a kprobe has been
|
* If we find a breakpoint instruction, a kprobe has been
|
||||||
* placed at the beginning of the function. We write the
|
* placed at the beginning of the function. We write the
|
||||||
|
@ -119,9 +149,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
||||||
* bytes of the original instruction so that the kprobes
|
* bytes of the original instruction so that the kprobes
|
||||||
* handler can execute a brasl if it reaches this breakpoint.
|
* handler can execute a brasl if it reaches this breakpoint.
|
||||||
*/
|
*/
|
||||||
new.opc = orig.opc = BREAKPOINT_INSTRUCTION;
|
ftrace_generate_kprobe_nop_insn(&orig);
|
||||||
orig.disp = KPROBE_ON_FTRACE_NOP;
|
ftrace_generate_kprobe_call_insn(&new);
|
||||||
new.disp = KPROBE_ON_FTRACE_CALL;
|
|
||||||
} else {
|
} else {
|
||||||
/* Replace nop with an ftrace call. */
|
/* Replace nop with an ftrace call. */
|
||||||
ftrace_generate_nop_insn(&orig);
|
ftrace_generate_nop_insn(&orig);
|
||||||
|
|
|
@ -1415,7 +1415,7 @@ CPUMF_EVENT_ATTR(SF, SF_CYCLES_BASIC_DIAG, PERF_EVENT_CPUM_SF_DIAG);
|
||||||
|
|
||||||
static struct attribute *cpumsf_pmu_events_attr[] = {
|
static struct attribute *cpumsf_pmu_events_attr[] = {
|
||||||
CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC),
|
CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC),
|
||||||
CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC_DIAG),
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1606,8 +1606,11 @@ static int __init init_cpum_sampling_pmu(void)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (si.ad)
|
if (si.ad) {
|
||||||
sfb_set_limits(CPUM_SF_MIN_SDB, CPUM_SF_MAX_SDB);
|
sfb_set_limits(CPUM_SF_MIN_SDB, CPUM_SF_MAX_SDB);
|
||||||
|
cpumsf_pmu_events_attr[1] =
|
||||||
|
CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC_DIAG);
|
||||||
|
}
|
||||||
|
|
||||||
sfdbg = debug_register(KMSG_COMPONENT, 2, 1, 80);
|
sfdbg = debug_register(KMSG_COMPONENT, 2, 1, 80);
|
||||||
if (!sfdbg)
|
if (!sfdbg)
|
||||||
|
|
|
@ -177,6 +177,17 @@ restart_entry:
|
||||||
lhi %r1,1
|
lhi %r1,1
|
||||||
sigp %r1,%r0,SIGP_SET_ARCHITECTURE
|
sigp %r1,%r0,SIGP_SET_ARCHITECTURE
|
||||||
sam64
|
sam64
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
larl %r1,smp_cpu_mt_shift
|
||||||
|
icm %r1,15,0(%r1)
|
||||||
|
jz smt_done
|
||||||
|
llgfr %r1,%r1
|
||||||
|
smt_loop:
|
||||||
|
sigp %r1,%r0,SIGP_SET_MULTI_THREADING
|
||||||
|
brc 8,smt_done /* accepted */
|
||||||
|
brc 2,smt_loop /* busy, try again */
|
||||||
|
smt_done:
|
||||||
|
#endif
|
||||||
larl %r1,.Lnew_pgm_check_psw
|
larl %r1,.Lnew_pgm_check_psw
|
||||||
lpswe 0(%r1)
|
lpswe 0(%r1)
|
||||||
pgm_check_entry:
|
pgm_check_entry:
|
||||||
|
|
Loading…
Add table
Reference in a new issue