Hi all, here is an improved version of the kgdb-over-ipipe patch. This version specifically addresses the concerns Gilles brought up recently:
o No more dependencies on Xenomai, thus also no need to have the nucleus compiled into the kernel. There is now a registrable handler, ipipe_safe_current, which is invoked by the kgdb code to obtain "current". When the xeno nucleus arms its services, it overloads this handler to always provide a valid current (either the real one or init_task for kernel-only threads). o Replaced smp_processor_id with ipipe_processor_id in critical kgdb code. I haven't tested this replacement, so no guarantees here. But so far it looks consistent - at least for me. To use the kernel debugger with Xenomai, you need the latest kgdb patches [1] and have to follow the attached patch series. [BTW, there is a real alternative in case debugging does not concern hardware drivers or specific timing issues: QEMU in debugging mode. This is a really handy and fast way do step through the nucleus and skins, just give it a try!] Jan [1] CVSROOT=":pserver:[EMAIL PROTECTED]:/cvsroot/kgdb"
Index: linux-2.6.15.3-kgdb/kernel/kgdb.c
===================================================================
--- linux-2.6.15.3-kgdb.orig/kernel/kgdb.c
+++ linux-2.6.15.3-kgdb/kernel/kgdb.c
@@ -740,12 +740,12 @@ static void kgdb_wait(struct pt_regs *re
unsigned long flags;
int processor;
- local_irq_save(flags);
- processor = smp_processor_id();
+ local_irq_save_hw(flags);
+ processor = ipipe_processor_id();
kgdb_info[processor].debuggerinfo = regs;
- kgdb_info[processor].task = current;
+ kgdb_info[processor].task = ipipe_safe_current();
atomic_set(&procindebug[processor], 1);
- atomic_set(&kgdb_sync_softlockup[smp_processor_id()],1);
+ atomic_set(&kgdb_sync_softlockup[ipipe_processor_id()],1);
/* Wait till master processor goes completely into the debugger.
* FIXME: this looks racy */
@@ -770,7 +770,7 @@ static void kgdb_wait(struct pt_regs *re
/* Signal the master processor that we are done */
atomic_set(&procindebug[processor], 0);
spin_unlock(&slavecpulocks[processor]);
- local_irq_restore(flags);
+ local_irq_restore_hw(flags);
}
#endif
@@ -821,7 +821,8 @@ int kgdb_activate_sw_breakpoints(void)
return error;
if (CACHE_FLUSH_IS_SAFE) {
- if (current->mm && addr < TASK_SIZE)
+ if (ipipe_safe_current() == current &&
+ current->mm && addr < TASK_SIZE)
flush_cache_range(current->mm->mmap_cache,
addr, addr + BREAK_INSTR_SIZE);
else
@@ -884,8 +885,8 @@ int kgdb_deactivate_sw_breakpoints(void)
kgdb_break[i].saved_instr)))
return error;
- if (CACHE_FLUSH_IS_SAFE && current->mm &&
- addr < TASK_SIZE)
+ if (CACHE_FLUSH_IS_SAFE && ipipe_safe_current() == current &&
+ current->mm && addr < TASK_SIZE)
flush_cache_range(current->mm->mmap_cache,
addr, addr + BREAK_INSTR_SIZE);
else if (CACHE_FLUSH_IS_SAFE)
@@ -950,7 +951,7 @@ static inline int shadow_pid(int realpid
if (realpid) {
return realpid;
}
- return pid_max + smp_processor_id();
+ return pid_max + ipipe_processor_id();
}
static char gdbmsgbuf[BUFMAX + 1];
@@ -1014,11 +1015,11 @@ int kgdb_handle_exception(int ex_vector,
long kgdb_usethreadid = 0;
int error = 0, all_cpus_synced = 0;
struct pt_regs *shadowregs;
- int processor = smp_processor_id();
+ int processor = ipipe_processor_id();
void *local_debuggerinfo;
/* Panic on recursive debugger calls. */
- if (atomic_read(&debugger_active) == smp_processor_id() + 1)
+ if (atomic_read(&debugger_active) == ipipe_processor_id() + 1)
return 0;
acquirelock:
@@ -1033,10 +1034,10 @@ int kgdb_handle_exception(int ex_vector,
* Interrupts will be restored by the 'trap return' code, except when
* single stepping.
*/
- local_irq_save(flags);
+ local_irq_save_hw(flags);
/* Hold debugger_active */
- procid = smp_processor_id();
+ procid = ipipe_processor_id();
while (cmpxchg(&atomic_read(&debugger_active), 0, (procid + 1)) != 0) {
int i = 25; /* an arbitrary number */
@@ -1056,11 +1057,11 @@ int kgdb_handle_exception(int ex_vector,
if (atomic_read(&cpu_doing_single_step) != -1 &&
atomic_read(&cpu_doing_single_step) != procid) {
atomic_set(&debugger_active, 0);
- local_irq_restore(flags);
+ local_irq_restore_hw(flags);
goto acquirelock;
}
- atomic_set(&kgdb_sync_softlockup[smp_processor_id()], 1);
+ atomic_set(&kgdb_sync_softlockup[ipipe_processor_id()], 1);
/*
* Don't enter if we have hit a removed breakpoint.
@@ -1069,7 +1070,7 @@ int kgdb_handle_exception(int ex_vector,
goto kgdb_restore;
kgdb_info[processor].debuggerinfo = linux_regs;
- kgdb_info[processor].task = current;
+ kgdb_info[processor].task = ipipe_safe_current();
kgdb_disable_hw_debug(linux_regs);
@@ -1121,7 +1122,8 @@ int kgdb_handle_exception(int ex_vector,
*ptr++ = hexchars[(signo >> 4) % 16];
*ptr++ = hexchars[signo % 16];
ptr += strlen(strcpy(ptr, "thread:"));
- int_to_threadref(&thref, shadow_pid(current->pid));
+ int_to_threadref(&thref,
+ shadow_pid(ipipe_safe_current()->pid));
ptr = pack_threadid(ptr, &thref);
*ptr++ = ';';
@@ -1213,7 +1215,8 @@ int kgdb_handle_exception(int ex_vector,
kgdb_hex2mem(&remcom_in_buffer[1], (char *)gdb_regs,
NUMREGBYTES);
- if (kgdb_usethread && kgdb_usethread != current)
+ if (kgdb_usethread &&
+ kgdb_usethread != ipipe_safe_current())
error_packet(remcom_out_buffer, -EINVAL);
else {
gdb_regs_to_regs(gdb_regs, linux_regs);
@@ -1334,7 +1337,8 @@ int kgdb_handle_exception(int ex_vector,
/* Current thread id */
strcpy(remcom_out_buffer, "QC");
- threadid = shadow_pid(current->pid);
+ threadid =
+ shadow_pid(ipipe_safe_current()->pid);
int_to_threadref(&thref, threadid);
pack_threadid(remcom_out_buffer + 2, &thref);
@@ -1488,7 +1492,8 @@ int kgdb_handle_exception(int ex_vector,
break;
case 'c':
case 's':
- if (kgdb_contthread && kgdb_contthread != current) {
+ if (kgdb_contthread &&
+ kgdb_contthread != ipipe_safe_current()) {
/* Can't switch threads in kgdb */
error_packet(remcom_out_buffer, -EINVAL);
break;
@@ -1556,7 +1561,7 @@ int kgdb_handle_exception(int ex_vector,
kgdb_restore:
/* Free debugger_active */
atomic_set(&debugger_active, 0);
- local_irq_restore(flags);
+ local_irq_restore_hw(flags);
return error;
}
@@ -1925,9 +1930,9 @@ static int kgdb_notify_reboot(struct not
if (!kgdb_connected || atomic_read(&debugger_active) != 0)
return 0;
if ((code == SYS_RESTART) || (code == SYS_HALT) || (code == SYS_POWER_OFF)){
- local_irq_save(flags);
+ local_irq_save_hw(flags);
put_packet("X00");
- local_irq_restore(flags);
+ local_irq_restore_hw(flags);
}
return NOTIFY_DONE;
}
@@ -1942,9 +1947,9 @@ void kgdb_console_write(struct console *
if (!kgdb_connected || atomic_read(&debugger_active) != 0)
return;
- local_irq_save(flags);
+ local_irq_save_hw(flags);
kgdb_msg_write(s, count);
- local_irq_restore(flags);
+ local_irq_restore_hw(flags);
}
static struct console kgdbcons = {
@@ -1974,3 +1979,12 @@ static int __init opt_kgdb_enter(char *s
}
early_param("kgdbwait", opt_kgdb_enter);
+
+struct task_struct *ipipe_default_current(void)
+{
+ return current;
+}
+EXPORT_SYMBOL(ipipe_default_current);
+
+struct task_struct *(*ipipe_safe_current)(void) = ipipe_default_current;
+EXPORT_SYMBOL(ipipe_safe_current);
Index: linux-2.6.15.3-kgdb/drivers/serial/8250_kgdb.c
===================================================================
--- linux-2.6.15.3-kgdb.orig/drivers/serial/8250_kgdb.c
+++ linux-2.6.15.3-kgdb/drivers/serial/8250_kgdb.c
@@ -301,6 +301,10 @@ static void __init kgdb8250_late_init(vo
"GDB-stub", current_port) < 0)
printk(KERN_ERR "KGDB failed to request the serial IRQ (%d)\n",
current_port->irq);
+#ifdef CONFIG_IPIPE
+ ipipe_control_irq(current_port->irq, 0,
+ IPIPE_HANDLE_MASK|IPIPE_STICKY_MASK|IPIPE_SYSTEM_MASK);
+#endif /* CONFIG_IPIPE */
}
static __init int kgdb_init_io(void)
Index: linux-2.6.15.3-kgdb/lib/Kconfig.debug
===================================================================
--- linux-2.6.15.3-kgdb.orig/lib/Kconfig.debug
+++ linux-2.6.15.3-kgdb/lib/Kconfig.debug
@@ -250,7 +250,7 @@ choice
config KGDB_ONLY_MODULES
bool "KGDB: Use only kernel modules for I/O"
- depends on MODULES
+ depends on MODULES && !IPIPE
help
Use only kernel modules to configure KGDB I/O after the
kernel is booted.
@@ -295,7 +295,7 @@ config KGDB_SIBYTE
endchoice
config KGDBOE
- tristate "KGDB: On ethernet" if !KGDBOE_NOMODULE
+ tristate "KGDB: On ethernet" if !KGDBOE_NOMODULE && !IPIPE
depends on m && KGDB
select NETPOLL
select NETPOLL_TRAP
Index: linux-2.6.15.3-kgdb/include/linux/kgdb.h
===================================================================
--- linux-2.6.15.3-kgdb.orig/include/linux/kgdb.h
+++ linux-2.6.15.3-kgdb/include/linux/kgdb.h
@@ -267,6 +267,9 @@ extern int kgdb_handle_exception(int ex_
extern void kgdb_nmihook(int cpu, void *regs);
extern int debugger_step;
extern atomic_t debugger_active;
+
+struct task_struct *ipipe_default_current(void);
+extern struct task_struct *(*ipipe_safe_current)(void);
#else
/* Stubs for when KGDB is not set. */
static const atomic_t debugger_active = ATOMIC_INIT(0);
Index: linux-2.6.15.3-kgdb/arch/i386/kernel/entry.S
===================================================================
--- linux-2.6.15.3-kgdb.orig/arch/i386/kernel/entry.S
+++ linux-2.6.15.3-kgdb/arch/i386/kernel/entry.S
@@ -194,7 +194,7 @@ VM_MASK = 0x00020000
.previous
-ENTRY(ret_from_fork)
+KPROBE_ENTRY(ret_from_fork)
STI_COND_HW
pushl %eax
call schedule_tail
@@ -582,7 +582,7 @@ ENTRY(simd_coprocessor_error)
PUSH_XCODE(do_simd_coprocessor_error)
jmp error_code
-ENTRY(device_not_available)
+KPROBE_ENTRY(device_not_available)
pushl $-1 # mark this as an int
SAVE_ALL
DIVERT_EXCEPTION(device_not_available)
@@ -767,7 +767,7 @@ ENTRY(machine_check)
jmp error_code
#endif
-ENTRY(spurious_interrupt_bug)
+KPROBE_ENTRY(spurious_interrupt_bug)
pushl $0
PUSH_XCODE(do_spurious_interrupt_bug)
jmp error_code
Index: linux-2.6.15.3-kgdb/arch/i386/kernel/ipipe-root.c
===================================================================
--- linux-2.6.15.3-kgdb.orig/arch/i386/kernel/ipipe-root.c
+++ linux-2.6.15.3-kgdb/arch/i386/kernel/ipipe-root.c
@@ -34,6 +34,9 @@
#include <asm/irq.h>
#include <asm/desc.h>
#include <asm/io.h>
+#ifdef CONFIG_KGDB
+#include <linux/kgdb.h>
+#endif /* CONFIG_KGDB */
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/tlbflush.h>
#include <asm/fixmap.h>
@@ -422,8 +425,44 @@ static __ipipe_exptr __ipipe_std_extable
[ex_do_iret_error] = &do_iret_error,
};
+#ifdef CONFIG_KGDB
+static int __ipipe_xlate_signo[] = {
+
+ [ex_do_divide_error] = SIGFPE,
+ [ex_do_debug] = SIGTRAP,
+ [2] = -1,
+ [ex_do_int3] = SIGTRAP,
+ [ex_do_overflow] = SIGSEGV,
+ [ex_do_bounds] = SIGSEGV,
+ [ex_do_invalid_op] = SIGILL,
+ [ex_device_not_available] = -1,
+ [8] = -1,
+ [ex_do_coprocessor_segment_overrun] = SIGFPE,
+ [ex_do_invalid_TSS] = SIGSEGV,
+ [ex_do_segment_not_present] = SIGBUS,
+ [ex_do_stack_segment] = SIGBUS,
+ [ex_do_general_protection] = SIGSEGV,
+ [ex_do_page_fault] = SIGSEGV,
+ [ex_do_spurious_interrupt_bug] = -1,
+ [ex_do_coprocessor_error] = -1,
+ [ex_do_alignment_check] = SIGBUS,
+ [ex_machine_check_vector] = -1,
+ [ex_do_simd_coprocessor_error] = -1,
+ [20 ... 31] = -1,
+ [ex_do_iret_error] = SIGSEGV,
+};
+#endif /* CONFIG_KGDB */
+
fastcall int __ipipe_handle_exception(struct pt_regs *regs, long error_code, int vector)
{
+#ifdef CONFIG_KGDB
+ /* catch exception KGDB is interested in over non-root domains */
+ if ((ipipe_current_domain != ipipe_root_domain) &&
+ (__ipipe_xlate_signo[vector] >= 0) &&
+ !kgdb_handle_exception(vector, __ipipe_xlate_signo[vector], error_code, regs))
+ return 1;
+#endif /* CONFIG_KGDB */
+
if (!__ipipe_event_pipelined_p(vector) ||
__ipipe_dispatch_event(vector,regs) == 0) {
__ipipe_exptr handler = __ipipe_std_extable[vector];
@@ -437,6 +476,19 @@ fastcall int __ipipe_handle_exception(st
fastcall int __ipipe_divert_exception(struct pt_regs *regs, int vector)
{
+#ifdef CONFIG_KGDB
+ /* catch int1 and int3 over non-root domains */
+ if ((ipipe_current_domain != ipipe_root_domain) &&
+ (vector != ex_device_not_available)) {
+ unsigned int condition = 0;
+
+ if (vector == 1)
+ get_debugreg(condition, 6);
+ if (!kgdb_handle_exception(vector, SIGTRAP, condition, regs))
+ return 1;
+ }
+#endif /* CONFIG_KGDB */
+
if (__ipipe_event_pipelined_p(vector) &&
__ipipe_dispatch_event(vector,regs) != 0)
return 1;
Index: linux-2.6.15.3-kgdb/arch/i386/kernel/kgdb.c
===================================================================
--- linux-2.6.15.3-kgdb.orig/arch/i386/kernel/kgdb.c
+++ linux-2.6.15.3-kgdb/arch/i386/kernel/kgdb.c
@@ -276,7 +276,8 @@ int kgdb_arch_handle_exception(int e_vec
if (remcom_in_buffer[0] == 's') {
linux_regs->eflags |= TF_MASK;
debugger_step = 1;
- atomic_set(&cpu_doing_single_step,smp_processor_id());
+ atomic_set(&cpu_doing_single_step,
+ ipipe_processor_id());
}
asm volatile ("movl %%db6, %0\n":"=r" (dr6));
@@ -319,7 +320,7 @@ static int kgdb_notify(struct notifier_b
else if ((cmd == DIE_NMI || cmd == DIE_NMI_IPI ||
cmd == DIE_NMIWATCHDOG) && atomic_read(&debugger_active)) {
/* CPU roundup */
- kgdb_nmihook(smp_processor_id(), regs);
+ kgdb_nmihook(ipipe_processor_id(), regs);
return NOTIFY_STOP;
} else if (cmd == DIE_NMI_IPI || cmd == DIE_NMI || user_mode(regs) ||
(cmd == DIE_DEBUG && atomic_read(&debugger_active)))
Index: linux-2.6.15.3-kgdb/arch/i386/kernel/entry.S =================================================================== --- linux-2.6.15.3-kgdb.orig/arch/i386/kernel/entry.S +++ linux-2.6.15.3-kgdb/arch/i386/kernel/entry.S @@ -123,7 +123,7 @@ VM_MASK = 0x00020000 .previous -KPROBE_ENTRY(ret_from_fork) +ENTRY(ret_from_fork) pushl %eax call schedule_tail GET_THREAD_INFO(%ebp) @@ -470,7 +470,7 @@ ENTRY(simd_coprocessor_error) pushl $do_simd_coprocessor_error jmp error_code -KPROBE_ENTRY(device_not_available) +ENTRY(device_not_available) pushl $-1 # mark this as an int SAVE_ALL movl %cr0, %eax @@ -652,7 +652,7 @@ ENTRY(machine_check) jmp error_code #endif -KPROBE_ENTRY(spurious_interrupt_bug) +ENTRY(spurious_interrupt_bug) pushl $0 pushl $do_spurious_interrupt_bug jmp error_code
# Patchdir: linux-2.6.15.5 # Source: linux-2.6.15.5.tar.bz2 core-lite.patch 8250.patch netpoll_pass_skb_to_rx_hook.patch eth.patch i386-lite.patch powerpc-lite.patch mips-lite.patch ia64-lite.patch x86_64-no_context_hook.patch x86_64-lite.patch sh-lite.patch arm-lite.patch cfi_annotations.patch sysrq_bugfix.patch module.patch core.patch i386.patch powerpc.patch prepare-kgdb-ipipe-x86.patch adeos-ipipe-2.6.15-i386-1.3-02.patch kgdb-ipipe.patch kgdb-ipipe-x86.patch
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Adeos-main mailing list [email protected] https://mail.gna.org/listinfo/adeos-main
