From 191e6f7499462061cd1d8729f20c6d5de94a415f Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Mon, 15 Jun 2020 12:48:25 +0900 Subject: [PATCH] TO RESET: preempt_enable: check if no_preempt isn't negative Change-Id: I1cef2077c50f3b3020870505dd065d10617f440e --- arch/arm64/kernel/cpu.c | 43 ++++++++++++++++++++++++ arch/x86_64/kernel/cpu.c | 43 ++++++++++++++++++++++++ arch/x86_64/kernel/include/arch-memory.h | 8 +++++ arch/x86_64/kernel/include/cpulocal.h | 4 +++ arch/x86_64/kernel/local.c | 2 ++ kernel/cls.c | 26 +++++++++++++- 6 files changed, 125 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/cpu.c b/arch/arm64/kernel/cpu.c index 1450743e..05196d29 100644 --- a/arch/arm64/kernel/cpu.c +++ b/arch/arm64/kernel/cpu.c @@ -730,6 +730,49 @@ static void show_context_stack(struct pt_regs *regs) } } +#ifdef ENABLE_FUGAKU_HACKS +void __show_context_stack(struct thread *thread, + unsigned long pc, uintptr_t sp, int kprintf_locked) +{ + uintptr_t stack_top; + unsigned long irqflags = 0; + + stack_top = ALIGN_UP(sp, (uintptr_t)KERNEL_STACK_SIZE); + + if (!kprintf_locked) + irqflags = kprintf_lock(); + + __kprintf("TID: %d, call stack (most recent first):\n", + thread->tid); + __kprintf("PC: %016lx, SP: %016lx\n", pc, sp); + for (;;) { + extern char _head[], _end[]; + uintptr_t *fp, *lr; + fp = (uintptr_t *)sp; + lr = (uintptr_t *)(sp + 8); + + if ((*fp <= sp)) { + break; + } + + if ((*fp > stack_top)) { + break; + } + + if ((*lr < (unsigned long)_head) || + (*lr > (unsigned long)_end)) { + break; + } + + __kprintf("PC: %016lx, SP: %016lx, FP: %016lx\n", *lr - 4, sp, *fp); + sp = *fp; + } + + if (!kprintf_locked) + kprintf_unlock(irqflags); +} +#endif + void handle_IPI(unsigned int vector, struct pt_regs *regs) { struct ihk_mc_interrupt_handler *h; diff --git a/arch/x86_64/kernel/cpu.c b/arch/x86_64/kernel/cpu.c index ebe9c6d9..1876652f 100644 --- a/arch/x86_64/kernel/cpu.c +++ b/arch/x86_64/kernel/cpu.c @@ -868,6 +868,49 @@ void show_context_stack(uintptr_t *rbp) { return; } +#ifdef ENABLE_FUGAKU_HACKS +void __show_context_stack(struct thread *thread, + unsigned long pc, uintptr_t sp, int kprintf_locked) +{ + uintptr_t stack_top; + unsigned long irqflags = 0; + + stack_top = ALIGN_UP(sp, (uintptr_t)KERNEL_STACK_SIZE); + + if (!kprintf_locked) + irqflags = kprintf_lock(); + + __kprintf("TID: %d, call stack (most recent first):\n", + thread->tid); + __kprintf("PC: %016lx, SP: %016lx\n", pc, sp); + for (;;) { + extern char _head[], _end[]; + uintptr_t *fp, *lr; + fp = (uintptr_t *)sp; + lr = (uintptr_t *)(sp + 8); + + if ((*fp <= sp)) { + break; + } + + if ((*fp > stack_top)) { + break; + } + + if ((*lr < (unsigned long)_head) || + (*lr > (unsigned long)_end)) { + break; + } + + __kprintf("PC: %016lx, SP: %016lx, FP: %016lx\n", *lr - 4, sp, *fp); + sp = *fp; + } + + if (!kprintf_locked) + kprintf_unlock(irqflags); +} +#endif + void interrupt_exit(struct x86_user_context *regs) { if (interrupt_from_user(regs)) { diff --git a/arch/x86_64/kernel/include/arch-memory.h b/arch/x86_64/kernel/include/arch-memory.h index e067a5e1..dfa38bbe 100644 --- a/arch/x86_64/kernel/include/arch-memory.h +++ b/arch/x86_64/kernel/include/arch-memory.h @@ -451,4 +451,12 @@ extern unsigned long ap_trampoline; /* Local is cachable */ #define IHK_IKC_QUEUE_PT_ATTR (PTATTR_NO_EXECUTE | PTATTR_WRITABLE) + +#ifdef ENABLE_FUGAKU_HACKS +#ifndef __ASSEMBLY__ +# define ALIGN_UP(x, align) ALIGN_DOWN((x) + (align) - 1, align) +# define ALIGN_DOWN(x, align) ((x) & ~((align) - 1)) +#endif /* !__ASSEMBLY__ */ +#endif + #endif diff --git a/arch/x86_64/kernel/include/cpulocal.h b/arch/x86_64/kernel/include/cpulocal.h index 66cf69c1..5eac0c61 100644 --- a/arch/x86_64/kernel/include/cpulocal.h +++ b/arch/x86_64/kernel/include/cpulocal.h @@ -53,5 +53,9 @@ struct x86_cpu_local_variables *get_x86_this_cpu_local(void); void *get_x86_cpu_local_kstack(int id); void *get_x86_this_cpu_kstack(void); +#ifdef ENABLE_FUGAKU_HACKS +#define LOCALS_SPAN (4 * PAGE_SIZE) +#define KERNEL_STACK_SIZE LOCALS_SPAN +#endif #endif diff --git a/arch/x86_64/kernel/local.c b/arch/x86_64/kernel/local.c index aa74fc9c..45a25267 100644 --- a/arch/x86_64/kernel/local.c +++ b/arch/x86_64/kernel/local.c @@ -21,7 +21,9 @@ #include #include +#ifndef ENABLE_FUGAKU_HACKS #define LOCALS_SPAN (4 * PAGE_SIZE) +#endif struct x86_cpu_local_variables *locals; size_t x86_cpu_local_variables_span = LOCALS_SPAN; /* for debugger */ diff --git a/kernel/cls.c b/kernel/cls.c index ca5bb1b5..ad256d25 100644 --- a/kernel/cls.c +++ b/kernel/cls.c @@ -58,16 +58,40 @@ struct cpu_local_var *get_cpu_local_var(int id) return clv + id; } +#ifdef ENABLE_FUGAKU_HACKS +void __show_context_stack(struct thread *thread, + unsigned long pc, uintptr_t sp, int kprintf_locked); +#endif void preempt_enable(void) { +#ifndef ENABLE_FUGAKU_HACKS if (cpu_local_var_initialized) --cpu_local_var(no_preempt); +#else + if (cpu_local_var_initialized) { + --cpu_local_var(no_preempt); + + if (cpu_local_var(no_preempt) < 0) { + //cpu_disable_interrupt(); + + __kprintf("%s: %d\n", __func__, cpu_local_var(no_preempt)); + __kprintf("TID: %d, call stack from builtin frame (most recent first):\n", + cpu_local_var(current)->tid); + __show_context_stack(cpu_local_var(current), (uintptr_t)&preempt_enable, + (unsigned long)__builtin_frame_address(0), 1); + + //arch_cpu_stop(); + //cpu_halt(); + } + } +#endif } void preempt_disable(void) { - if (cpu_local_var_initialized) + if (cpu_local_var_initialized) { ++cpu_local_var(no_preempt); + } } int add_backlog(int (*func)(void *arg), void *arg)