diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-25 18:35:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-25 18:35:32 -0400 |
commit | 0798b1dbfbd9ff2a370c5968c5f0621ef0075fe0 (patch) | |
tree | c7f61ab9683786a070da0933b9981fc74a4d865f /arch/tile/mm | |
parent | ad363e0916423b2e6cdfcdc30ae707ec709f0a65 (diff) | |
parent | 6738d3210aabe3016a1b03cd98a7fc479c229197 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile: (26 commits)
arch/tile: prefer "tilepro" as the name of the 32-bit architecture
compat: include aio_abi.h for aio_context_t
arch/tile: cleanups for tilegx compat mode
arch/tile: allocate PCI IRQs later in boot
arch/tile: support signal "exception-trace" hook
arch/tile: use better definitions of xchg() and cmpxchg()
include/linux/compat.h: coding-style fixes
tile: add an RTC driver for the Tilera hypervisor
arch/tile: finish enabling support for TILE-Gx 64-bit chip
compat: fixes to allow working with tile arch
arch/tile: update defconfig file to something more useful
tile: do_hardwall_trap: do not play with task->sighand
tile: replace mm->cpu_vm_mask with mm_cpumask()
tile,mn10300: add device parameter to dma_cache_sync()
audit: support the "standard" <asm-generic/unistd.h>
arch/tile: clarify flush_buffer()/finv_buffer() function names
arch/tile: kernel-related cleanups from removing static page size
arch/tile: various header improvements for building drivers
arch/tile: disable GX prefetcher during cache flush
arch/tile: tolerate disabling CONFIG_BLK_DEV_INITRD
...
Diffstat (limited to 'arch/tile/mm')
-rw-r--r-- | arch/tile/mm/fault.c | 30 | ||||
-rw-r--r-- | arch/tile/mm/migrate_64.S | 187 |
2 files changed, 206 insertions, 11 deletions
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c index 51f8663bf074..25b7b90fd620 100644 --- a/arch/tile/mm/fault.c +++ b/arch/tile/mm/fault.c | |||
@@ -43,8 +43,11 @@ | |||
43 | 43 | ||
44 | #include <arch/interrupts.h> | 44 | #include <arch/interrupts.h> |
45 | 45 | ||
46 | static noinline void force_sig_info_fault(int si_signo, int si_code, | 46 | static noinline void force_sig_info_fault(const char *type, int si_signo, |
47 | unsigned long address, int fault_num, struct task_struct *tsk) | 47 | int si_code, unsigned long address, |
48 | int fault_num, | ||
49 | struct task_struct *tsk, | ||
50 | struct pt_regs *regs) | ||
48 | { | 51 | { |
49 | siginfo_t info; | 52 | siginfo_t info; |
50 | 53 | ||
@@ -59,6 +62,7 @@ static noinline void force_sig_info_fault(int si_signo, int si_code, | |||
59 | info.si_code = si_code; | 62 | info.si_code = si_code; |
60 | info.si_addr = (void __user *)address; | 63 | info.si_addr = (void __user *)address; |
61 | info.si_trapno = fault_num; | 64 | info.si_trapno = fault_num; |
65 | trace_unhandled_signal(type, regs, address, si_signo); | ||
62 | force_sig_info(si_signo, &info, tsk); | 66 | force_sig_info(si_signo, &info, tsk); |
63 | } | 67 | } |
64 | 68 | ||
@@ -71,11 +75,12 @@ SYSCALL_DEFINE2(cmpxchg_badaddr, unsigned long, address, | |||
71 | struct pt_regs *, regs) | 75 | struct pt_regs *, regs) |
72 | { | 76 | { |
73 | if (address >= PAGE_OFFSET) | 77 | if (address >= PAGE_OFFSET) |
74 | force_sig_info_fault(SIGSEGV, SEGV_MAPERR, address, | 78 | force_sig_info_fault("atomic segfault", SIGSEGV, SEGV_MAPERR, |
75 | INT_DTLB_MISS, current); | 79 | address, INT_DTLB_MISS, current, regs); |
76 | else | 80 | else |
77 | force_sig_info_fault(SIGBUS, BUS_ADRALN, address, | 81 | force_sig_info_fault("atomic alignment fault", SIGBUS, |
78 | INT_UNALIGN_DATA, current); | 82 | BUS_ADRALN, address, |
83 | INT_UNALIGN_DATA, current, regs); | ||
79 | 84 | ||
80 | /* | 85 | /* |
81 | * Adjust pc to point at the actual instruction, which is unusual | 86 | * Adjust pc to point at the actual instruction, which is unusual |
@@ -471,8 +476,8 @@ bad_area_nosemaphore: | |||
471 | */ | 476 | */ |
472 | local_irq_enable(); | 477 | local_irq_enable(); |
473 | 478 | ||
474 | force_sig_info_fault(SIGSEGV, si_code, address, | 479 | force_sig_info_fault("segfault", SIGSEGV, si_code, address, |
475 | fault_num, tsk); | 480 | fault_num, tsk, regs); |
476 | return 0; | 481 | return 0; |
477 | } | 482 | } |
478 | 483 | ||
@@ -547,7 +552,8 @@ do_sigbus: | |||
547 | if (is_kernel_mode) | 552 | if (is_kernel_mode) |
548 | goto no_context; | 553 | goto no_context; |
549 | 554 | ||
550 | force_sig_info_fault(SIGBUS, BUS_ADRERR, address, fault_num, tsk); | 555 | force_sig_info_fault("bus error", SIGBUS, BUS_ADRERR, address, |
556 | fault_num, tsk, regs); | ||
551 | return 0; | 557 | return 0; |
552 | } | 558 | } |
553 | 559 | ||
@@ -732,6 +738,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num, | |||
732 | panic("Bad fault number %d in do_page_fault", fault_num); | 738 | panic("Bad fault number %d in do_page_fault", fault_num); |
733 | } | 739 | } |
734 | 740 | ||
741 | #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() | ||
735 | if (EX1_PL(regs->ex1) != USER_PL) { | 742 | if (EX1_PL(regs->ex1) != USER_PL) { |
736 | struct async_tlb *async; | 743 | struct async_tlb *async; |
737 | switch (fault_num) { | 744 | switch (fault_num) { |
@@ -775,6 +782,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num, | |||
775 | return; | 782 | return; |
776 | } | 783 | } |
777 | } | 784 | } |
785 | #endif | ||
778 | 786 | ||
779 | handle_page_fault(regs, fault_num, is_page_fault, address, write); | 787 | handle_page_fault(regs, fault_num, is_page_fault, address, write); |
780 | } | 788 | } |
@@ -801,8 +809,6 @@ static void handle_async_page_fault(struct pt_regs *regs, | |||
801 | async->address, async->is_write); | 809 | async->address, async->is_write); |
802 | } | 810 | } |
803 | } | 811 | } |
804 | #endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */ | ||
805 | |||
806 | 812 | ||
807 | /* | 813 | /* |
808 | * This routine effectively re-issues asynchronous page faults | 814 | * This routine effectively re-issues asynchronous page faults |
@@ -824,6 +830,8 @@ void do_async_page_fault(struct pt_regs *regs) | |||
824 | handle_async_page_fault(regs, ¤t->thread.sn_async_tlb); | 830 | handle_async_page_fault(regs, ¤t->thread.sn_async_tlb); |
825 | #endif | 831 | #endif |
826 | } | 832 | } |
833 | #endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */ | ||
834 | |||
827 | 835 | ||
828 | void vmalloc_sync_all(void) | 836 | void vmalloc_sync_all(void) |
829 | { | 837 | { |
diff --git a/arch/tile/mm/migrate_64.S b/arch/tile/mm/migrate_64.S new file mode 100644 index 000000000000..e76fea688beb --- /dev/null +++ b/arch/tile/mm/migrate_64.S | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * This routine is a helper for migrating the home of a set of pages to | ||
15 | * a new cpu. See the documentation in homecache.c for more information. | ||
16 | */ | ||
17 | |||
18 | #include <linux/linkage.h> | ||
19 | #include <linux/threads.h> | ||
20 | #include <asm/page.h> | ||
21 | #include <asm/thread_info.h> | ||
22 | #include <asm/types.h> | ||
23 | #include <asm/asm-offsets.h> | ||
24 | #include <hv/hypervisor.h> | ||
25 | |||
26 | .text | ||
27 | |||
28 | /* | ||
29 | * First, some definitions that apply to all the code in the file. | ||
30 | */ | ||
31 | |||
32 | /* Locals (caller-save) */ | ||
33 | #define r_tmp r10 | ||
34 | #define r_save_sp r11 | ||
35 | |||
36 | /* What we save where in the stack frame; must include all callee-saves. */ | ||
37 | #define FRAME_SP 8 | ||
38 | #define FRAME_R30 16 | ||
39 | #define FRAME_R31 24 | ||
40 | #define FRAME_R32 32 | ||
41 | #define FRAME_R33 40 | ||
42 | #define FRAME_SIZE 48 | ||
43 | |||
44 | |||
45 | |||
46 | |||
47 | /* | ||
48 | * On entry: | ||
49 | * | ||
50 | * r0 the new context PA to install (moved to r_context) | ||
51 | * r1 PTE to use for context access (moved to r_access) | ||
52 | * r2 ASID to use for new context (moved to r_asid) | ||
53 | * r3 pointer to cpumask with just this cpu set in it (r_my_cpumask) | ||
54 | */ | ||
55 | |||
56 | /* Arguments (caller-save) */ | ||
57 | #define r_context_in r0 | ||
58 | #define r_access_in r1 | ||
59 | #define r_asid_in r2 | ||
60 | #define r_my_cpumask r3 | ||
61 | |||
62 | /* Locals (callee-save); must not be more than FRAME_xxx above. */ | ||
63 | #define r_save_ics r30 | ||
64 | #define r_context r31 | ||
65 | #define r_access r32 | ||
66 | #define r_asid r33 | ||
67 | |||
68 | /* | ||
69 | * Caller-save locals and frame constants are the same as | ||
70 | * for homecache_migrate_stack_and_flush. | ||
71 | */ | ||
72 | |||
73 | STD_ENTRY(flush_and_install_context) | ||
74 | /* | ||
75 | * Create a stack frame; we can't touch it once we flush the | ||
76 | * cache until we install the new page table and flush the TLB. | ||
77 | */ | ||
78 | { | ||
79 | move r_save_sp, sp | ||
80 | st sp, lr | ||
81 | addi sp, sp, -FRAME_SIZE | ||
82 | } | ||
83 | addi r_tmp, sp, FRAME_SP | ||
84 | { | ||
85 | st r_tmp, r_save_sp | ||
86 | addi r_tmp, sp, FRAME_R30 | ||
87 | } | ||
88 | { | ||
89 | st r_tmp, r30 | ||
90 | addi r_tmp, sp, FRAME_R31 | ||
91 | } | ||
92 | { | ||
93 | st r_tmp, r31 | ||
94 | addi r_tmp, sp, FRAME_R32 | ||
95 | } | ||
96 | { | ||
97 | st r_tmp, r32 | ||
98 | addi r_tmp, sp, FRAME_R33 | ||
99 | } | ||
100 | st r_tmp, r33 | ||
101 | |||
102 | /* Move some arguments to callee-save registers. */ | ||
103 | { | ||
104 | move r_context, r_context_in | ||
105 | move r_access, r_access_in | ||
106 | } | ||
107 | move r_asid, r_asid_in | ||
108 | |||
109 | /* Disable interrupts, since we can't use our stack. */ | ||
110 | { | ||
111 | mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION | ||
112 | movei r_tmp, 1 | ||
113 | } | ||
114 | mtspr INTERRUPT_CRITICAL_SECTION, r_tmp | ||
115 | |||
116 | /* First, flush our L2 cache. */ | ||
117 | { | ||
118 | move r0, zero /* cache_pa */ | ||
119 | moveli r1, hw2_last(HV_FLUSH_EVICT_L2) /* cache_control */ | ||
120 | } | ||
121 | { | ||
122 | shl16insli r1, r1, hw1(HV_FLUSH_EVICT_L2) | ||
123 | move r2, r_my_cpumask /* cache_cpumask */ | ||
124 | } | ||
125 | { | ||
126 | shl16insli r1, r1, hw0(HV_FLUSH_EVICT_L2) | ||
127 | move r3, zero /* tlb_va */ | ||
128 | } | ||
129 | { | ||
130 | move r4, zero /* tlb_length */ | ||
131 | move r5, zero /* tlb_pgsize */ | ||
132 | } | ||
133 | { | ||
134 | move r6, zero /* tlb_cpumask */ | ||
135 | move r7, zero /* asids */ | ||
136 | } | ||
137 | { | ||
138 | move r8, zero /* asidcount */ | ||
139 | jal hv_flush_remote | ||
140 | } | ||
141 | bnez r0, 1f | ||
142 | |||
143 | /* Now install the new page table. */ | ||
144 | { | ||
145 | move r0, r_context | ||
146 | move r1, r_access | ||
147 | } | ||
148 | { | ||
149 | move r2, r_asid | ||
150 | movei r3, HV_CTX_DIRECTIO | ||
151 | } | ||
152 | jal hv_install_context | ||
153 | bnez r0, 1f | ||
154 | |||
155 | /* Finally, flush the TLB. */ | ||
156 | { | ||
157 | movei r0, 0 /* preserve_global */ | ||
158 | jal hv_flush_all | ||
159 | } | ||
160 | |||
161 | 1: /* Reset interrupts back how they were before. */ | ||
162 | mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics | ||
163 | |||
164 | /* Restore the callee-saved registers and return. */ | ||
165 | addli lr, sp, FRAME_SIZE | ||
166 | { | ||
167 | ld lr, lr | ||
168 | addli r_tmp, sp, FRAME_R30 | ||
169 | } | ||
170 | { | ||
171 | ld r30, r_tmp | ||
172 | addli r_tmp, sp, FRAME_R31 | ||
173 | } | ||
174 | { | ||
175 | ld r31, r_tmp | ||
176 | addli r_tmp, sp, FRAME_R32 | ||
177 | } | ||
178 | { | ||
179 | ld r32, r_tmp | ||
180 | addli r_tmp, sp, FRAME_R33 | ||
181 | } | ||
182 | { | ||
183 | ld r33, r_tmp | ||
184 | addi sp, sp, FRAME_SIZE | ||
185 | } | ||
186 | jrp lr | ||
187 | STD_ENDPROC(flush_and_install_context) | ||