mirror of https://github.com/l4ka/pistachio.git
- Minor spinlock debugging fix
- In rare cases, we might get a NMI (or breakpoint exception) just after sys_ipc has been invoked, but _before_ esp has been set to tss.esp0 in that case, we need to switch stacks manually and preserve the processor-saved frame. We make sure that, before tss there is enough scratch space to cover EFLAGS, CS, and EIP saved by the processor; this way, we can get around without having to spend KDB its own interrupt task gate
This commit is contained in:
parent
cd7e97b512
commit
37031aa006
|
@ -1,6 +1,6 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002-2003, 2007, Karlsruhe University
|
||||
* Copyright (C) 2002-2003, 2007-2008, Karlsruhe University
|
||||
*
|
||||
* File path: arch/x86/x32/trapgate.h
|
||||
* Description: defines macros for implementation of trap and
|
||||
|
@ -109,6 +109,39 @@ public:
|
|||
#endif
|
||||
|
||||
|
||||
#if defined(X86_EXC_KDB)
|
||||
|
||||
/* js: in rare cases, we might get a NMI (or breakpoint exception) just
|
||||
* after sys_ipc has been invoked, but _before_ esp has been set to tss.esp0
|
||||
* in that case, we need to switch stacks manually and preserve the
|
||||
* processor-saved frame. We make sure that, before tss there is enough scratch
|
||||
* space to cover EFLAGS, CS, and EIP saved by the processor; this way, we can
|
||||
* get along without having to establish a interrupt task xgate for KDB
|
||||
*/
|
||||
#define kdb_check_stack() \
|
||||
"push %%ebp \n" \
|
||||
"lea (tss - 12), %%ebp \n" \
|
||||
"cmpl %%esp, %%ebp \n" \
|
||||
"pop %%ebp \n" \
|
||||
"jne 1f \n" \
|
||||
"addl $12, %%esp \n" \
|
||||
"movl (%%esp), %%esp \n" \
|
||||
"subl $12, %%esp \n" \
|
||||
"push %%ebp \n" \
|
||||
"mov (tss ), %%ebp \n" \
|
||||
"mov %%ebp, 12(%%esp) \n" \
|
||||
"mov (tss - 4), %%ebp \n" \
|
||||
"mov %%ebp, 8(%%esp) \n" \
|
||||
"mov (tss - 8), %%ebp \n" \
|
||||
"add $3, %%ebp \n" \
|
||||
"mov %%ebp, 4(%%esp) \n" \
|
||||
"pop %%ebp \n" \
|
||||
"1: \n"
|
||||
#else
|
||||
#define kdb_check_stack()
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* X86_EXCWITH_ERRORCODE: allows C implementation of
|
||||
* exception handlers and trap/interrupt gates with error
|
||||
|
@ -148,7 +181,6 @@ static void name##handler(x86_exceptionframe_t * frame)
|
|||
|
||||
|
||||
|
||||
|
||||
#define X86_EXCNO_ERRORCODE(name, reason) \
|
||||
extern "C" void name (void); \
|
||||
static void name##handler(x86_exceptionframe_t * frame); \
|
||||
|
@ -158,6 +190,7 @@ void name##_wrapper() \
|
|||
".global "#name " \n" \
|
||||
"\t.type "#name",@function \n" \
|
||||
#name": \n" \
|
||||
kdb_check_stack() \
|
||||
"subl $4, %%esp \n" \
|
||||
"pusha \n" \
|
||||
"push %%ds \n" \
|
||||
|
@ -181,4 +214,7 @@ void name##_wrapper() \
|
|||
static void name##handler(x86_exceptionframe_t * frame)
|
||||
|
||||
|
||||
|
||||
#endif /* !__ARCH__X86__X32__TRAPGATE_H__ */
|
||||
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
*
|
||||
********************************************************************/
|
||||
|
||||
#if defined(CONFIG_DEBUG)
|
||||
|
||||
#define X86_EXC_KDB
|
||||
|
||||
#include <debug.h>
|
||||
#include <ctors.h>
|
||||
#include <kdb/tracepoints.h>
|
||||
|
@ -43,7 +47,6 @@
|
|||
#include INC_GLUE(debug.h)
|
||||
#include INC_PLAT(nmi.h)
|
||||
|
||||
#if defined(CONFIG_DEBUG)
|
||||
|
||||
static void do_return_from_kdb(void);
|
||||
|
||||
|
@ -54,11 +57,13 @@ static bool sync_dbg_enter = false;
|
|||
|
||||
extern "C" void sync_debug (word_t address)
|
||||
{
|
||||
printf_spin_lock.unlock();
|
||||
//ENABLE_TRACEPOINT(DEBUG_LOCK, ~0, 0);
|
||||
|
||||
if (get_current_tcb() == get_kdebug_tcb())
|
||||
ENABLE_TRACEPOINT(DEBUG_LOCK, ~0, 0);
|
||||
|
||||
if (!sync_dbg_enter)
|
||||
{
|
||||
printf_spin_lock.unlock();
|
||||
sync_dbg_enter = true;
|
||||
TRACEPOINT(DEBUG_LOCK, "CPU %d, tcb %t, spinlock BUG (lock %x) @ %x\n",
|
||||
get_current_cpu(), get_current_tcb(),
|
||||
|
@ -69,6 +74,7 @@ extern "C" void sync_debug (word_t address)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
class cpu_kdb_t
|
||||
{
|
||||
private:
|
||||
|
@ -96,9 +102,10 @@ public:
|
|||
{
|
||||
if (get_current_tcb() == get_kdebug_tcb())
|
||||
return;
|
||||
|
||||
|
||||
void (*entry)(word_t) = (void (*)(word_t)) get_kip()->kdebug_entry;
|
||||
void (*exit)(void) = do_return_from_kdb;
|
||||
|
||||
kdb_tcb->stack = kdb_tcb->get_stack_top();
|
||||
kdb_tcb->notify(exit);
|
||||
kdb_tcb->notify(entry, (word_t) ¶m);
|
||||
|
@ -119,6 +126,11 @@ cpu_kdb_t cpu_kdb UNIT("cpulocal") CTORPRIO(CTORPRIO_CPU, 1);
|
|||
tcb_t *get_kdebug_tcb() { return cpu_kdb.get_kdb_tcb(); }
|
||||
|
||||
|
||||
void do_enter_kdebug(x86_exceptionframe_t *frame, const word_t exception)
|
||||
{
|
||||
cpu_kdb.do_enter_kdebug(frame, X86_EXC_DEBUG);
|
||||
}
|
||||
|
||||
void do_return_from_kdb(void)
|
||||
{
|
||||
ASSERT(get_current_tcb() == get_kdebug_tcb());
|
||||
|
@ -127,7 +139,7 @@ void do_return_from_kdb(void)
|
|||
|
||||
X86_EXCNO_ERRORCODE(exc_breakpoint, X86_EXC_BREAKPOINT)
|
||||
{
|
||||
cpu_kdb.do_enter_kdebug(frame, X86_EXC_BREAKPOINT);
|
||||
cpu_kdb.do_enter_kdebug(frame, X86_EXC_BREAKPOINT);
|
||||
}
|
||||
|
||||
X86_EXCNO_ERRORCODE(exc_debug, X86_EXC_DEBUG)
|
||||
|
@ -135,17 +147,10 @@ X86_EXCNO_ERRORCODE(exc_debug, X86_EXC_DEBUG)
|
|||
cpu_kdb.do_enter_kdebug(frame, X86_EXC_DEBUG);
|
||||
}
|
||||
|
||||
DECLARE_TRACEPOINT(X86_NMI);
|
||||
X86_EXCNO_ERRORCODE(exc_nmi, X86_EXC_NMI)
|
||||
{
|
||||
TRACEPOINT(X86_NMI, "NMI frame %x eip %x efl %x",
|
||||
frame,
|
||||
frame->regs[x86_exceptionframe_t::ipreg],
|
||||
frame->regs[x86_exceptionframe_t::freg]);
|
||||
|
||||
cpu_kdb.do_enter_kdebug(frame, X86_EXC_NMI);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
X86_EXCNO_ERRORCODE(exc_debug_ipi, 0)
|
||||
{
|
||||
|
@ -153,6 +158,8 @@ X86_EXCNO_ERRORCODE(exc_debug_ipi, 0)
|
|||
}
|
||||
#endif
|
||||
|
||||
#undef X86_EXC_KDB
|
||||
|
||||
#endif /* CONFIG_DEBUG */
|
||||
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ void setup_smp_boot_gdt (void)
|
|||
|
||||
/* processor local data */
|
||||
x86_segdesc_t gdt[GDT_SIZE] UNIT("x86.cpulocal");
|
||||
x86_x32_tss_t tss UNIT("x86.cpulocal");
|
||||
x86_x32_tss_t tss UNIT("x86.cpulocal.tss");
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2005, 2007, Karlsruhe University
|
||||
* Copyright (C) 1999-2005, 2007-2008, Karlsruhe University
|
||||
*
|
||||
* File path: glue/v4-x86/x32/linker-pc99.lds
|
||||
* Description: Generic linkser script for x86.
|
||||
|
@ -78,6 +78,11 @@ SECTIONS
|
|||
{
|
||||
*(.data.cpulocal)
|
||||
*(.data.x86.cpulocal)
|
||||
#if defined(CONFIG_DEBUG)
|
||||
. = . + 8;
|
||||
#endif
|
||||
*(.data.x86.cpulocal.tss)
|
||||
|
||||
}
|
||||
_end_cpu_local = .;
|
||||
|
||||
|
|
Loading…
Reference in New Issue