This patch enables hardware breakpoints and debugging kernel early
before slab is initialized and cpu local data has been established.
Signed-off-by: Bob Picco <[EMAIL PROTECTED]>
arch/ia64/kernel/entry.S | 4 +-
arch/ia64/kernel/ivt.S | 16 ++++++++
arch/ia64/kernel/process.c | 6 +++
arch/ia64/kernel/unwind.c | 87 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 111 insertions(+), 2 deletions(-)
Index: linux-2.6.17-rc3-kgdb/arch/ia64/kernel/process.c
===================================================================
--- linux-2.6.17-rc3-kgdb.orig/arch/ia64/kernel/process.c 2006-05-01
13:55:27.000000000 -0400
+++ linux-2.6.17-rc3-kgdb/arch/ia64/kernel/process.c 2006-05-01
13:56:11.000000000 -0400
@@ -459,6 +459,9 @@ copy_thread (int nr, unsigned long clone
*/
child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
& ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP |
IA64_PSR_UP));
+#ifdef CONFIG_KGDB
+ child_ptregs->cr_ipsr |= IA64_PSR_DB;
+#endif
/*
* NOTE: The calling convention considers all floating point
@@ -687,6 +690,9 @@ kernel_thread (int (*fn)(void *), void *
regs.pt.r11 = (unsigned long) arg; /* 2nd argument */
/* Preserve PSR bits, except for bits 32-34 and 37-45, which we can't
read. */
regs.pt.cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN;
+#ifdef CONFIG_KGDB
+ regs.pt.cr_ipsr |= IA64_PSR_DB;
+#endif
regs.pt.cr_ifs = 1UL << 63; /* mark as valid, empty frame */
regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR);
regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET;
Index: linux-2.6.17-rc3-kgdb/arch/ia64/kernel/unwind.c
===================================================================
--- linux-2.6.17-rc3-kgdb.orig/arch/ia64/kernel/unwind.c 2006-05-01
13:55:27.000000000 -0400
+++ linux-2.6.17-rc3-kgdb/arch/ia64/kernel/unwind.c 2006-05-01
13:56:11.000000000 -0400
@@ -72,10 +72,68 @@
# define STAT(x...)
#endif
+#ifdef CONFIG_KGDB
+#define KGDB_EARLY_SIZE 100
+static struct unw_reg_state __initdata kgdb_reg_state[KGDB_EARLY_SIZE];
+static struct unw_labeled_state __initdata kgdb_labeled_state[KGDB_EARLY_SIZE];
+void __initdata *kgdb_reg_state_free, __initdata *kgdb_labeled_state_free;
+
+static void __init
+kgdb_malloc_init(void)
+{
+ int i;
+
+ kgdb_reg_state_free = kgdb_reg_state;
+ for (i = 1; i < KGDB_EARLY_SIZE; i++) {
+ *((unsigned long *) &kgdb_reg_state[i]) = (unsigned long)
kgdb_reg_state_free;
+ kgdb_reg_state_free = &kgdb_reg_state[i];
+ }
+
+ kgdb_labeled_state_free = kgdb_labeled_state;
+ for (i = 1; i < KGDB_EARLY_SIZE; i++) {
+ *((unsigned long *) &kgdb_labeled_state[i]) =
+ (unsigned long) kgdb_labeled_state_free;
+ kgdb_labeled_state_free = &kgdb_labeled_state[i];
+ }
+
+}
+
+static void * __init
+kgdb_malloc(void **mem)
+{
+ void *p;
+
+ p = *mem;
+ *mem = *((void **) p);
+ return p;
+}
+
+static void __init
+kgdb_free(void **mem, void *p)
+{
+ *((void **)p) = *mem;
+ *mem = p;
+}
+
+#define alloc_reg_state() (!malloc_sizes[0].cs_cachep ? \
+ kgdb_malloc(&kgdb_reg_state_free) : \
+ kmalloc(sizeof(struct unw_reg_state), GFP_ATOMIC))
+#define free_reg_state(usr) (!malloc_sizes[0].cs_cachep ? \
+ kgdb_free(&kgdb_reg_state_free, usr) : \
+ kfree(usr))
+#define alloc_labeled_state() (!malloc_sizes[0].cs_cachep ? \
+ kgdb_malloc(&kgdb_labeled_state_free) : \
+ kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC))
+#define free_labeled_state(usr) (!malloc_sizes[0].cs_cachep ?
\
+ kgdb_free(&kgdb_labeled_state_free, usr) : \
+ kfree(usr))
+
+#else
#define alloc_reg_state() kmalloc(sizeof(struct unw_reg_state),
GFP_ATOMIC)
#define free_reg_state(usr) kfree(usr)
#define alloc_labeled_state() kmalloc(sizeof(struct unw_labeled_state),
GFP_ATOMIC)
#define free_labeled_state(usr) kfree(usr)
+#endif
typedef unsigned long unw_word;
typedef unsigned char unw_hash_index_t;
@@ -238,6 +296,24 @@ static struct {
#endif
};
+#ifdef CONFIG_KGDB
+/*
+ * This makes it safe to call breakpoint() very early
+ * in setup_arch providing:
+ * 1) breakpoint isn't called between lines in cpu_init
+ * where init_mm.mm_count is incremented and ia64_mmu_init
+ * is called. Otherwise the test below is invalid.
+ * 2) the memory examined doesn't result in tlbmiss.
+ */
+static unsigned long inline kgdb_unimpl_va_mask(void)
+{
+ if (atomic_read(&init_mm.mm_count) > 1)
+ return local_cpu_data->unimpl_va_mask;
+ else
+ return 0UL;
+}
+#endif
+
static inline int
read_only (void *addr)
{
@@ -1786,7 +1862,11 @@ run_script (struct unw_script *script, s
case UNW_INSN_LOAD:
#ifdef UNW_DEBUG
+#ifdef CONFIG_KGDB
+ if ((s[val] & (kgdb_unimpl_va_mask() | 0x7)) != 0
+#else
if ((s[val] & (local_cpu_data->unimpl_va_mask | 0x7))
!= 0
+#endif
|| s[val] < TASK_SIZE)
{
UNW_DPRINT(0, "unwind.%s: rejecting bad
psp=0x%lx\n",
@@ -1821,7 +1901,11 @@ find_save_locs (struct unw_frame_info *i
struct unw_script *scr;
unsigned long flags = 0;
+#ifdef CONFIG_KGDB
+ if ((info->ip & (kgdb_unimpl_va_mask() | 0xf)) || info->ip < TASK_SIZE)
{
+#else
if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip <
TASK_SIZE) {
+#endif
/* don't let obviously bad addresses pollute the cache */
/* FIXME: should really be level 0 but it occurs too often. KAO
*/
UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n",
__FUNCTION__, info->ip);
@@ -2249,6 +2333,9 @@ unw_init (void)
init_unwind_table(&unw.kernel_table, "kernel", KERNEL_START, (unsigned
long) __gp,
__start_unwind, __end_unwind);
+#ifdef CONFIG_KGDB
+ kgdb_malloc_init();
+#endif
}
/*
Index: linux-2.6.17-rc3-kgdb/arch/ia64/kernel/entry.S
===================================================================
--- linux-2.6.17-rc3-kgdb.orig/arch/ia64/kernel/entry.S 2006-05-01
13:55:27.000000000 -0400
+++ linux-2.6.17-rc3-kgdb/arch/ia64/kernel/entry.S 2006-05-01
13:56:11.000000000 -0400
@@ -954,9 +954,9 @@ GLOBAL_ENTRY(ia64_leave_kernel)
shr.u r18=r19,16 // get byte size of existing "dirty" partition
;;
mov r16=ar.bsp // get existing backing store pointer
- addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
+(pUStk) addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
;;
- ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8
+(pUStk) ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8
(pKStk) br.cond.dpnt skip_rbs_switch
/*
Index: linux-2.6.17-rc3-kgdb/arch/ia64/kernel/ivt.S
===================================================================
--- linux-2.6.17-rc3-kgdb.orig/arch/ia64/kernel/ivt.S 2006-05-01
13:55:27.000000000 -0400
+++ linux-2.6.17-rc3-kgdb/arch/ia64/kernel/ivt.S 2006-05-01
13:56:11.000000000 -0400
@@ -53,6 +53,14 @@
#include <asm/unistd.h>
#include <asm/errno.h>
+#ifdef CONFIG_KGDB
+#define KGDB_ENABLE_PSR_DB mov r31=psr;; movl r30=IA64_PSR_DB;; \
+ or r31=r31,r30;; \
+ mov psr.l=r31;; srlz.i;;
+#else
+#define KGDB_ENABLE_PSR_DB
+#endif
+
#if 1
# define PSR_DEFAULT_BITS psr.ac
#else
@@ -520,6 +528,7 @@ ENTRY(page_fault)
movl r14=ia64_leave_kernel
;;
SAVE_REST
+ KGDB_ENABLE_PSR_DB
mov rp=r14
;;
adds out2=16,r12 // out2 = pointer to pt_regs
@@ -864,6 +873,7 @@ ENTRY(interrupt)
srlz.i // ensure everybody knows psr.ic is back on
;;
SAVE_REST
+ KGDB_ENABLE_PSR_DB
;;
MCA_RECOVER_RANGE(interrupt)
alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
@@ -1111,6 +1121,7 @@ ENTRY(non_syscall)
movl r15=ia64_leave_kernel
;;
SAVE_REST
+ KGDB_ENABLE_PSR_DB
mov rp=r15
;;
br.call.sptk.many b6=ia64_bad_break // avoid WAW on CFM and ignore
return addr
@@ -1144,6 +1155,7 @@ ENTRY(dispatch_unaligned_handler)
adds r3=8,r2 // set up second base pointer
;;
SAVE_REST
+ KGDB_ENABLE_PSR_DB
movl r14=ia64_leave_kernel
;;
mov rp=r14
@@ -1186,6 +1198,10 @@ ENTRY(dispatch_to_fault_handler)
adds r3=8,r2 // set up second base pointer
for SAVE_REST
;;
SAVE_REST
+ cmp.eq p6,p0=29,out0
+(p6) br.cond.spnt 1f;; // debug_vector
+ KGDB_ENABLE_PSR_DB
+1:
movl r14=ia64_leave_kernel
;;
mov rp=r14
-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport