lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 16 Sep 2008 16:37:15 +0800
From:	sonic zhang <sonic.adi@...il.com>
To:	Jason Wessel <jason.wessel@...driver.com>
Cc:	Linux Kernel <linux-kernel@...r.kernel.org>,
	kgdb mailing list <kgdb-bugreport@...ts.sourceforge.net>
Subject: [PATCH] [kgdb]switch master cpu after gdb thread command for SMP

 In blackfin SMP architecture, different core has its own L1 SRAM and MMR
 memory, which code running on the other core can't access. In current kgdb
 impelemntation, cpus are represented by thread with minus prefix.

If user wants gdb to switch to the thread of the other cpu, kgdb should:
1. signal current master cpu to enter kgdb_wait
2. release the specific waiting passive cpu
3. exit kgdb exception loop on current master cpu
4. trap the release cpu into kgdb exception loop

The kgdb arch implementation with SMP support should include function
kgdb_roundup_cpu().


Signed-off-by: Sonic Zhang <sonic.adi@...il.com>
---
 include/linux/kgdb.h |   13 +++++++++++++
 kernel/kgdb.c        |   32 ++++++++++++++++++++++++++++++--
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
index cb8a3d6..5bbfdae 100644
--- a/include/linux/kgdb.h
+++ b/include/linux/kgdb.h
@@ -203,6 +203,19 @@ kgdb_arch_handle_exception(int vector, int signo, int err_code,
  */
 extern void kgdb_roundup_cpus(unsigned long flags);
 
+/**
+ *	kgdb_roundup_cpu - Get spcific CPU into a holding pattern
+ *	@cpu: Specific cpu id
+ *	@flags: Current IRQ state
+ *
+ *	On SMP systems, we need to switch cpu from current active one to
+ *	the other passive one. This get current active CPU into a known state
+ *	in kgdb_wait(). 
+ *
+ *	On non-SMP systems, this is not called.
+ */
+extern void kgdb_roundup_cpu(int cpu, unsigned long flags);
+
 /* Optional functions. */
 extern int kgdb_validate_break_address(unsigned long addr);
 extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr);
diff --git a/kernel/kgdb.c b/kernel/kgdb.c
index aae578e..852370f 100644
--- a/kernel/kgdb.c
+++ b/kernel/kgdb.c
@@ -566,6 +566,7 @@ static void kgdb_wait(struct pt_regs *regs)
 {
 	unsigned long flags;
 	int cpu;
+	struct task_struct *thread;
 
 	local_irq_save(flags);
 	cpu = raw_smp_processor_id();
@@ -585,6 +586,15 @@ static void kgdb_wait(struct pt_regs *regs)
 	kgdb_info[cpu].debuggerinfo = NULL;
 	kgdb_info[cpu].task = NULL;
 
+	/* Trap into kgdb as the active CPU if gdb asks to switch. */
+	thread = getthread(regs, -raw_smp_processor_id() - 2);
+	if (kgdb_usethread && kgdb_usethread == thread) {
+		kgdb_breakpoint();
+		clocksource_touch_watchdog();
+		local_irq_restore(flags);
+		return;
+	}
+ 
 	/* fix up hardware debug registers on local cpu */
 	if (arch_kgdb_ops.correct_hw_break)
 		arch_kgdb_ops.correct_hw_break();
@@ -1072,7 +1082,7 @@ static void gdb_cmd_query(struct kgdb_state *ks)
 }
 
 /* Handle the 'H' task query packets */
-static void gdb_cmd_task(struct kgdb_state *ks)
+static int gdb_cmd_task(struct kgdb_state *ks)
 {
 	struct task_struct *thread;
 	char *ptr;
@@ -1089,6 +1099,13 @@ static void gdb_cmd_task(struct kgdb_state *ks)
 		kgdb_usethread = thread;
 		ks->kgdb_usethreadid = ks->threadid;
 		strcpy(remcom_out_buffer, "OK");
+#ifdef CONFIG_SMP
+		if (ks->kgdb_usethreadid < -1 &&
+			ks->kgdb_usethreadid + 2 != -raw_smp_processor_id()) {
+			kgdb_roundup_cpu(-ks->kgdb_usethreadid - 2);
+			return 1;
+		}
+#endif
 		break;
 	case 'c':
 		ptr = &remcom_in_buffer[2];
@@ -1106,6 +1123,8 @@ static void gdb_cmd_task(struct kgdb_state *ks)
 		strcpy(remcom_out_buffer, "OK");
 		break;
 	}
+
+	return 0;
 }
 
 /* Handle the 'T' thread query packets */
@@ -1284,7 +1303,8 @@ static int gdb_serial_stub(struct kgdb_state *ks)
 			gdb_cmd_query(ks);
 			break;
 		case 'H': /* task related */
-			gdb_cmd_task(ks);
+			if (gdb_cmd_task(ks))
+				goto default_handle;
 			break;
 		case 'T': /* Query thread status */
 			gdb_cmd_thread(ks);
@@ -1509,6 +1529,14 @@ acquirelock:
 	kgdb_info[ks->cpu].task = NULL;
 	atomic_set(&cpu_in_kgdb[ks->cpu], 0);
 
+#ifdef CONFIG_SMP
+	i = -(ks->kgdb_usethreadid + 2);
+	if (ks->kgdb_usethreadid < -1 && i != cpu) {
+		atomic_set(&passive_cpu_wait[i], 0);
+		while (atomic_read(&cpu_in_kgdb[i]))
+			cpu_relax();
+	} else
+#endif
 	if (!kgdb_single_step || !kgdb_contthread) {
 		for (i = NR_CPUS-1; i >= 0; i--)
 			atomic_set(&passive_cpu_wait[i], 0);
-- 
1.6.0


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ