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

Commit 737a460f authored by Jason Wessel's avatar Jason Wessel Committed by Ingo Molnar
Browse files

kgdb: fix several kgdb regressions



kgdb core fixes:
- Check to see that mm->mmap_cache is not null before calling
  flush_cache_range(), else on arch=ARM it will cause a fatal
  fault.

- Breakpoints should only be restored if they are in the BP_ACTIVE
  state.

- Fix a typo in comments to "kgdb_register_io_module"

x86 kgdb fixes:
- Fix the x86 arch handler such that on a kill or detach that the
  appropriate cleanup on the single stepping flags gets run.

- Add in the DIE_NMIWATCHDOG call for x86_64

- Touch the nmi watchdog before returning the system to normal
  operation after performing any kind of kgdb operation, else
  the possibility exists to trigger the watchdog.

Signed-off-by: default avatarJason Wessel <jason.wessel@windriver.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 84b5ae15
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -370,6 +370,8 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
		ptr = &remcomInBuffer[1];
		if (kgdb_hex2long(&ptr, &addr))
			linux_regs->ip = addr;
	case 'D':
	case 'k':
		newPC = linux_regs->ip;

		/* clear the trace bit */
@@ -480,6 +482,8 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd)
	if (kgdb_handle_exception(args->trapnr, args->signr, args->err, regs))
		return NOTIFY_DONE;

	/* Must touch watchdog before return to normal operation */
	touch_nmi_watchdog();
	return NOTIFY_STOP;
}

+6 −1
Original line number Diff line number Diff line
@@ -600,8 +600,13 @@ void die(const char * str, struct pt_regs * regs, long err)

void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic)
{
	unsigned long flags = oops_begin();
	unsigned long flags;

	if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) ==
	    NOTIFY_STOP)
		return;

	flags = oops_begin();
	/*
	 * We are in trouble anyway, lets at least try
	 * to get a message out.
+8 −6
Original line number Diff line number Diff line
@@ -600,7 +600,7 @@ static void kgdb_flush_swbreak_addr(unsigned long addr)
	if (!CACHE_FLUSH_IS_SAFE)
		return;

	if (current->mm) {
	if (current->mm && current->mm->mmap_cache) {
		flush_cache_range(current->mm->mmap_cache,
				  addr, addr + BREAK_INSTR_SIZE);
	} else {
@@ -729,14 +729,16 @@ int remove_all_break(void)

	/* Clear memory breakpoints. */
	for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
		if (kgdb_break[i].state != BP_SET)
			continue;
		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);
		if (error)
			return error;
		kgdb_break[i].state = BP_REMOVED;
			printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n",
			   addr);
setundefined:
		kgdb_break[i].state = BP_UNDEFINED;
	}

	/* Clear hardware breakpoints. */
@@ -1605,7 +1607,7 @@ static void kgdb_initial_breakpoint(void)
}

/**
 *	kkgdb_register_io_module - register KGDB IO module
 *	kgdb_register_io_module - register KGDB IO module
 *	@new_kgdb_io_ops: the io ops vector
 *
 *	Register it with the KGDB core.