Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 495363d3 authored by Jason Wessel's avatar Jason Wessel
Browse files

kdb,debug_core: adjust master cpu switch logic against new debug_core locking



The kdb shell needs to enforce switching back to the original CPU that
took the exception before restoring normal kernel execution.  Resuming
from a different CPU than what took the original exception will cause
problems with spin locks that are freed from the a different processor
than had taken the lock.

The special logic in dbg_cpu_switch() can go away entirely with
because the state of what cpus want to be masters or slaves will
remain unchanged between entry and exit of the debug_core exception
context.

Signed-off-by: default avatarJason Wessel <jason.wessel@windriver.com>
parent dfee3a7b
Loading
Loading
Loading
Loading
+2 −14
Original line number Diff line number Diff line
@@ -460,19 +460,6 @@ static int kgdb_reenter_check(struct kgdb_state *ks)
	return 1;
}

static void dbg_cpu_switch(int cpu, int next_cpu)
{
	/* Mark the cpu we are switching away from as a slave when it
	 * holds the kgdb_active token.  This must be done so that the
	 * that all the cpus wait in for the debug core will not enter
	 * again as the master. */
	if (cpu == atomic_read(&kgdb_active)) {
		kgdb_info[cpu].exception_state |= DCPU_IS_SLAVE;
		kgdb_info[cpu].exception_state &= ~DCPU_WANT_MASTER;
	}
	kgdb_info[next_cpu].exception_state |= DCPU_NEXT_MASTER;
}

static void dbg_touch_watchdogs(void)
{
	touch_softlockup_watchdog_sync();
@@ -638,7 +625,8 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
		if (error == DBG_PASS_EVENT) {
			dbg_kdb_mode = !dbg_kdb_mode;
		} else if (error == DBG_SWITCH_CPU_EVENT) {
			dbg_cpu_switch(cpu, dbg_switch_cpu);
			kgdb_info[dbg_switch_cpu].exception_state |=
				DCPU_NEXT_MASTER;
			goto cpu_loop;
		} else {
			kgdb_info[cpu].ret_state = error;
+1 −2
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ int kdb_stub(struct kgdb_state *ks)
	}
	/* Set initial kdb state variables */
	KDB_STATE_CLEAR(KGDB_TRANS);
	kdb_initial_cpu = ks->cpu;
	kdb_initial_cpu = atomic_read(&kgdb_active);
	kdb_current_task = kgdb_info[ks->cpu].task;
	kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo;
	/* Remove any breakpoints as needed by kdb and clear single step */
@@ -105,7 +105,6 @@ int kdb_stub(struct kgdb_state *ks)
		ks->pass_exception = 1;
		KDB_FLAG_SET(CATASTROPHIC);
	}
	kdb_initial_cpu = ks->cpu;
	if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) {
		KDB_STATE_CLEAR(SSBPT);
		KDB_STATE_CLEAR(DOING_SS);
+6 −6
Original line number Diff line number Diff line
@@ -1749,13 +1749,13 @@ static int kdb_go(int argc, const char **argv)
	int nextarg;
	long offset;

	if (argc == 1) {
	if (raw_smp_processor_id() != kdb_initial_cpu) {
			kdb_printf("go <address> must be issued from the "
				   "initial cpu, do cpu %d first\n",
		kdb_printf("go must execute on the entry cpu, "
			   "please use \"cpu %d\" and then execute go\n",
			   kdb_initial_cpu);
			return KDB_ARGCOUNT;
		return KDB_BADCPUNUM;
	}
	if (argc == 1) {
		nextarg = 1;
		diag = kdbgetaddrarg(argc, argv, &nextarg,
				     &addr, &offset, NULL);