forked from luck/tmp_suning_uos_patched
sh: stack debugging support.
This adds a DEBUG_STACK_USAGE and DEBUG_STACKOVERFLOW for SH. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
7a440c950e
commit
d153ea88dc
|
@ -30,6 +30,22 @@ config EARLY_PRINTK
|
||||||
when the kernel may crash or hang before the serial console is
|
when the kernel may crash or hang before the serial console is
|
||||||
initialised. If unsure, say N.
|
initialised. If unsure, say N.
|
||||||
|
|
||||||
|
config DEBUG_STACKOVERFLOW
|
||||||
|
bool "Check for stack overflows"
|
||||||
|
depends on DEBUG_KERNEL
|
||||||
|
help
|
||||||
|
This option will cause messages to be printed if free stack space
|
||||||
|
drops below a certain limit.
|
||||||
|
|
||||||
|
config DEBUG_STACK_USAGE
|
||||||
|
bool "Stack utilization instrumentation"
|
||||||
|
depends on DEBUG_KERNEL
|
||||||
|
help
|
||||||
|
Enables the display of the minimum amount of free stack which each
|
||||||
|
task has ever had available in the sysrq-T and sysrq-P debug output.
|
||||||
|
|
||||||
|
This option will slow down process creation somewhat.
|
||||||
|
|
||||||
config KGDB
|
config KGDB
|
||||||
bool "Include KGDB kernel debugger"
|
bool "Include KGDB kernel debugger"
|
||||||
select FRAME_POINTER
|
select FRAME_POINTER
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
* Head.S contains the SH exception handlers and startup code.
|
* Head.S contains the SH exception handlers and startup code.
|
||||||
*/
|
*/
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/thread_info.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_SH4A
|
#ifdef CONFIG_CPU_SH4A
|
||||||
#define SYNCO() synco
|
#define SYNCO() synco
|
||||||
|
@ -95,7 +97,7 @@ ENTRY(_stext)
|
||||||
|
|
||||||
.balign 4
|
.balign 4
|
||||||
1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
|
1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
|
||||||
2: .long init_thread_union+8192
|
2: .long init_thread_union+THREAD_SIZE
|
||||||
3: .long __bss_start
|
3: .long __bss_start
|
||||||
4: .long _end
|
4: .long _end
|
||||||
5: .long start_kernel
|
5: .long start_kernel
|
||||||
|
|
|
@ -60,7 +60,6 @@ int show_interrupts(struct seq_file *p, void *v)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
|
asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
|
||||||
unsigned long r6, unsigned long r7,
|
unsigned long r6, unsigned long r7,
|
||||||
struct pt_regs regs)
|
struct pt_regs regs)
|
||||||
|
@ -69,6 +68,22 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
|
||||||
|
|
||||||
irq_enter();
|
irq_enter();
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
||||||
|
/* Debugging check for stack overflow: is there less than 1KB free? */
|
||||||
|
{
|
||||||
|
long sp;
|
||||||
|
|
||||||
|
__asm__ __volatile__ ("and r15, %0" :
|
||||||
|
"=r" (sp) : "0" (THREAD_SIZE - 1));
|
||||||
|
|
||||||
|
if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
|
||||||
|
printk("do_IRQ: stack overflow: %ld\n",
|
||||||
|
sp - sizeof(struct thread_info));
|
||||||
|
dump_stack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_HAS_INTEVT
|
#ifdef CONFIG_CPU_HAS_INTEVT
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
#ifdef CONFIG_CPU_HAS_SR_RB
|
#ifdef CONFIG_CPU_HAS_SR_RB
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* ld script to make SuperH Linux kernel
|
* ld script to make SuperH Linux kernel
|
||||||
* Written by Niibe Yutaka
|
* Written by Niibe Yutaka
|
||||||
*/
|
*/
|
||||||
|
#include <asm/thread_info.h>
|
||||||
|
#include <asm/page.h>
|
||||||
#include <asm-generic/vmlinux.lds.h>
|
#include <asm-generic/vmlinux.lds.h>
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||||
|
@ -40,16 +42,16 @@ SECTIONS
|
||||||
*(.data)
|
*(.data)
|
||||||
|
|
||||||
/* Align the initial ramdisk image (INITRD) on page boundaries. */
|
/* Align the initial ramdisk image (INITRD) on page boundaries. */
|
||||||
. = ALIGN(4096);
|
. = ALIGN(PAGE_SIZE);
|
||||||
__rd_start = .;
|
__rd_start = .;
|
||||||
*(.initrd)
|
*(.initrd)
|
||||||
. = ALIGN(4096);
|
. = ALIGN(PAGE_SIZE);
|
||||||
__rd_end = .;
|
__rd_end = .;
|
||||||
|
|
||||||
CONSTRUCTORS
|
CONSTRUCTORS
|
||||||
}
|
}
|
||||||
|
|
||||||
. = ALIGN(4096);
|
. = ALIGN(PAGE_SIZE);
|
||||||
.data.page_aligned : { *(.data.idt) }
|
.data.page_aligned : { *(.data.idt) }
|
||||||
|
|
||||||
. = ALIGN(32);
|
. = ALIGN(32);
|
||||||
|
@ -60,10 +62,10 @@ SECTIONS
|
||||||
|
|
||||||
_edata = .; /* End of data section */
|
_edata = .; /* End of data section */
|
||||||
|
|
||||||
. = ALIGN(8192); /* init_task */
|
. = ALIGN(THREAD_SIZE); /* init_task */
|
||||||
.data.init_task : { *(.data.init_task) }
|
.data.init_task : { *(.data.init_task) }
|
||||||
|
|
||||||
. = ALIGN(4096); /* Init code and data */
|
. = ALIGN(PAGE_SIZE); /* Init code and data */
|
||||||
__init_begin = .;
|
__init_begin = .;
|
||||||
_sinittext = .;
|
_sinittext = .;
|
||||||
.init.text : { *(.init.text) }
|
.init.text : { *(.init.text) }
|
||||||
|
@ -94,7 +96,7 @@ SECTIONS
|
||||||
__machvec_start = .;
|
__machvec_start = .;
|
||||||
.init.machvec : { *(.init.machvec) }
|
.init.machvec : { *(.init.machvec) }
|
||||||
__machvec_end = .;
|
__machvec_end = .;
|
||||||
. = ALIGN(4096);
|
. = ALIGN(PAGE_SIZE);
|
||||||
__init_end = .;
|
__init_end = .;
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
/* PAGE_SHIFT determines the page size */
|
/* PAGE_SHIFT determines the page size */
|
||||||
#define PAGE_SHIFT 12
|
#define PAGE_SHIFT 12
|
||||||
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
#define PAGE_SIZE (1 << PAGE_SHIFT)
|
||||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||||
#define PTE_MASK PAGE_MASK
|
#define PTE_MASK PAGE_MASK
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ struct thread_info {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PREEMPT_ACTIVE 0x10000000
|
#define PREEMPT_ACTIVE 0x10000000
|
||||||
|
#define THREAD_SIZE (PAGE_SIZE * 2)
|
||||||
|
#define STACK_WARN (THREAD_SIZE / 8)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* macros/functions for gaining access to the thread information structure
|
* macros/functions for gaining access to the thread information structure
|
||||||
|
@ -50,8 +52,6 @@ struct thread_info {
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
#define init_stack (init_thread_union.stack)
|
#define init_stack (init_thread_union.stack)
|
||||||
|
|
||||||
#define THREAD_SIZE (2*PAGE_SIZE)
|
|
||||||
|
|
||||||
/* how to get the thread information struct from C */
|
/* how to get the thread information struct from C */
|
||||||
static inline struct thread_info *current_thread_info(void)
|
static inline struct thread_info *current_thread_info(void)
|
||||||
{
|
{
|
||||||
|
@ -73,8 +73,12 @@ static inline struct thread_info *current_thread_info(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* thread information allocation */
|
/* thread information allocation */
|
||||||
#define alloc_thread_info(ti) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
|
#ifdef CONFIG_DEBUG_STACK_USAGE
|
||||||
#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
|
#define alloc_thread_info(ti) kzalloc(THREAD_SIZE, GFP_KERNEL)
|
||||||
|
#else
|
||||||
|
#define alloc_thread_info(ti) kmalloc(THREAD_SIZE, GFP_KERNEL)
|
||||||
|
#endif
|
||||||
|
#define free_thread_info(ti) kfree(ti)
|
||||||
|
|
||||||
#else /* !__ASSEMBLY__ */
|
#else /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user