diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-04 20:26:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-04 20:26:08 -0400 |
commit | 6c216ec636f75d834461be15f83ec41a6759bd2b (patch) | |
tree | 505ab410c3208e586fd7db0bb97364d8dac490a1 /kernel | |
parent | 58bca4a8fa90fcf9069379653b396b2cec642f7f (diff) | |
parent | 3751d3e85cf693e10e2c47c03c8caa65e171099b (diff) |
Merge tag 'for_linus-3.4-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb
Pull KGDB/KDB regression fixes from Jason Wessel:
- Fix a Smatch warning that appeared in the 3.4 merge window
- Fix kgdb test suite with SMP for all archs without HW single stepping
- Fix kgdb sw breakpoints with CONFIG_DEBUG_RODATA=y limitations on x86
- Fix oops on kgdb test suite with CONFIG_DEBUG_RODATA
- Fix kgdb test suite with SMP for all archs with HW single stepping
* tag 'for_linus-3.4-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb:
x86,kgdb: Fix DEBUG_RODATA limitation using text_poke()
kgdb,debug_core: pass the breakpoint struct instead of address and memory
kgdbts: (2 of 2) fix single step awareness to work correctly with SMP
kgdbts: (1 of 2) fix single step awareness to work correctly with SMP
kgdbts: Fix kernel oops with CONFIG_DEBUG_RODATA
kdb: Fix smatch warning on dbg_io_ops->is_console
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/debug/debug_core.c | 53 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_io.c | 2 |
2 files changed, 25 insertions, 30 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 1dc53bae56e1..0557f24c6bca 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
@@ -160,37 +160,39 @@ early_param("nokgdbroundup", opt_nokgdbroundup); | |||
160 | * Weak aliases for breakpoint management, | 160 | * Weak aliases for breakpoint management, |
161 | * can be overriden by architectures when needed: | 161 | * can be overriden by architectures when needed: |
162 | */ | 162 | */ |
163 | int __weak kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) | 163 | int __weak kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) |
164 | { | 164 | { |
165 | int err; | 165 | int err; |
166 | 166 | ||
167 | err = probe_kernel_read(saved_instr, (char *)addr, BREAK_INSTR_SIZE); | 167 | err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, |
168 | BREAK_INSTR_SIZE); | ||
168 | if (err) | 169 | if (err) |
169 | return err; | 170 | return err; |
170 | 171 | err = probe_kernel_write((char *)bpt->bpt_addr, | |
171 | return probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr, | 172 | arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); |
172 | BREAK_INSTR_SIZE); | 173 | return err; |
173 | } | 174 | } |
174 | 175 | ||
175 | int __weak kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) | 176 | int __weak kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) |
176 | { | 177 | { |
177 | return probe_kernel_write((char *)addr, | 178 | return probe_kernel_write((char *)bpt->bpt_addr, |
178 | (char *)bundle, BREAK_INSTR_SIZE); | 179 | (char *)bpt->saved_instr, BREAK_INSTR_SIZE); |
179 | } | 180 | } |
180 | 181 | ||
181 | int __weak kgdb_validate_break_address(unsigned long addr) | 182 | int __weak kgdb_validate_break_address(unsigned long addr) |
182 | { | 183 | { |
183 | char tmp_variable[BREAK_INSTR_SIZE]; | 184 | struct kgdb_bkpt tmp; |
184 | int err; | 185 | int err; |
185 | /* Validate setting the breakpoint and then removing it. In the | 186 | /* Validate setting the breakpoint and then removing it. If the |
186 | * remove fails, the kernel needs to emit a bad message because we | 187 | * remove fails, the kernel needs to emit a bad message because we |
187 | * are deep trouble not being able to put things back the way we | 188 | * are deep trouble not being able to put things back the way we |
188 | * found them. | 189 | * found them. |
189 | */ | 190 | */ |
190 | err = kgdb_arch_set_breakpoint(addr, tmp_variable); | 191 | tmp.bpt_addr = addr; |
192 | err = kgdb_arch_set_breakpoint(&tmp); | ||
191 | if (err) | 193 | if (err) |
192 | return err; | 194 | return err; |
193 | err = kgdb_arch_remove_breakpoint(addr, tmp_variable); | 195 | err = kgdb_arch_remove_breakpoint(&tmp); |
194 | if (err) | 196 | if (err) |
195 | printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " | 197 | printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " |
196 | "memory destroyed at: %lx", addr); | 198 | "memory destroyed at: %lx", addr); |
@@ -234,7 +236,6 @@ static void kgdb_flush_swbreak_addr(unsigned long addr) | |||
234 | */ | 236 | */ |
235 | int dbg_activate_sw_breakpoints(void) | 237 | int dbg_activate_sw_breakpoints(void) |
236 | { | 238 | { |
237 | unsigned long addr; | ||
238 | int error; | 239 | int error; |
239 | int ret = 0; | 240 | int ret = 0; |
240 | int i; | 241 | int i; |
@@ -243,16 +244,15 @@ int dbg_activate_sw_breakpoints(void) | |||
243 | if (kgdb_break[i].state != BP_SET) | 244 | if (kgdb_break[i].state != BP_SET) |
244 | continue; | 245 | continue; |
245 | 246 | ||
246 | addr = kgdb_break[i].bpt_addr; | 247 | error = kgdb_arch_set_breakpoint(&kgdb_break[i]); |
247 | error = kgdb_arch_set_breakpoint(addr, | ||
248 | kgdb_break[i].saved_instr); | ||
249 | if (error) { | 248 | if (error) { |
250 | ret = error; | 249 | ret = error; |
251 | printk(KERN_INFO "KGDB: BP install failed: %lx", addr); | 250 | printk(KERN_INFO "KGDB: BP install failed: %lx", |
251 | kgdb_break[i].bpt_addr); | ||
252 | continue; | 252 | continue; |
253 | } | 253 | } |
254 | 254 | ||
255 | kgdb_flush_swbreak_addr(addr); | 255 | kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr); |
256 | kgdb_break[i].state = BP_ACTIVE; | 256 | kgdb_break[i].state = BP_ACTIVE; |
257 | } | 257 | } |
258 | return ret; | 258 | return ret; |
@@ -301,7 +301,6 @@ int dbg_set_sw_break(unsigned long addr) | |||
301 | 301 | ||
302 | int dbg_deactivate_sw_breakpoints(void) | 302 | int dbg_deactivate_sw_breakpoints(void) |
303 | { | 303 | { |
304 | unsigned long addr; | ||
305 | int error; | 304 | int error; |
306 | int ret = 0; | 305 | int ret = 0; |
307 | int i; | 306 | int i; |
@@ -309,15 +308,14 @@ int dbg_deactivate_sw_breakpoints(void) | |||
309 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 308 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
310 | if (kgdb_break[i].state != BP_ACTIVE) | 309 | if (kgdb_break[i].state != BP_ACTIVE) |
311 | continue; | 310 | continue; |
312 | addr = kgdb_break[i].bpt_addr; | 311 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); |
313 | error = kgdb_arch_remove_breakpoint(addr, | ||
314 | kgdb_break[i].saved_instr); | ||
315 | if (error) { | 312 | if (error) { |
316 | printk(KERN_INFO "KGDB: BP remove failed: %lx\n", addr); | 313 | printk(KERN_INFO "KGDB: BP remove failed: %lx\n", |
314 | kgdb_break[i].bpt_addr); | ||
317 | ret = error; | 315 | ret = error; |
318 | } | 316 | } |
319 | 317 | ||
320 | kgdb_flush_swbreak_addr(addr); | 318 | kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr); |
321 | kgdb_break[i].state = BP_SET; | 319 | kgdb_break[i].state = BP_SET; |
322 | } | 320 | } |
323 | return ret; | 321 | return ret; |
@@ -351,7 +349,6 @@ int kgdb_isremovedbreak(unsigned long addr) | |||
351 | 349 | ||
352 | int dbg_remove_all_break(void) | 350 | int dbg_remove_all_break(void) |
353 | { | 351 | { |
354 | unsigned long addr; | ||
355 | int error; | 352 | int error; |
356 | int i; | 353 | int i; |
357 | 354 | ||
@@ -359,12 +356,10 @@ int dbg_remove_all_break(void) | |||
359 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 356 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
360 | if (kgdb_break[i].state != BP_ACTIVE) | 357 | if (kgdb_break[i].state != BP_ACTIVE) |
361 | goto setundefined; | 358 | goto setundefined; |
362 | addr = kgdb_break[i].bpt_addr; | 359 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); |
363 | error = kgdb_arch_remove_breakpoint(addr, | ||
364 | kgdb_break[i].saved_instr); | ||
365 | if (error) | 360 | if (error) |
366 | printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", | 361 | printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", |
367 | addr); | 362 | kgdb_break[i].bpt_addr); |
368 | setundefined: | 363 | setundefined: |
369 | kgdb_break[i].state = BP_UNDEFINED; | 364 | kgdb_break[i].state = BP_UNDEFINED; |
370 | } | 365 | } |
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 9b5f17da1c56..bb9520f0f6ff 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c | |||
@@ -743,7 +743,7 @@ kdb_printit: | |||
743 | kdb_input_flush(); | 743 | kdb_input_flush(); |
744 | c = console_drivers; | 744 | c = console_drivers; |
745 | 745 | ||
746 | if (!dbg_io_ops->is_console) { | 746 | if (dbg_io_ops && !dbg_io_ops->is_console) { |
747 | len = strlen(moreprompt); | 747 | len = strlen(moreprompt); |
748 | cp = moreprompt; | 748 | cp = moreprompt; |
749 | while (len--) { | 749 | while (len--) { |