From 313ce674d3cbc2d48ed34a9462427920ac54f4ad Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Mon, 2 May 2011 14:50:06 -0400 Subject: arch/tile: support TIF_NOTIFY_RESUME This support is required for CONFIG_KEYS, NFSv4 kernel DNS, etc. The change is slightly more complex than the minimal thing, since I took advantage of having to go into the assembly code to just move a bunch of stuff into C code: specifically, the schedule(), do_async_page_fault(), do_signal(), and single_step_once() support, in addition to the TIF_NOTIFY_RESUME support. Signed-off-by: Chris Metcalf --- arch/tile/mm/fault.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/tile/mm') diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c index 51f8663..24ca54a 100644 --- a/arch/tile/mm/fault.c +++ b/arch/tile/mm/fault.c @@ -732,6 +732,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num, panic("Bad fault number %d in do_page_fault", fault_num); } +#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() if (EX1_PL(regs->ex1) != USER_PL) { struct async_tlb *async; switch (fault_num) { @@ -775,6 +776,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num, return; } } +#endif handle_page_fault(regs, fault_num, is_page_fault, address, write); } @@ -801,8 +803,6 @@ static void handle_async_page_fault(struct pt_regs *regs, async->address, async->is_write); } } -#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */ - /* * This routine effectively re-issues asynchronous page faults @@ -824,6 +824,8 @@ void do_async_page_fault(struct pt_regs *regs) handle_async_page_fault(regs, ¤t->thread.sn_async_tlb); #endif } +#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */ + void vmalloc_sync_all(void) { -- cgit v1.1 From 18aecc2b645bbb07851b196452a2af314222069b Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Wed, 4 May 2011 14:38:26 -0400 Subject: arch/tile: finish enabling support for TILE-Gx 64-bit chip This support was partially present in the existing code (look for "__tilegx__" ifdefs) but with this change you can build a working kernel using the TILE-Gx toolchain and ARCH=tilegx. Most of these files are new, generally adding a foo_64.c file where previously there was just a foo_32.c file. The ARCH=tilegx directive redirects to arch/tile, not arch/tilegx, using the existing SRCARCH mechanism in the top-level Makefile. Changes to existing files: - and changed to factor the include of in the common header. - and arch/tile/kernel/compat.c changed to remove the "const" markers I had put on compat_sys_execve() when trying to match some recent similar changes to the non-compat execve. It turns out the compat version wasn't "upgraded" to use const. - and were previously included accidentally, with the 32-bit contents. Now they have the proper 64-bit contents. Finally, I had to hack the existing hacky drivers/input/input-compat.h to add yet another "#ifdef" for INPUT_COMPAT_TEST (same as x86_64). Signed-off-by: Chris Metcalf Acked-by: Dmitry Torokhov [drivers/input] --- arch/tile/mm/migrate_64.S | 187 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 arch/tile/mm/migrate_64.S (limited to 'arch/tile/mm') diff --git a/arch/tile/mm/migrate_64.S b/arch/tile/mm/migrate_64.S new file mode 100644 index 0000000..e76fea6 --- /dev/null +++ b/arch/tile/mm/migrate_64.S @@ -0,0 +1,187 @@ +/* + * Copyright 2011 Tilera Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for + * more details. + * + * This routine is a helper for migrating the home of a set of pages to + * a new cpu. See the documentation in homecache.c for more information. + */ + +#include +#include +#include +#include +#include +#include +#include + + .text + +/* + * First, some definitions that apply to all the code in the file. + */ + +/* Locals (caller-save) */ +#define r_tmp r10 +#define r_save_sp r11 + +/* What we save where in the stack frame; must include all callee-saves. */ +#define FRAME_SP 8 +#define FRAME_R30 16 +#define FRAME_R31 24 +#define FRAME_R32 32 +#define FRAME_R33 40 +#define FRAME_SIZE 48 + + + + +/* + * On entry: + * + * r0 the new context PA to install (moved to r_context) + * r1 PTE to use for context access (moved to r_access) + * r2 ASID to use for new context (moved to r_asid) + * r3 pointer to cpumask with just this cpu set in it (r_my_cpumask) + */ + +/* Arguments (caller-save) */ +#define r_context_in r0 +#define r_access_in r1 +#define r_asid_in r2 +#define r_my_cpumask r3 + +/* Locals (callee-save); must not be more than FRAME_xxx above. */ +#define r_save_ics r30 +#define r_context r31 +#define r_access r32 +#define r_asid r33 + +/* + * Caller-save locals and frame constants are the same as + * for homecache_migrate_stack_and_flush. + */ + +STD_ENTRY(flush_and_install_context) + /* + * Create a stack frame; we can't touch it once we flush the + * cache until we install the new page table and flush the TLB. + */ + { + move r_save_sp, sp + st sp, lr + addi sp, sp, -FRAME_SIZE + } + addi r_tmp, sp, FRAME_SP + { + st r_tmp, r_save_sp + addi r_tmp, sp, FRAME_R30 + } + { + st r_tmp, r30 + addi r_tmp, sp, FRAME_R31 + } + { + st r_tmp, r31 + addi r_tmp, sp, FRAME_R32 + } + { + st r_tmp, r32 + addi r_tmp, sp, FRAME_R33 + } + st r_tmp, r33 + + /* Move some arguments to callee-save registers. */ + { + move r_context, r_context_in + move r_access, r_access_in + } + move r_asid, r_asid_in + + /* Disable interrupts, since we can't use our stack. */ + { + mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION + movei r_tmp, 1 + } + mtspr INTERRUPT_CRITICAL_SECTION, r_tmp + + /* First, flush our L2 cache. */ + { + move r0, zero /* cache_pa */ + moveli r1, hw2_last(HV_FLUSH_EVICT_L2) /* cache_control */ + } + { + shl16insli r1, r1, hw1(HV_FLUSH_EVICT_L2) + move r2, r_my_cpumask /* cache_cpumask */ + } + { + shl16insli r1, r1, hw0(HV_FLUSH_EVICT_L2) + move r3, zero /* tlb_va */ + } + { + move r4, zero /* tlb_length */ + move r5, zero /* tlb_pgsize */ + } + { + move r6, zero /* tlb_cpumask */ + move r7, zero /* asids */ + } + { + move r8, zero /* asidcount */ + jal hv_flush_remote + } + bnez r0, 1f + + /* Now install the new page table. */ + { + move r0, r_context + move r1, r_access + } + { + move r2, r_asid + movei r3, HV_CTX_DIRECTIO + } + jal hv_install_context + bnez r0, 1f + + /* Finally, flush the TLB. */ + { + movei r0, 0 /* preserve_global */ + jal hv_flush_all + } + +1: /* Reset interrupts back how they were before. */ + mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics + + /* Restore the callee-saved registers and return. */ + addli lr, sp, FRAME_SIZE + { + ld lr, lr + addli r_tmp, sp, FRAME_R30 + } + { + ld r30, r_tmp + addli r_tmp, sp, FRAME_R31 + } + { + ld r31, r_tmp + addli r_tmp, sp, FRAME_R32 + } + { + ld r32, r_tmp + addli r_tmp, sp, FRAME_R33 + } + { + ld r33, r_tmp + addi sp, sp, FRAME_SIZE + } + jrp lr + STD_ENDPROC(flush_and_install_context) -- cgit v1.1 From 571d76acdab95876aeff869ab6449f826c23aa43 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Mon, 16 May 2011 14:23:44 -0400 Subject: arch/tile: support signal "exception-trace" hook This change adds support for /proc/sys/debug/exception-trace to tile. Like x86 and sparc, by default it is set to "1", generating a one-line printk whenever a user process crashes. By setting it to "2", we get a much more complete userspace diagnostic at crash time, including a user-space backtrace, register dump, and memory dump around the address of the crash. Some vestiges of the Tilera-internal version of this support are removed with this patch (the show_crashinfo variable and the arch_coredump_signal function). We retain a "crashinfo" boot parameter which allows you to set the boot-time value of exception-trace. Signed-off-by: Chris Metcalf --- arch/tile/mm/fault.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'arch/tile/mm') diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c index 24ca54a..25b7b90 100644 --- a/arch/tile/mm/fault.c +++ b/arch/tile/mm/fault.c @@ -43,8 +43,11 @@ #include -static noinline void force_sig_info_fault(int si_signo, int si_code, - unsigned long address, int fault_num, struct task_struct *tsk) +static noinline void force_sig_info_fault(const char *type, int si_signo, + int si_code, unsigned long address, + int fault_num, + struct task_struct *tsk, + struct pt_regs *regs) { siginfo_t info; @@ -59,6 +62,7 @@ static noinline void force_sig_info_fault(int si_signo, int si_code, info.si_code = si_code; info.si_addr = (void __user *)address; info.si_trapno = fault_num; + trace_unhandled_signal(type, regs, address, si_signo); force_sig_info(si_signo, &info, tsk); } @@ -71,11 +75,12 @@ SYSCALL_DEFINE2(cmpxchg_badaddr, unsigned long, address, struct pt_regs *, regs) { if (address >= PAGE_OFFSET) - force_sig_info_fault(SIGSEGV, SEGV_MAPERR, address, - INT_DTLB_MISS, current); + force_sig_info_fault("atomic segfault", SIGSEGV, SEGV_MAPERR, + address, INT_DTLB_MISS, current, regs); else - force_sig_info_fault(SIGBUS, BUS_ADRALN, address, - INT_UNALIGN_DATA, current); + force_sig_info_fault("atomic alignment fault", SIGBUS, + BUS_ADRALN, address, + INT_UNALIGN_DATA, current, regs); /* * Adjust pc to point at the actual instruction, which is unusual @@ -471,8 +476,8 @@ bad_area_nosemaphore: */ local_irq_enable(); - force_sig_info_fault(SIGSEGV, si_code, address, - fault_num, tsk); + force_sig_info_fault("segfault", SIGSEGV, si_code, address, + fault_num, tsk, regs); return 0; } @@ -547,7 +552,8 @@ do_sigbus: if (is_kernel_mode) goto no_context; - force_sig_info_fault(SIGBUS, BUS_ADRERR, address, fault_num, tsk); + force_sig_info_fault("bus error", SIGBUS, BUS_ADRERR, address, + fault_num, tsk, regs); return 0; } -- cgit v1.1