From: Jan Kiszka <jan.kiszka@domain.hid>
To: xenomai-core <xenomai@xenomai.org>
Cc: adeos-main@gna.org
Subject: [Xenomai-core] [patch] kgdb for ipipe - updated version
Date: Sun, 14 May 2006 21:33:30 +0200 [thread overview]
Message-ID: <4467860A.9020103@domain.hid> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 1152 bytes --]
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:anonymous@domain.hid"
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: kgdb-ipipe.patch --]
[-- Type: text/x-patch; name="kgdb-ipipe.patch", Size: 8518 bytes --]
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);
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.3: kgdb-ipipe-x86.patch --]
[-- Type: text/x-patch; name="kgdb-ipipe-x86.patch", Size: 4611 bytes --]
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)))
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.4: prepare-kgdb-ipipe-x86.patch --]
[-- Type: text/x-patch; name="prepare-kgdb-ipipe-x86.patch", Size: 854 bytes --]
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
[-- Attachment #1.5: series --]
[-- Type: text/plain, Size: 504 bytes --]
# 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
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]
next reply other threads:[~2006-05-14 19:33 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-14 19:33 Jan Kiszka [this message]
2006-05-14 19:41 ` [Xenomai-core] Re: [patch] kgdb for ipipe - updated version Jan Kiszka
2006-05-14 20:20 ` [Xenomai-core] Re: [Adeos-main] " Philippe Gerum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4467860A.9020103@domain.hid \
--to=jan.kiszka@domain.hid \
--cc=adeos-main@gna.org \
--cc=xenomai@xenomai.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.