diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-03-31 03:08:13 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-03-31 03:08:13 -0400 |
commit | c5e77f5216abdd1d98e6d14d9a3eb4e88d80011a (patch) | |
tree | a542b5bb7d96a8f37c4d5e3319086064448ed67b /arch/s390/kernel | |
parent | de81e64b250d3865a75d221a80b4311e3273670a (diff) | |
parent | e42391cd048809d903291d07f86ed3934ce138e9 (diff) |
Merge tag 'v4.0-rc6' into timers/core, before applying new patches
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/ftrace.c | 61 | ||||
-rw-r--r-- | arch/s390/kernel/jump_label.c | 12 | ||||
-rw-r--r-- | arch/s390/kernel/module.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/perf_cpum_sf.c | 7 | ||||
-rw-r--r-- | arch/s390/kernel/processor.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/swsusp_asm64.S | 11 |
6 files changed, 71 insertions, 23 deletions
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 82c19899574f..6c79f1b44fe7 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c | |||
@@ -57,6 +57,44 @@ | |||
57 | 57 | ||
58 | unsigned long ftrace_plt; | 58 | unsigned long ftrace_plt; |
59 | 59 | ||
60 | static inline void ftrace_generate_orig_insn(struct ftrace_insn *insn) | ||
61 | { | ||
62 | #ifdef CC_USING_HOTPATCH | ||
63 | /* brcl 0,0 */ | ||
64 | insn->opc = 0xc004; | ||
65 | insn->disp = 0; | ||
66 | #else | ||
67 | /* stg r14,8(r15) */ | ||
68 | insn->opc = 0xe3e0; | ||
69 | insn->disp = 0xf0080024; | ||
70 | #endif | ||
71 | } | ||
72 | |||
73 | static inline int is_kprobe_on_ftrace(struct ftrace_insn *insn) | ||
74 | { | ||
75 | #ifdef CONFIG_KPROBES | ||
76 | if (insn->opc == BREAKPOINT_INSTRUCTION) | ||
77 | return 1; | ||
78 | #endif | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static inline void ftrace_generate_kprobe_nop_insn(struct ftrace_insn *insn) | ||
83 | { | ||
84 | #ifdef CONFIG_KPROBES | ||
85 | insn->opc = BREAKPOINT_INSTRUCTION; | ||
86 | insn->disp = KPROBE_ON_FTRACE_NOP; | ||
87 | #endif | ||
88 | } | ||
89 | |||
90 | static inline void ftrace_generate_kprobe_call_insn(struct ftrace_insn *insn) | ||
91 | { | ||
92 | #ifdef CONFIG_KPROBES | ||
93 | insn->opc = BREAKPOINT_INSTRUCTION; | ||
94 | insn->disp = KPROBE_ON_FTRACE_CALL; | ||
95 | #endif | ||
96 | } | ||
97 | |||
60 | int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, | 98 | int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, |
61 | unsigned long addr) | 99 | unsigned long addr) |
62 | { | 100 | { |
@@ -72,16 +110,9 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, | |||
72 | return -EFAULT; | 110 | return -EFAULT; |
73 | if (addr == MCOUNT_ADDR) { | 111 | if (addr == MCOUNT_ADDR) { |
74 | /* Initial code replacement */ | 112 | /* Initial code replacement */ |
75 | #ifdef CC_USING_HOTPATCH | 113 | ftrace_generate_orig_insn(&orig); |
76 | /* We expect to see brcl 0,0 */ | ||
77 | ftrace_generate_nop_insn(&orig); | ||
78 | #else | ||
79 | /* We expect to see stg r14,8(r15) */ | ||
80 | orig.opc = 0xe3e0; | ||
81 | orig.disp = 0xf0080024; | ||
82 | #endif | ||
83 | ftrace_generate_nop_insn(&new); | 114 | ftrace_generate_nop_insn(&new); |
84 | } else if (old.opc == BREAKPOINT_INSTRUCTION) { | 115 | } else if (is_kprobe_on_ftrace(&old)) { |
85 | /* | 116 | /* |
86 | * If we find a breakpoint instruction, a kprobe has been | 117 | * If we find a breakpoint instruction, a kprobe has been |
87 | * placed at the beginning of the function. We write the | 118 | * 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, | |||
89 | * bytes of the original instruction so that the kprobes | 120 | * bytes of the original instruction so that the kprobes |
90 | * handler can execute a nop, if it reaches this breakpoint. | 121 | * handler can execute a nop, if it reaches this breakpoint. |
91 | */ | 122 | */ |
92 | new.opc = orig.opc = BREAKPOINT_INSTRUCTION; | 123 | ftrace_generate_kprobe_call_insn(&orig); |
93 | orig.disp = KPROBE_ON_FTRACE_CALL; | 124 | ftrace_generate_kprobe_nop_insn(&new); |
94 | new.disp = KPROBE_ON_FTRACE_NOP; | ||
95 | } else { | 125 | } else { |
96 | /* Replace ftrace call with a nop. */ | 126 | /* Replace ftrace call with a nop. */ |
97 | ftrace_generate_call_insn(&orig, rec->ip); | 127 | ftrace_generate_call_insn(&orig, rec->ip); |
@@ -111,7 +141,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
111 | 141 | ||
112 | if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) | 142 | if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) |
113 | return -EFAULT; | 143 | return -EFAULT; |
114 | if (old.opc == BREAKPOINT_INSTRUCTION) { | 144 | if (is_kprobe_on_ftrace(&old)) { |
115 | /* | 145 | /* |
116 | * If we find a breakpoint instruction, a kprobe has been | 146 | * If we find a breakpoint instruction, a kprobe has been |
117 | * placed at the beginning of the function. We write the | 147 | * 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) | |||
119 | * bytes of the original instruction so that the kprobes | 149 | * bytes of the original instruction so that the kprobes |
120 | * handler can execute a brasl if it reaches this breakpoint. | 150 | * handler can execute a brasl if it reaches this breakpoint. |
121 | */ | 151 | */ |
122 | new.opc = orig.opc = BREAKPOINT_INSTRUCTION; | 152 | ftrace_generate_kprobe_nop_insn(&orig); |
123 | orig.disp = KPROBE_ON_FTRACE_NOP; | 153 | ftrace_generate_kprobe_call_insn(&new); |
124 | new.disp = KPROBE_ON_FTRACE_CALL; | ||
125 | } else { | 154 | } else { |
126 | /* Replace nop with an ftrace call. */ | 155 | /* Replace nop with an ftrace call. */ |
127 | ftrace_generate_nop_insn(&orig); | 156 | ftrace_generate_nop_insn(&orig); |
diff --git a/arch/s390/kernel/jump_label.c b/arch/s390/kernel/jump_label.c index cb2d51e779df..830066f936c8 100644 --- a/arch/s390/kernel/jump_label.c +++ b/arch/s390/kernel/jump_label.c | |||
@@ -36,16 +36,20 @@ static void jump_label_make_branch(struct jump_entry *entry, struct insn *insn) | |||
36 | insn->offset = (entry->target - entry->code) >> 1; | 36 | insn->offset = (entry->target - entry->code) >> 1; |
37 | } | 37 | } |
38 | 38 | ||
39 | static void jump_label_bug(struct jump_entry *entry, struct insn *insn) | 39 | static void jump_label_bug(struct jump_entry *entry, struct insn *expected, |
40 | struct insn *new) | ||
40 | { | 41 | { |
41 | unsigned char *ipc = (unsigned char *)entry->code; | 42 | unsigned char *ipc = (unsigned char *)entry->code; |
42 | unsigned char *ipe = (unsigned char *)insn; | 43 | unsigned char *ipe = (unsigned char *)expected; |
44 | unsigned char *ipn = (unsigned char *)new; | ||
43 | 45 | ||
44 | pr_emerg("Jump label code mismatch at %pS [%p]\n", ipc, ipc); | 46 | pr_emerg("Jump label code mismatch at %pS [%p]\n", ipc, ipc); |
45 | pr_emerg("Found: %02x %02x %02x %02x %02x %02x\n", | 47 | pr_emerg("Found: %02x %02x %02x %02x %02x %02x\n", |
46 | ipc[0], ipc[1], ipc[2], ipc[3], ipc[4], ipc[5]); | 48 | ipc[0], ipc[1], ipc[2], ipc[3], ipc[4], ipc[5]); |
47 | pr_emerg("Expected: %02x %02x %02x %02x %02x %02x\n", | 49 | pr_emerg("Expected: %02x %02x %02x %02x %02x %02x\n", |
48 | ipe[0], ipe[1], ipe[2], ipe[3], ipe[4], ipe[5]); | 50 | ipe[0], ipe[1], ipe[2], ipe[3], ipe[4], ipe[5]); |
51 | pr_emerg("New: %02x %02x %02x %02x %02x %02x\n", | ||
52 | ipn[0], ipn[1], ipn[2], ipn[3], ipn[4], ipn[5]); | ||
49 | panic("Corrupted kernel text"); | 53 | panic("Corrupted kernel text"); |
50 | } | 54 | } |
51 | 55 | ||
@@ -69,10 +73,10 @@ static void __jump_label_transform(struct jump_entry *entry, | |||
69 | } | 73 | } |
70 | if (init) { | 74 | if (init) { |
71 | if (memcmp((void *)entry->code, &orignop, sizeof(orignop))) | 75 | if (memcmp((void *)entry->code, &orignop, sizeof(orignop))) |
72 | jump_label_bug(entry, &old); | 76 | jump_label_bug(entry, &orignop, &new); |
73 | } else { | 77 | } else { |
74 | if (memcmp((void *)entry->code, &old, sizeof(old))) | 78 | if (memcmp((void *)entry->code, &old, sizeof(old))) |
75 | jump_label_bug(entry, &old); | 79 | jump_label_bug(entry, &old, &new); |
76 | } | 80 | } |
77 | probe_kernel_write((void *)entry->code, &new, sizeof(new)); | 81 | probe_kernel_write((void *)entry->code, &new, sizeof(new)); |
78 | } | 82 | } |
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 36154a2f1814..2ca95862e336 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c | |||
@@ -436,6 +436,7 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
436 | const Elf_Shdr *sechdrs, | 436 | const Elf_Shdr *sechdrs, |
437 | struct module *me) | 437 | struct module *me) |
438 | { | 438 | { |
439 | jump_label_apply_nops(me); | ||
439 | vfree(me->arch.syminfo); | 440 | vfree(me->arch.syminfo); |
440 | me->arch.syminfo = NULL; | 441 | me->arch.syminfo = NULL; |
441 | return 0; | 442 | return 0; |
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index c3f8d157cb0d..e6a1578fc000 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c | |||
@@ -1415,7 +1415,7 @@ CPUMF_EVENT_ATTR(SF, SF_CYCLES_BASIC_DIAG, PERF_EVENT_CPUM_SF_DIAG); | |||
1415 | 1415 | ||
1416 | static struct attribute *cpumsf_pmu_events_attr[] = { | 1416 | static struct attribute *cpumsf_pmu_events_attr[] = { |
1417 | CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC), | 1417 | CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC), |
1418 | CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC_DIAG), | 1418 | NULL, |
1419 | NULL, | 1419 | NULL, |
1420 | }; | 1420 | }; |
1421 | 1421 | ||
@@ -1606,8 +1606,11 @@ static int __init init_cpum_sampling_pmu(void) | |||
1606 | return -EINVAL; | 1606 | return -EINVAL; |
1607 | } | 1607 | } |
1608 | 1608 | ||
1609 | if (si.ad) | 1609 | if (si.ad) { |
1610 | sfb_set_limits(CPUM_SF_MIN_SDB, CPUM_SF_MAX_SDB); | 1610 | sfb_set_limits(CPUM_SF_MIN_SDB, CPUM_SF_MAX_SDB); |
1611 | cpumsf_pmu_events_attr[1] = | ||
1612 | CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC_DIAG); | ||
1613 | } | ||
1611 | 1614 | ||
1612 | sfdbg = debug_register(KMSG_COMPONENT, 2, 1, 80); | 1615 | sfdbg = debug_register(KMSG_COMPONENT, 2, 1, 80); |
1613 | if (!sfdbg) | 1616 | if (!sfdbg) |
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 26108232fcaa..dc488e13b7e3 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | static DEFINE_PER_CPU(struct cpuid, cpu_id); | 19 | static DEFINE_PER_CPU(struct cpuid, cpu_id); |
20 | 20 | ||
21 | void cpu_relax(void) | 21 | void notrace cpu_relax(void) |
22 | { | 22 | { |
23 | if (!smp_cpu_mtid && MACHINE_HAS_DIAG44) | 23 | if (!smp_cpu_mtid && MACHINE_HAS_DIAG44) |
24 | asm volatile("diag 0,0,0x44"); | 24 | asm volatile("diag 0,0,0x44"); |
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S index 6b09fdffbd2f..ca6294645dd3 100644 --- a/arch/s390/kernel/swsusp_asm64.S +++ b/arch/s390/kernel/swsusp_asm64.S | |||
@@ -177,6 +177,17 @@ restart_entry: | |||
177 | lhi %r1,1 | 177 | lhi %r1,1 |
178 | sigp %r1,%r0,SIGP_SET_ARCHITECTURE | 178 | sigp %r1,%r0,SIGP_SET_ARCHITECTURE |
179 | sam64 | 179 | sam64 |
180 | #ifdef CONFIG_SMP | ||
181 | larl %r1,smp_cpu_mt_shift | ||
182 | icm %r1,15,0(%r1) | ||
183 | jz smt_done | ||
184 | llgfr %r1,%r1 | ||
185 | smt_loop: | ||
186 | sigp %r1,%r0,SIGP_SET_MULTI_THREADING | ||
187 | brc 8,smt_done /* accepted */ | ||
188 | brc 2,smt_loop /* busy, try again */ | ||
189 | smt_done: | ||
190 | #endif | ||
180 | larl %r1,.Lnew_pgm_check_psw | 191 | larl %r1,.Lnew_pgm_check_psw |
181 | lpswe 0(%r1) | 192 | lpswe 0(%r1) |
182 | pgm_check_entry: | 193 | pgm_check_entry: |