--- /dev/null
+From 98b54aa1a2241b59372468bd1e9c2d207bdba54b Mon Sep 17 00:00:00 2001
+From: Jason Wessel <jason.wessel@windriver.com>
+Date: Wed, 21 Mar 2012 10:17:03 -0500
+Subject: kgdb,debug_core: pass the breakpoint struct instead of address and memory
+
+From: Jason Wessel <jason.wessel@windriver.com>
+
+commit 98b54aa1a2241b59372468bd1e9c2d207bdba54b upstream.
+
+There is extra state information that needs to be exposed in the
+kgdb_bpt structure for tracking how a breakpoint was installed. The
+debug_core only uses the the probe_kernel_write() to install
+breakpoints, but this is not enough for all the archs. Some arch such
+as x86 need to use text_poke() in order to install a breakpoint into a
+read only page.
+
+Passing the kgdb_bpt structure to kgdb_arch_set_breakpoint() and
+kgdb_arch_remove_breakpoint() allows other archs to set the type
+variable which indicates how the breakpoint was installed.
+
+Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/kgdb.h | 4 +--
+ kernel/debug/debug_core.c | 53 ++++++++++++++++++++--------------------------
+ 2 files changed, 26 insertions(+), 31 deletions(-)
+
+--- a/include/linux/kgdb.h
++++ b/include/linux/kgdb.h
+@@ -207,8 +207,8 @@ extern void kgdb_arch_set_pc(struct pt_r
+
+ /* Optional functions. */
+ extern int kgdb_validate_break_address(unsigned long addr);
+-extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr);
+-extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle);
++extern int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt);
++extern int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt);
+
+ /**
+ * kgdb_arch_late - Perform any architecture specific initalization.
+--- a/kernel/debug/debug_core.c
++++ b/kernel/debug/debug_core.c
+@@ -157,37 +157,39 @@ early_param("nokgdbroundup", opt_nokgdbr
+ * Weak aliases for breakpoint management,
+ * can be overriden by architectures when needed:
+ */
+-int __weak kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
++int __weak kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
+ {
+ int err;
+
+- err = probe_kernel_read(saved_instr, (char *)addr, BREAK_INSTR_SIZE);
++ err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
++ BREAK_INSTR_SIZE);
+ if (err)
+ return err;
+-
+- return probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr,
+- BREAK_INSTR_SIZE);
++ err = probe_kernel_write((char *)bpt->bpt_addr,
++ arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
++ return err;
+ }
+
+-int __weak kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)
++int __weak kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
+ {
+- return probe_kernel_write((char *)addr,
+- (char *)bundle, BREAK_INSTR_SIZE);
++ return probe_kernel_write((char *)bpt->bpt_addr,
++ (char *)bpt->saved_instr, BREAK_INSTR_SIZE);
+ }
+
+ int __weak kgdb_validate_break_address(unsigned long addr)
+ {
+- char tmp_variable[BREAK_INSTR_SIZE];
++ struct kgdb_bkpt tmp;
+ int err;
+- /* Validate setting the breakpoint and then removing it. In the
++ /* Validate setting the breakpoint and then removing it. If the
+ * remove fails, the kernel needs to emit a bad message because we
+ * are deep trouble not being able to put things back the way we
+ * found them.
+ */
+- err = kgdb_arch_set_breakpoint(addr, tmp_variable);
++ tmp.bpt_addr = addr;
++ err = kgdb_arch_set_breakpoint(&tmp);
+ if (err)
+ return err;
+- err = kgdb_arch_remove_breakpoint(addr, tmp_variable);
++ err = kgdb_arch_remove_breakpoint(&tmp);
+ if (err)
+ printk(KERN_ERR "KGDB: Critical breakpoint error, kernel "
+ "memory destroyed at: %lx", addr);
+@@ -231,7 +233,6 @@ static void kgdb_flush_swbreak_addr(unsi
+ */
+ int dbg_activate_sw_breakpoints(void)
+ {
+- unsigned long addr;
+ int error;
+ int ret = 0;
+ int i;
+@@ -240,16 +241,15 @@ int dbg_activate_sw_breakpoints(void)
+ if (kgdb_break[i].state != BP_SET)
+ continue;
+
+- addr = kgdb_break[i].bpt_addr;
+- error = kgdb_arch_set_breakpoint(addr,
+- kgdb_break[i].saved_instr);
++ error = kgdb_arch_set_breakpoint(&kgdb_break[i]);
+ if (error) {
+ ret = error;
+- printk(KERN_INFO "KGDB: BP install failed: %lx", addr);
++ printk(KERN_INFO "KGDB: BP install failed: %lx",
++ kgdb_break[i].bpt_addr);
+ continue;
+ }
+
+- kgdb_flush_swbreak_addr(addr);
++ kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr);
+ kgdb_break[i].state = BP_ACTIVE;
+ }
+ return ret;
+@@ -298,7 +298,6 @@ int dbg_set_sw_break(unsigned long addr)
+
+ int dbg_deactivate_sw_breakpoints(void)
+ {
+- unsigned long addr;
+ int error;
+ int ret = 0;
+ int i;
+@@ -306,15 +305,14 @@ int dbg_deactivate_sw_breakpoints(void)
+ for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
+ if (kgdb_break[i].state != BP_ACTIVE)
+ continue;
+- addr = kgdb_break[i].bpt_addr;
+- error = kgdb_arch_remove_breakpoint(addr,
+- kgdb_break[i].saved_instr);
++ error = kgdb_arch_remove_breakpoint(&kgdb_break[i]);
+ if (error) {
+- printk(KERN_INFO "KGDB: BP remove failed: %lx\n", addr);
++ printk(KERN_INFO "KGDB: BP remove failed: %lx\n",
++ kgdb_break[i].bpt_addr);
+ ret = error;
+ }
+
+- kgdb_flush_swbreak_addr(addr);
++ kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr);
+ kgdb_break[i].state = BP_SET;
+ }
+ return ret;
+@@ -348,7 +346,6 @@ int kgdb_isremovedbreak(unsigned long ad
+
+ int dbg_remove_all_break(void)
+ {
+- unsigned long addr;
+ int error;
+ int i;
+
+@@ -356,12 +353,10 @@ int dbg_remove_all_break(void)
+ for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
+ if (kgdb_break[i].state != BP_ACTIVE)
+ goto setundefined;
+- addr = kgdb_break[i].bpt_addr;
+- error = kgdb_arch_remove_breakpoint(addr,
+- kgdb_break[i].saved_instr);
++ error = kgdb_arch_remove_breakpoint(&kgdb_break[i]);
+ if (error)
+ printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n",
+- addr);
++ kgdb_break[i].bpt_addr);
+ setundefined:
+ kgdb_break[i].state = BP_UNDEFINED;
+ }
--- /dev/null
+From 486c5987a00a89d56c2c04c506417ef8f823ca2e Mon Sep 17 00:00:00 2001
+From: Jason Wessel <jason.wessel@windriver.com>
+Date: Thu, 29 Mar 2012 17:41:24 -0500
+Subject: kgdbts: (1 of 2) fix single step awareness to work correctly with SMP
+
+From: Jason Wessel <jason.wessel@windriver.com>
+
+commit 486c5987a00a89d56c2c04c506417ef8f823ca2e upstream.
+
+The do_fork and sys_open tests have never worked properly on anything
+other than a UP configuration with the kgdb test suite. This is
+because the test suite did not fully implement the behavior of a real
+debugger. A real debugger tracks the state of what thread it asked to
+single step and can correctly continue other threads of execution or
+conditionally stop while waiting for the original thread single step
+request to return.
+
+Below is a simple method to cause a fatal kernel oops with the kgdb
+test suite on a 4 processor x86 system:
+
+while [ 1 ] ; do ls > /dev/null 2> /dev/null; done&
+while [ 1 ] ; do ls > /dev/null 2> /dev/null; done&
+while [ 1 ] ; do ls > /dev/null 2> /dev/null; done&
+while [ 1 ] ; do ls > /dev/null 2> /dev/null; done&
+echo V1I1F1000 > /sys/module/kgdbts/parameters/kgdbts
+
+Very soon after starting the test the kernel will oops with a message like:
+
+kgdbts: BP mismatch 3b7da66480 expected ffffffff8106a590
+WARNING: at drivers/misc/kgdbts.c:303 check_and_rewind_pc+0xe0/0x100()
+Call Trace:
+ [<ffffffff812994a0>] check_and_rewind_pc+0xe0/0x100
+ [<ffffffff81298945>] validate_simple_test+0x25/0xc0
+ [<ffffffff81298f77>] run_simple_test+0x107/0x2c0
+ [<ffffffff81298a18>] kgdbts_put_char+0x18/0x20
+
+The warn will turn to a hard kernel crash shortly after that because
+the pc will not get properly rewound to the right value after hitting
+a breakpoint leading to a hard lockup.
+
+This change is broken up into 2 pieces because archs that have hw
+single stepping (2.6.26 and up) need different changes than archs that
+do not have hw single stepping (3.0 and up). This change implements
+the correct behavior for an arch that supports hw single stepping.
+
+A minor defect was fixed where sys_open should be do_sys_open
+for the sys_open break point test. This solves the problem of running
+a 64 bit with a 32 bit user space. The sys_open() never gets called
+when using the 32 bit file system for the kgdb testsuite because the
+32 bit binaries invoke the compat_sys_open() call leading to the test
+never completing.
+
+In order to mimic a real debugger, the kgdb test suite now tracks the
+most recent thread that was continued (cont_thread_id), with the
+intent to single step just this thread. When the response to the
+single step request stops in a different thread that hit the original
+break point that thread will now get continued, while the debugger
+waits for the thread with the single step pending. Here is a high
+level description of the sequence of events.
+
+ cont_instead_of_sstep = 0;
+
+1) set breakpoint at do_fork
+2) continue
+3) Save the thread id where we stop to cont_thread_id
+4) Remove breakpoint at do_fork
+5) Reset the PC if needed depending on kernel exception type
+6) if (cont_instead_of_sstep) { continue } else { single step }
+7) Check where we stopped
+ if current thread != cont_thread_id {
+ cont_instead_of_sstep = 1;
+ goto step 5
+ } else {
+ cont_instead_of_sstep = 0;
+ }
+8) clean up and run test again if needed
+
+Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/kgdbts.c | 54 +++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 43 insertions(+), 11 deletions(-)
+
+--- a/drivers/misc/kgdbts.c
++++ b/drivers/misc/kgdbts.c
+@@ -134,6 +134,9 @@ static int force_hwbrks;
+ static int hwbreaks_ok;
+ static int hw_break_val;
+ static int hw_break_val2;
++static int cont_instead_of_sstep;
++static unsigned long cont_thread_id;
++static unsigned long sstep_thread_id;
+ #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC)
+ static int arch_needs_sstep_emulation = 1;
+ #else
+@@ -211,7 +214,7 @@ static unsigned long lookup_addr(char *a
+ if (!strcmp(arg, "kgdbts_break_test"))
+ addr = (unsigned long)kgdbts_break_test;
+ else if (!strcmp(arg, "sys_open"))
+- addr = (unsigned long)sys_open;
++ addr = (unsigned long)do_sys_open;
+ else if (!strcmp(arg, "do_fork"))
+ addr = (unsigned long)do_fork;
+ else if (!strcmp(arg, "hw_break_val"))
+@@ -283,6 +286,16 @@ static void hw_break_val_write(void)
+ hw_break_val++;
+ }
+
++static int get_thread_id_continue(char *put_str, char *arg)
++{
++ char *ptr = &put_str[11];
++
++ if (put_str[1] != 'T' || put_str[2] != '0')
++ return 1;
++ kgdb_hex2long(&ptr, &cont_thread_id);
++ return 0;
++}
++
+ static int check_and_rewind_pc(char *put_str, char *arg)
+ {
+ unsigned long addr = lookup_addr(arg);
+@@ -324,6 +337,18 @@ static int check_single_step(char *put_s
+ gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
+ v2printk("Singlestep stopped at IP: %lx\n",
+ instruction_pointer(&kgdbts_regs));
++
++ if (sstep_thread_id != cont_thread_id && !arch_needs_sstep_emulation) {
++ /*
++ * Ensure we stopped in the same thread id as before, else the
++ * debugger should continue until the original thread that was
++ * single stepped is scheduled again, emulating gdb's behavior.
++ */
++ v2printk("ThrID does not match: %lx\n", cont_thread_id);
++ cont_instead_of_sstep = 1;
++ ts.idx -= 4;
++ return 0;
++ }
+ if (instruction_pointer(&kgdbts_regs) == addr) {
+ eprintk("kgdbts: SingleStep failed at %lx\n",
+ instruction_pointer(&kgdbts_regs));
+@@ -368,7 +393,12 @@ static int got_break(char *put_str, char
+ static void emul_sstep_get(char *arg)
+ {
+ if (!arch_needs_sstep_emulation) {
+- fill_get_buf(arg);
++ if (cont_instead_of_sstep) {
++ cont_instead_of_sstep = 0;
++ fill_get_buf("c");
++ } else {
++ fill_get_buf(arg);
++ }
+ return;
+ }
+ switch (sstep_state) {
+@@ -398,9 +428,11 @@ static void emul_sstep_get(char *arg)
+ static int emul_sstep_put(char *put_str, char *arg)
+ {
+ if (!arch_needs_sstep_emulation) {
+- if (!strncmp(put_str+1, arg, 2))
+- return 0;
+- return 1;
++ char *ptr = &put_str[11];
++ if (put_str[1] != 'T' || put_str[2] != '0')
++ return 1;
++ kgdb_hex2long(&ptr, &sstep_thread_id);
++ return 0;
+ }
+ switch (sstep_state) {
+ case 1:
+@@ -502,10 +534,10 @@ static struct test_struct bad_read_test[
+ static struct test_struct singlestep_break_test[] = {
+ { "?", "S0*" }, /* Clear break points */
+ { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
+- { "c", "T0*", }, /* Continue */
++ { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
++ { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
+ { "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
+ { "write", "OK", write_regs }, /* Write registers */
+- { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
+ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
+ { "g", "kgdbts_break_test", NULL, check_single_step },
+ { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
+@@ -523,10 +555,10 @@ static struct test_struct singlestep_bre
+ static struct test_struct do_fork_test[] = {
+ { "?", "S0*" }, /* Clear break points */
+ { "do_fork", "OK", sw_break, }, /* set sw breakpoint */
+- { "c", "T0*", }, /* Continue */
++ { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
++ { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */
+ { "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */
+ { "write", "OK", write_regs }, /* Write registers */
+- { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */
+ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
+ { "g", "do_fork", NULL, check_single_step },
+ { "do_fork", "OK", sw_break, }, /* set sw breakpoint */
+@@ -541,10 +573,10 @@ static struct test_struct do_fork_test[]
+ static struct test_struct sys_open_test[] = {
+ { "?", "S0*" }, /* Clear break points */
+ { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
+- { "c", "T0*", }, /* Continue */
++ { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
++ { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */
+ { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */
+ { "write", "OK", write_regs }, /* Write registers */
+- { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */
+ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
+ { "g", "sys_open", NULL, check_single_step },
+ { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
--- /dev/null
+From 23bbd8e346f1ef3fc1219c79cea53d8d52b207d8 Mon Sep 17 00:00:00 2001
+From: Jason Wessel <jason.wessel@windriver.com>
+Date: Thu, 29 Mar 2012 17:41:24 -0500
+Subject: kgdbts: (2 of 2) fix single step awareness to work correctly with SMP
+
+From: Jason Wessel <jason.wessel@windriver.com>
+
+commit 23bbd8e346f1ef3fc1219c79cea53d8d52b207d8 upstream.
+
+The do_fork and sys_open tests have never worked properly on anything
+other than a UP configuration with the kgdb test suite. This is
+because the test suite did not fully implement the behavior of a real
+debugger. A real debugger tracks the state of what thread it asked to
+single step and can correctly continue other threads of execution or
+conditionally stop while waiting for the original thread single step
+request to return.
+
+Below is a simple method to cause a fatal kernel oops with the kgdb
+test suite on a 2 processor ARM system:
+
+while [ 1 ] ; do ls > /dev/null 2> /dev/null; done&
+while [ 1 ] ; do ls > /dev/null 2> /dev/null; done&
+echo V1I1F100 > /sys/module/kgdbts/parameters/kgdbts
+
+Very soon after starting the test the kernel will start warning with
+messages like:
+
+kgdbts: BP mismatch c002487c expected c0024878
+------------[ cut here ]------------
+WARNING: at drivers/misc/kgdbts.c:317 check_and_rewind_pc+0x9c/0xc4()
+[<c01f6520>] (check_and_rewind_pc+0x9c/0xc4)
+[<c01f595c>] (validate_simple_test+0x3c/0xc4)
+[<c01f60d4>] (run_simple_test+0x1e8/0x274)
+
+The kernel will eventually recovers, but the test suite has completely
+failed to test anything useful.
+
+This patch implements behavior similar to a real debugger that does
+not rely on hardware single stepping by using only software planted
+breakpoints.
+
+In order to mimic a real debugger, the kgdb test suite now tracks the
+most recent thread that was continued (cont_thread_id), with the
+intent to single step just this thread. When the response to the
+single step request stops in a different thread that hit the original
+break point that thread will now get continued, while the debugger
+waits for the thread with the single step pending. Here is a high
+level description of the sequence of events.
+
+ cont_instead_of_sstep = 0;
+
+1) set breakpoint at do_fork
+2) continue
+3) Save the thread id where we stop to cont_thread_id
+4) Remove breakpoint at do_fork
+5) Reset the PC if needed depending on kernel exception type
+6) soft single step
+7) Check where we stopped
+ if current thread != cont_thread_id {
+ if (here for more than 2 times for the same thead) {
+ ### must be a really busy system, start test again ###
+ goto step 1
+ }
+ goto step 5
+ } else {
+ cont_instead_of_sstep = 0;
+ }
+8) clean up and run test again if needed
+9) Clear out any threads that were waiting on a break point at the
+ point in time the test is ended with get_cont_catch(). This
+ happens sometimes because breakpoints are used in place of single
+ stepping and some threads could have been in the debugger exception
+ handling queue because breakpoints were hit concurrently on
+ different CPUs. This also means we wait at least one second before
+ unplumbing the debugger connection at the very end, so as respond
+ to any debug threads waiting to be serviced.
+
+Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/kgdbts.c | 73 ++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 62 insertions(+), 11 deletions(-)
+
+--- a/drivers/misc/kgdbts.c
++++ b/drivers/misc/kgdbts.c
+@@ -142,7 +142,9 @@ static int arch_needs_sstep_emulation =
+ #else
+ static int arch_needs_sstep_emulation;
+ #endif
++static unsigned long cont_addr;
+ static unsigned long sstep_addr;
++static int restart_from_top_after_write;
+ static int sstep_state;
+
+ /* Storage for the registers, in GDB format. */
+@@ -190,7 +192,8 @@ static int kgdbts_unreg_thread(void *ptr
+ */
+ while (!final_ack)
+ msleep_interruptible(1500);
+-
++ /* Pause for any other threads to exit after final ack. */
++ msleep_interruptible(1000);
+ if (configured)
+ kgdb_unregister_io_module(&kgdbts_io_ops);
+ configured = 0;
+@@ -312,13 +315,21 @@ static int check_and_rewind_pc(char *put
+ if (addr + BREAK_INSTR_SIZE == ip)
+ offset = -BREAK_INSTR_SIZE;
+ #endif
+- if (strcmp(arg, "silent") && ip + offset != addr) {
++
++ if (arch_needs_sstep_emulation && sstep_addr &&
++ ip + offset == sstep_addr &&
++ ((!strcmp(arg, "sys_open") || !strcmp(arg, "do_fork")))) {
++ /* This is special case for emulated single step */
++ v2printk("Emul: rewind hit single step bp\n");
++ restart_from_top_after_write = 1;
++ } else if (strcmp(arg, "silent") && ip + offset != addr) {
+ eprintk("kgdbts: BP mismatch %lx expected %lx\n",
+ ip + offset, addr);
+ return 1;
+ }
+ /* Readjust the instruction pointer if needed */
+ ip += offset;
++ cont_addr = ip;
+ #ifdef GDB_ADJUSTS_BREAK_OFFSET
+ instruction_pointer_set(&kgdbts_regs, ip);
+ #endif
+@@ -328,6 +339,8 @@ static int check_and_rewind_pc(char *put
+ static int check_single_step(char *put_str, char *arg)
+ {
+ unsigned long addr = lookup_addr(arg);
++ static int matched_id;
++
+ /*
+ * From an arch indepent point of view the instruction pointer
+ * should be on a different instruction
+@@ -338,17 +351,28 @@ static int check_single_step(char *put_s
+ v2printk("Singlestep stopped at IP: %lx\n",
+ instruction_pointer(&kgdbts_regs));
+
+- if (sstep_thread_id != cont_thread_id && !arch_needs_sstep_emulation) {
++ if (sstep_thread_id != cont_thread_id) {
+ /*
+ * Ensure we stopped in the same thread id as before, else the
+ * debugger should continue until the original thread that was
+ * single stepped is scheduled again, emulating gdb's behavior.
+ */
+ v2printk("ThrID does not match: %lx\n", cont_thread_id);
++ if (arch_needs_sstep_emulation) {
++ if (matched_id &&
++ instruction_pointer(&kgdbts_regs) != addr)
++ goto continue_test;
++ matched_id++;
++ ts.idx -= 2;
++ sstep_state = 0;
++ return 0;
++ }
+ cont_instead_of_sstep = 1;
+ ts.idx -= 4;
+ return 0;
+ }
++continue_test:
++ matched_id = 0;
+ if (instruction_pointer(&kgdbts_regs) == addr) {
+ eprintk("kgdbts: SingleStep failed at %lx\n",
+ instruction_pointer(&kgdbts_regs));
+@@ -390,6 +414,31 @@ static int got_break(char *put_str, char
+ return 1;
+ }
+
++static void get_cont_catch(char *arg)
++{
++ /* Always send detach because the test is completed at this point */
++ fill_get_buf("D");
++}
++
++static int put_cont_catch(char *put_str, char *arg)
++{
++ /* This is at the end of the test and we catch any and all input */
++ v2printk("kgdbts: cleanup task: %lx\n", sstep_thread_id);
++ ts.idx--;
++ return 0;
++}
++
++static int emul_reset(char *put_str, char *arg)
++{
++ if (strncmp(put_str, "$OK", 3))
++ return 1;
++ if (restart_from_top_after_write) {
++ restart_from_top_after_write = 0;
++ ts.idx = -1;
++ }
++ return 0;
++}
++
+ static void emul_sstep_get(char *arg)
+ {
+ if (!arch_needs_sstep_emulation) {
+@@ -443,8 +492,7 @@ static int emul_sstep_put(char *put_str,
+ v2printk("Stopped at IP: %lx\n",
+ instruction_pointer(&kgdbts_regs));
+ /* Want to stop at IP + break instruction size by default */
+- sstep_addr = instruction_pointer(&kgdbts_regs) +
+- BREAK_INSTR_SIZE;
++ sstep_addr = cont_addr + BREAK_INSTR_SIZE;
+ break;
+ case 2:
+ if (strncmp(put_str, "$OK", 3)) {
+@@ -456,6 +504,9 @@ static int emul_sstep_put(char *put_str,
+ if (strncmp(put_str, "$T0", 3)) {
+ eprintk("kgdbts: failed continue sstep\n");
+ return 1;
++ } else {
++ char *ptr = &put_str[11];
++ kgdb_hex2long(&ptr, &sstep_thread_id);
+ }
+ break;
+ case 4:
+@@ -558,13 +609,13 @@ static struct test_struct do_fork_test[]
+ { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
+ { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */
+ { "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */
+- { "write", "OK", write_regs }, /* Write registers */
++ { "write", "OK", write_regs, emul_reset }, /* Write registers */
+ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
+ { "g", "do_fork", NULL, check_single_step },
+ { "do_fork", "OK", sw_break, }, /* set sw breakpoint */
+ { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
+ { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */
+- { "", "" },
++ { "", "", get_cont_catch, put_cont_catch },
+ };
+
+ /* Test for hitting a breakpoint at sys_open for what ever the number
+@@ -576,13 +627,13 @@ static struct test_struct sys_open_test[
+ { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
+ { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */
+ { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */
+- { "write", "OK", write_regs }, /* Write registers */
++ { "write", "OK", write_regs, emul_reset }, /* Write registers */
+ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
+ { "g", "sys_open", NULL, check_single_step },
+ { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
+ { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
+ { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */
+- { "", "" },
++ { "", "", get_cont_catch, put_cont_catch },
+ };
+
+ /*
+@@ -725,8 +776,8 @@ static int run_simple_test(int is_get_ch
+ /* This callback is a put char which is when kgdb sends data to
+ * this I/O module.
+ */
+- if (ts.tst[ts.idx].get[0] == '\0' &&
+- ts.tst[ts.idx].put[0] == '\0') {
++ if (ts.tst[ts.idx].get[0] == '\0' && ts.tst[ts.idx].put[0] == '\0' &&
++ !ts.tst[ts.idx].get_handler) {
+ eprintk("kgdbts: ERROR: beyond end of test on"
+ " '%s' line %i\n", ts.name, ts.idx);
+ return 0;
--- /dev/null
+From 456ca7ff24841bf2d2a2dfd690fe7d42ef70d932 Mon Sep 17 00:00:00 2001
+From: Jason Wessel <jason.wessel@windriver.com>
+Date: Thu, 29 Mar 2012 06:55:44 -0500
+Subject: kgdbts: Fix kernel oops with CONFIG_DEBUG_RODATA
+
+From: Jason Wessel <jason.wessel@windriver.com>
+
+commit 456ca7ff24841bf2d2a2dfd690fe7d42ef70d932 upstream.
+
+On x86 the kgdb test suite will oops when the kernel is compiled with
+CONFIG_DEBUG_RODATA and you run the tests after boot time. This is
+regression has existed since 2.6.26 by commit: b33cb815 (kgdbts: Use
+HW breakpoints with CONFIG_DEBUG_RODATA).
+
+The test suite can use hw breakpoints for all the tests, but it has to
+execute the hardware breakpoint specific tests first in order to
+determine that the hw breakpoints actually work. Specifically the
+very first test causes an oops:
+
+# echo V1I1 > /sys/module/kgdbts/parameters/kgdbts
+kgdb: Registered I/O driver kgdbts.
+kgdbts:RUN plant and detach test
+
+Entering kdb (current=0xffff880017aa9320, pid 1078) on processor 0 due to Keyboard Entry
+[0]kdb> kgdbts: ERROR PUT: end of test buffer on 'plant_and_detach_test' line 1 expected OK got $E14#aa
+WARNING: at drivers/misc/kgdbts.c:730 run_simple_test+0x151/0x2c0()
+[...oops clipped...]
+
+This commit re-orders the running of the tests and puts the RODATA
+check into its own function so as to correctly avoid the kernel oops
+by detecting and using the hw breakpoints.
+
+Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/kgdbts.c | 52 ++++++++++++++++++++++++++------------------------
+ 1 file changed, 28 insertions(+), 24 deletions(-)
+
+--- a/drivers/misc/kgdbts.c
++++ b/drivers/misc/kgdbts.c
+@@ -885,6 +885,22 @@ static void run_singlestep_break_test(vo
+ kgdbts_break_test();
+ }
+
++static void test_debug_rodata(void)
++{
++#ifdef CONFIG_DEBUG_RODATA
++ /* Until there is an api to write to read-only text segments, use
++ * HW breakpoints for the remainder of any tests, else print a
++ * failure message if hw breakpoints do not work.
++ */
++ if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) {
++ eprintk("kgdbts: HW breakpoints BROKEN, ending tests\n");
++ return;
++ }
++ force_hwbrks = 1;
++ v1printk("kgdbts:Using HW breakpoints for SW breakpoint tests\n");
++#endif /* CONFIG_DEBUG_RODATA */
++}
++
+ static void kgdbts_run_tests(void)
+ {
+ char *ptr;
+@@ -907,6 +923,18 @@ static void kgdbts_run_tests(void)
+ if (ptr)
+ sstep_test = simple_strtol(ptr+1, NULL, 10);
+
++ /* All HW break point tests */
++ if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) {
++ hwbreaks_ok = 1;
++ v1printk("kgdbts:RUN hw breakpoint test\n");
++ run_breakpoint_test(1);
++ v1printk("kgdbts:RUN hw write breakpoint test\n");
++ run_hw_break_test(1);
++ v1printk("kgdbts:RUN access write breakpoint test\n");
++ run_hw_break_test(0);
++ }
++ test_debug_rodata();
++
+ /* required internal KGDB tests */
+ v1printk("kgdbts:RUN plant and detach test\n");
+ run_plant_and_detach_test(0);
+@@ -924,35 +952,11 @@ static void kgdbts_run_tests(void)
+
+ /* ===Optional tests=== */
+
+- /* All HW break point tests */
+- if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) {
+- hwbreaks_ok = 1;
+- v1printk("kgdbts:RUN hw breakpoint test\n");
+- run_breakpoint_test(1);
+- v1printk("kgdbts:RUN hw write breakpoint test\n");
+- run_hw_break_test(1);
+- v1printk("kgdbts:RUN access write breakpoint test\n");
+- run_hw_break_test(0);
+- }
+-
+ if (nmi_sleep) {
+ v1printk("kgdbts:RUN NMI sleep %i seconds test\n", nmi_sleep);
+ run_nmi_sleep_test(nmi_sleep);
+ }
+
+-#ifdef CONFIG_DEBUG_RODATA
+- /* Until there is an api to write to read-only text segments, use
+- * HW breakpoints for the remainder of any tests, else print a
+- * failure message if hw breakpoints do not work.
+- */
+- if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) {
+- eprintk("kgdbts: HW breakpoints do not work,"
+- "skipping remaining tests\n");
+- return;
+- }
+- force_hwbrks = 1;
+-#endif /* CONFIG_DEBUG_RODATA */
+-
+ /* If the do_fork test is run it will be the last test that is
+ * executed because a kernel thread will be spawned at the very
+ * end to unregister the debug hooks.
pm-hibernate-disable-usermode-helpers-right-before-freezing-tasks.patch
pm-sleep-move-disabling-of-usermode-helpers-to-the-freezer.patch
pm-sleep-mitigate-race-between-the-freezer-and-request_firmware.patch
+kgdb-debug_core-pass-the-breakpoint-struct-instead-of-address-and-memory.patch
+kgdbts-fix-kernel-oops-with-config_debug_rodata.patch
+kgdbts-1-of-2-fix-single-step-awareness-to-work-correctly-with-smp.patch
+kgdbts-2-of-2-fix-single-step-awareness-to-work-correctly-with-smp.patch
+x86-kgdb-fix-debug_rodata-limitation-using-text_poke.patch
--- /dev/null
+From 3751d3e85cf693e10e2c47c03c8caa65e171099b Mon Sep 17 00:00:00 2001
+From: Jason Wessel <jason.wessel@windriver.com>
+Date: Fri, 23 Mar 2012 09:35:05 -0500
+Subject: x86,kgdb: Fix DEBUG_RODATA limitation using text_poke()
+
+From: Jason Wessel <jason.wessel@windriver.com>
+
+commit 3751d3e85cf693e10e2c47c03c8caa65e171099b upstream.
+
+There has long been a limitation using software breakpoints with a
+kernel compiled with CONFIG_DEBUG_RODATA going back to 2.6.26. For
+this particular patch, it will apply cleanly and has been tested all
+the way back to 2.6.36.
+
+The kprobes code uses the text_poke() function which accommodates
+writing a breakpoint into a read-only page. The x86 kgdb code can
+solve the problem similarly by overriding the default breakpoint
+set/remove routines and using text_poke() directly.
+
+The x86 kgdb code will first attempt to use the traditional
+probe_kernel_write(), and next try using a the text_poke() function.
+The break point install method is tracked such that the correct break
+point removal routine will get called later on.
+
+Cc: x86@kernel.org
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Inspried-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
+Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/kgdb.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/misc/kgdbts.c | 17 -------------
+ include/linux/kgdb.h | 3 +-
+ 3 files changed, 62 insertions(+), 18 deletions(-)
+
+--- a/arch/x86/kernel/kgdb.c
++++ b/arch/x86/kernel/kgdb.c
+@@ -43,6 +43,8 @@
+ #include <linux/smp.h>
+ #include <linux/nmi.h>
+ #include <linux/hw_breakpoint.h>
++#include <linux/uaccess.h>
++#include <linux/memory.h>
+
+ #include <asm/debugreg.h>
+ #include <asm/apicdef.h>
+@@ -740,6 +742,64 @@ void kgdb_arch_set_pc(struct pt_regs *re
+ regs->ip = ip;
+ }
+
++int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
++{
++ int err;
++ char opc[BREAK_INSTR_SIZE];
++
++ bpt->type = BP_BREAKPOINT;
++ err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
++ BREAK_INSTR_SIZE);
++ if (err)
++ return err;
++ err = probe_kernel_write((char *)bpt->bpt_addr,
++ arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
++#ifdef CONFIG_DEBUG_RODATA
++ if (!err)
++ return err;
++ /*
++ * It is safe to call text_poke() because normal kernel execution
++ * is stopped on all cores, so long as the text_mutex is not locked.
++ */
++ if (mutex_is_locked(&text_mutex))
++ return -EBUSY;
++ text_poke((void *)bpt->bpt_addr, arch_kgdb_ops.gdb_bpt_instr,
++ BREAK_INSTR_SIZE);
++ err = probe_kernel_read(opc, (char *)bpt->bpt_addr, BREAK_INSTR_SIZE);
++ if (err)
++ return err;
++ if (memcmp(opc, arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE))
++ return -EINVAL;
++ bpt->type = BP_POKE_BREAKPOINT;
++#endif /* CONFIG_DEBUG_RODATA */
++ return err;
++}
++
++int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
++{
++#ifdef CONFIG_DEBUG_RODATA
++ int err;
++ char opc[BREAK_INSTR_SIZE];
++
++ if (bpt->type != BP_POKE_BREAKPOINT)
++ goto knl_write;
++ /*
++ * It is safe to call text_poke() because normal kernel execution
++ * is stopped on all cores, so long as the text_mutex is not locked.
++ */
++ if (mutex_is_locked(&text_mutex))
++ goto knl_write;
++ text_poke((void *)bpt->bpt_addr, bpt->saved_instr, BREAK_INSTR_SIZE);
++ err = probe_kernel_read(opc, (char *)bpt->bpt_addr, BREAK_INSTR_SIZE);
++ if (err || memcmp(opc, bpt->saved_instr, BREAK_INSTR_SIZE))
++ goto knl_write;
++ return err;
++knl_write:
++#endif /* CONFIG_DEBUG_RODATA */
++ return probe_kernel_write((char *)bpt->bpt_addr,
++ (char *)bpt->saved_instr, BREAK_INSTR_SIZE);
++}
++
+ struct kgdb_arch arch_kgdb_ops = {
+ /* Breakpoint instruction: */
+ .gdb_bpt_instr = { 0xcc },
+--- a/drivers/misc/kgdbts.c
++++ b/drivers/misc/kgdbts.c
+@@ -968,22 +968,6 @@ static void run_singlestep_break_test(vo
+ kgdbts_break_test();
+ }
+
+-static void test_debug_rodata(void)
+-{
+-#ifdef CONFIG_DEBUG_RODATA
+- /* Until there is an api to write to read-only text segments, use
+- * HW breakpoints for the remainder of any tests, else print a
+- * failure message if hw breakpoints do not work.
+- */
+- if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) {
+- eprintk("kgdbts: HW breakpoints BROKEN, ending tests\n");
+- return;
+- }
+- force_hwbrks = 1;
+- v1printk("kgdbts:Using HW breakpoints for SW breakpoint tests\n");
+-#endif /* CONFIG_DEBUG_RODATA */
+-}
+-
+ static void kgdbts_run_tests(void)
+ {
+ char *ptr;
+@@ -1016,7 +1000,6 @@ static void kgdbts_run_tests(void)
+ v1printk("kgdbts:RUN access write breakpoint test\n");
+ run_hw_break_test(0);
+ }
+- test_debug_rodata();
+
+ /* required internal KGDB tests */
+ v1printk("kgdbts:RUN plant and detach test\n");
+--- a/include/linux/kgdb.h
++++ b/include/linux/kgdb.h
+@@ -63,7 +63,8 @@ enum kgdb_bptype {
+ BP_HARDWARE_BREAKPOINT,
+ BP_WRITE_WATCHPOINT,
+ BP_READ_WATCHPOINT,
+- BP_ACCESS_WATCHPOINT
++ BP_ACCESS_WATCHPOINT,
++ BP_POKE_BREAKPOINT,
+ };
+
+ enum kgdb_bpstate {