diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 22:34:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 22:34:12 -0400 |
commit | 08351fc6a75731226e1112fc7254542bd3a2912e (patch) | |
tree | 8b25bd168e0663c766f0332c8be082aa7d6ed265 /arch/tile/include/asm | |
parent | 0df0914d414a504b975f3cc66ace0c16ef55b7f3 (diff) | |
parent | 0dccb0489f9a5a13a33e828ab965aa49685d12f8 (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: (27 commits)
arch/tile: support newer binutils assembler shift semantics
arch/tile: fix deadlock bugs in rwlock implementation
drivers/edac: provide support for tile architecture
tile on-chip network driver: sync up with latest fixes
arch/tile: support 4KB page size as well as 64KB
arch/tile: add some more VMSPLIT options and use consistent naming
arch/tile: fix some comments and whitespace
arch/tile: export some additional module symbols
arch/tile: enhance existing finv_buffer_remote() routine
arch/tile: fix two bugs in the backtracer code
arch/tile: use extended assembly to inline __mb_incoherent()
arch/tile: use a cleaner technique to enable interrupt for cpu_idle()
arch/tile: sync up with <arch/sim.h> and <arch/sim_def.h> changes
arch/tile: fix reversed test of strict_strtol() return value
arch/tile: avoid a simulator warning during bootup
arch/tile: export <asm/hardwall.h> to userspace
arch/tile: warn and retry if an IPI is not accepted by the target cpu
arch/tile: stop disabling INTCTRL_1 interrupts during hypervisor downcalls
arch/tile: fix __ndelay etc to work better
arch/tile: bug fix: exec'ed task thought it was still single-stepping
...
Fix up trivial conflict in arch/tile/kernel/vmlinux.lds.S (percpu
alignment vs section naming convention fix)
Diffstat (limited to 'arch/tile/include/asm')
-rw-r--r-- | arch/tile/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/tile/include/asm/atomic.h | 2 | ||||
-rw-r--r-- | arch/tile/include/asm/bitops_32.h | 2 | ||||
-rw-r--r-- | arch/tile/include/asm/cache.h | 2 | ||||
-rw-r--r-- | arch/tile/include/asm/cacheflush.h | 55 | ||||
-rw-r--r-- | arch/tile/include/asm/edac.h | 29 | ||||
-rw-r--r-- | arch/tile/include/asm/hugetlb.h | 2 | ||||
-rw-r--r-- | arch/tile/include/asm/irqflags.h | 18 | ||||
-rw-r--r-- | arch/tile/include/asm/page.h | 34 | ||||
-rw-r--r-- | arch/tile/include/asm/pgalloc.h | 7 | ||||
-rw-r--r-- | arch/tile/include/asm/pgtable.h | 31 | ||||
-rw-r--r-- | arch/tile/include/asm/pgtable_32.h | 8 | ||||
-rw-r--r-- | arch/tile/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/tile/include/asm/ptrace.h | 3 | ||||
-rw-r--r-- | arch/tile/include/asm/spinlock_32.h | 83 | ||||
-rw-r--r-- | arch/tile/include/asm/stack.h | 3 | ||||
-rw-r--r-- | arch/tile/include/asm/system.h | 19 | ||||
-rw-r--r-- | arch/tile/include/asm/thread_info.h | 1 | ||||
-rw-r--r-- | arch/tile/include/asm/timex.h | 3 |
19 files changed, 125 insertions, 179 deletions
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index 3b8f55b82dee..849ab2fa1f5c 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild | |||
@@ -1,3 +1,4 @@ | |||
1 | include include/asm-generic/Kbuild.asm | 1 | include include/asm-generic/Kbuild.asm |
2 | 2 | ||
3 | header-y += ucontext.h | 3 | header-y += ucontext.h |
4 | header-y += hardwall.h | ||
diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h index b8c49f98a44c..75a16028a952 100644 --- a/arch/tile/include/asm/atomic.h +++ b/arch/tile/include/asm/atomic.h | |||
@@ -32,7 +32,7 @@ | |||
32 | */ | 32 | */ |
33 | static inline int atomic_read(const atomic_t *v) | 33 | static inline int atomic_read(const atomic_t *v) |
34 | { | 34 | { |
35 | return v->counter; | 35 | return ACCESS_ONCE(v->counter); |
36 | } | 36 | } |
37 | 37 | ||
38 | /** | 38 | /** |
diff --git a/arch/tile/include/asm/bitops_32.h b/arch/tile/include/asm/bitops_32.h index 7a93c001ac19..2638be51a164 100644 --- a/arch/tile/include/asm/bitops_32.h +++ b/arch/tile/include/asm/bitops_32.h | |||
@@ -122,7 +122,7 @@ static inline int test_and_change_bit(unsigned nr, | |||
122 | return (_atomic_xor(addr, mask) & mask) != 0; | 122 | return (_atomic_xor(addr, mask) & mask) != 0; |
123 | } | 123 | } |
124 | 124 | ||
125 | /* See discussion at smp_mb__before_atomic_dec() in <asm/atomic.h>. */ | 125 | /* See discussion at smp_mb__before_atomic_dec() in <asm/atomic_32.h>. */ |
126 | #define smp_mb__before_clear_bit() smp_mb() | 126 | #define smp_mb__before_clear_bit() smp_mb() |
127 | #define smp_mb__after_clear_bit() do {} while (0) | 127 | #define smp_mb__after_clear_bit() do {} while (0) |
128 | 128 | ||
diff --git a/arch/tile/include/asm/cache.h b/arch/tile/include/asm/cache.h index 08a2815b5e4e..392e5333dd8b 100644 --- a/arch/tile/include/asm/cache.h +++ b/arch/tile/include/asm/cache.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #define INTERNODE_CACHE_BYTES L2_CACHE_BYTES | 40 | #define INTERNODE_CACHE_BYTES L2_CACHE_BYTES |
41 | 41 | ||
42 | /* Group together read-mostly things to avoid cache false sharing */ | 42 | /* Group together read-mostly things to avoid cache false sharing */ |
43 | #define __read_mostly __attribute__((__section__(".data.read_mostly"))) | 43 | #define __read_mostly __attribute__((__section__(".data..read_mostly"))) |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * Attribute for data that is kept read/write coherent until the end of | 46 | * Attribute for data that is kept read/write coherent until the end of |
diff --git a/arch/tile/include/asm/cacheflush.h b/arch/tile/include/asm/cacheflush.h index 14a3f8556ace..12fb0fb330ee 100644 --- a/arch/tile/include/asm/cacheflush.h +++ b/arch/tile/include/asm/cacheflush.h | |||
@@ -138,55 +138,12 @@ static inline void finv_buffer(void *buffer, size_t size) | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /* | 140 | /* |
141 | * Flush & invalidate a VA range that is homed remotely on a single core, | 141 | * Flush and invalidate a VA range that is homed remotely, waiting |
142 | * waiting until the memory controller holds the flushed values. | 142 | * until the memory controller holds the flushed values. If "hfh" is |
143 | * true, we will do a more expensive flush involving additional loads | ||
144 | * to make sure we have touched all the possible home cpus of a buffer | ||
145 | * that is homed with "hash for home". | ||
143 | */ | 146 | */ |
144 | static inline void finv_buffer_remote(void *buffer, size_t size) | 147 | void finv_buffer_remote(void *buffer, size_t size, int hfh); |
145 | { | ||
146 | char *p; | ||
147 | int i; | ||
148 | |||
149 | /* | ||
150 | * Flush and invalidate the buffer out of the local L1/L2 | ||
151 | * and request the home cache to flush and invalidate as well. | ||
152 | */ | ||
153 | __finv_buffer(buffer, size); | ||
154 | |||
155 | /* | ||
156 | * Wait for the home cache to acknowledge that it has processed | ||
157 | * all the flush-and-invalidate requests. This does not mean | ||
158 | * that the flushed data has reached the memory controller yet, | ||
159 | * but it does mean the home cache is processing the flushes. | ||
160 | */ | ||
161 | __insn_mf(); | ||
162 | |||
163 | /* | ||
164 | * Issue a load to the last cache line, which can't complete | ||
165 | * until all the previously-issued flushes to the same memory | ||
166 | * controller have also completed. If we weren't striping | ||
167 | * memory, that one load would be sufficient, but since we may | ||
168 | * be, we also need to back up to the last load issued to | ||
169 | * another memory controller, which would be the point where | ||
170 | * we crossed an 8KB boundary (the granularity of striping | ||
171 | * across memory controllers). Keep backing up and doing this | ||
172 | * until we are before the beginning of the buffer, or have | ||
173 | * hit all the controllers. | ||
174 | */ | ||
175 | for (i = 0, p = (char *)buffer + size - 1; | ||
176 | i < (1 << CHIP_LOG_NUM_MSHIMS()) && p >= (char *)buffer; | ||
177 | ++i) { | ||
178 | const unsigned long STRIPE_WIDTH = 8192; | ||
179 | |||
180 | /* Force a load instruction to issue. */ | ||
181 | *(volatile char *)p; | ||
182 | |||
183 | /* Jump to end of previous stripe. */ | ||
184 | p -= STRIPE_WIDTH; | ||
185 | p = (char *)((unsigned long)p | (STRIPE_WIDTH - 1)); | ||
186 | } | ||
187 | |||
188 | /* Wait for the loads (and thus flushes) to have completed. */ | ||
189 | __insn_mf(); | ||
190 | } | ||
191 | 148 | ||
192 | #endif /* _ASM_TILE_CACHEFLUSH_H */ | 149 | #endif /* _ASM_TILE_CACHEFLUSH_H */ |
diff --git a/arch/tile/include/asm/edac.h b/arch/tile/include/asm/edac.h new file mode 100644 index 000000000000..87fc83eeaffd --- /dev/null +++ b/arch/tile/include/asm/edac.h | |||
@@ -0,0 +1,29 @@ | |||
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 | |||
15 | #ifndef _ASM_TILE_EDAC_H | ||
16 | #define _ASM_TILE_EDAC_H | ||
17 | |||
18 | /* ECC atomic, DMA, SMP and interrupt safe scrub function */ | ||
19 | |||
20 | static inline void atomic_scrub(void *va, u32 size) | ||
21 | { | ||
22 | /* | ||
23 | * These is nothing to be done here because CE is | ||
24 | * corrected by the mshim. | ||
25 | */ | ||
26 | return; | ||
27 | } | ||
28 | |||
29 | #endif /* _ASM_TILE_EDAC_H */ | ||
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h index 0521c277bbde..d396d1805163 100644 --- a/arch/tile/include/asm/hugetlb.h +++ b/arch/tile/include/asm/hugetlb.h | |||
@@ -54,7 +54,7 @@ static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb, | |||
54 | static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 54 | static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
55 | pte_t *ptep, pte_t pte) | 55 | pte_t *ptep, pte_t pte) |
56 | { | 56 | { |
57 | set_pte_order(ptep, pte, HUGETLB_PAGE_ORDER); | 57 | set_pte(ptep, pte); |
58 | } | 58 | } |
59 | 59 | ||
60 | static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | 60 | static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, |
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h index 641e4ff3d805..5db0ce54284d 100644 --- a/arch/tile/include/asm/irqflags.h +++ b/arch/tile/include/asm/irqflags.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <arch/interrupts.h> | 18 | #include <arch/interrupts.h> |
19 | #include <arch/chip.h> | 19 | #include <arch/chip.h> |
20 | 20 | ||
21 | #if !defined(__tilegx__) && defined(__ASSEMBLY__) | ||
22 | |||
21 | /* | 23 | /* |
22 | * The set of interrupts we want to allow when interrupts are nominally | 24 | * The set of interrupts we want to allow when interrupts are nominally |
23 | * disabled. The remainder are effectively "NMI" interrupts from | 25 | * disabled. The remainder are effectively "NMI" interrupts from |
@@ -25,6 +27,16 @@ | |||
25 | * interrupts (aka "non-queued") are not blocked by the mask in any case. | 27 | * interrupts (aka "non-queued") are not blocked by the mask in any case. |
26 | */ | 28 | */ |
27 | #if CHIP_HAS_AUX_PERF_COUNTERS() | 29 | #if CHIP_HAS_AUX_PERF_COUNTERS() |
30 | #define LINUX_MASKABLE_INTERRUPTS_HI \ | ||
31 | (~(INT_MASK_HI(INT_PERF_COUNT) | INT_MASK_HI(INT_AUX_PERF_COUNT))) | ||
32 | #else | ||
33 | #define LINUX_MASKABLE_INTERRUPTS_HI \ | ||
34 | (~(INT_MASK_HI(INT_PERF_COUNT))) | ||
35 | #endif | ||
36 | |||
37 | #else | ||
38 | |||
39 | #if CHIP_HAS_AUX_PERF_COUNTERS() | ||
28 | #define LINUX_MASKABLE_INTERRUPTS \ | 40 | #define LINUX_MASKABLE_INTERRUPTS \ |
29 | (~(INT_MASK(INT_PERF_COUNT) | INT_MASK(INT_AUX_PERF_COUNT))) | 41 | (~(INT_MASK(INT_PERF_COUNT) | INT_MASK(INT_AUX_PERF_COUNT))) |
30 | #else | 42 | #else |
@@ -32,6 +44,8 @@ | |||
32 | (~(INT_MASK(INT_PERF_COUNT))) | 44 | (~(INT_MASK(INT_PERF_COUNT))) |
33 | #endif | 45 | #endif |
34 | 46 | ||
47 | #endif | ||
48 | |||
35 | #ifndef __ASSEMBLY__ | 49 | #ifndef __ASSEMBLY__ |
36 | 50 | ||
37 | /* NOTE: we can't include <linux/percpu.h> due to #include dependencies. */ | 51 | /* NOTE: we can't include <linux/percpu.h> due to #include dependencies. */ |
@@ -224,11 +238,11 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); | |||
224 | #define IRQ_DISABLE(tmp0, tmp1) \ | 238 | #define IRQ_DISABLE(tmp0, tmp1) \ |
225 | { \ | 239 | { \ |
226 | movei tmp0, -1; \ | 240 | movei tmp0, -1; \ |
227 | moveli tmp1, lo16(LINUX_MASKABLE_INTERRUPTS) \ | 241 | moveli tmp1, lo16(LINUX_MASKABLE_INTERRUPTS_HI) \ |
228 | }; \ | 242 | }; \ |
229 | { \ | 243 | { \ |
230 | mtspr SPR_INTERRUPT_MASK_SET_K_0, tmp0; \ | 244 | mtspr SPR_INTERRUPT_MASK_SET_K_0, tmp0; \ |
231 | auli tmp1, tmp1, ha16(LINUX_MASKABLE_INTERRUPTS) \ | 245 | auli tmp1, tmp1, ha16(LINUX_MASKABLE_INTERRUPTS_HI) \ |
232 | }; \ | 246 | }; \ |
233 | mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp1 | 247 | mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp1 |
234 | 248 | ||
diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h index 7979a45430d3..3eb53525bf9d 100644 --- a/arch/tile/include/asm/page.h +++ b/arch/tile/include/asm/page.h | |||
@@ -16,10 +16,11 @@ | |||
16 | #define _ASM_TILE_PAGE_H | 16 | #define _ASM_TILE_PAGE_H |
17 | 17 | ||
18 | #include <linux/const.h> | 18 | #include <linux/const.h> |
19 | #include <hv/pagesize.h> | ||
19 | 20 | ||
20 | /* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */ | 21 | /* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */ |
21 | #define PAGE_SHIFT 16 | 22 | #define PAGE_SHIFT HV_LOG2_PAGE_SIZE_SMALL |
22 | #define HPAGE_SHIFT 24 | 23 | #define HPAGE_SHIFT HV_LOG2_PAGE_SIZE_LARGE |
23 | 24 | ||
24 | #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) | 25 | #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) |
25 | #define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) | 26 | #define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) |
@@ -29,25 +30,18 @@ | |||
29 | 30 | ||
30 | #ifdef __KERNEL__ | 31 | #ifdef __KERNEL__ |
31 | 32 | ||
32 | #include <hv/hypervisor.h> | ||
33 | #include <arch/chip.h> | ||
34 | |||
35 | /* | 33 | /* |
36 | * The {,H}PAGE_SHIFT values must match the HV_LOG2_PAGE_SIZE_xxx | 34 | * If the Kconfig doesn't specify, set a maximum zone order that |
37 | * definitions in <hv/hypervisor.h>. We validate this at build time | 35 | * is enough so that we can create huge pages from small pages given |
38 | * here, and again at runtime during early boot. We provide a | 36 | * the respective sizes of the two page types. See <linux/mmzone.h>. |
39 | * separate definition since userspace doesn't have <hv/hypervisor.h>. | ||
40 | * | ||
41 | * Be careful to distinguish PAGE_SHIFT from HV_PTE_INDEX_PFN, since | ||
42 | * they are the same on i386 but not TILE. | ||
43 | */ | 37 | */ |
44 | #if HV_LOG2_PAGE_SIZE_SMALL != PAGE_SHIFT | 38 | #ifndef CONFIG_FORCE_MAX_ZONEORDER |
45 | # error Small page size mismatch in Linux | 39 | #define CONFIG_FORCE_MAX_ZONEORDER (HPAGE_SHIFT - PAGE_SHIFT + 1) |
46 | #endif | ||
47 | #if HV_LOG2_PAGE_SIZE_LARGE != HPAGE_SHIFT | ||
48 | # error Huge page size mismatch in Linux | ||
49 | #endif | 40 | #endif |
50 | 41 | ||
42 | #include <hv/hypervisor.h> | ||
43 | #include <arch/chip.h> | ||
44 | |||
51 | #ifndef __ASSEMBLY__ | 45 | #ifndef __ASSEMBLY__ |
52 | 46 | ||
53 | #include <linux/types.h> | 47 | #include <linux/types.h> |
@@ -81,12 +75,6 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr, | |||
81 | * Hypervisor page tables are made of the same basic structure. | 75 | * Hypervisor page tables are made of the same basic structure. |
82 | */ | 76 | */ |
83 | 77 | ||
84 | typedef __u64 pteval_t; | ||
85 | typedef __u64 pmdval_t; | ||
86 | typedef __u64 pudval_t; | ||
87 | typedef __u64 pgdval_t; | ||
88 | typedef __u64 pgprotval_t; | ||
89 | |||
90 | typedef HV_PTE pte_t; | 78 | typedef HV_PTE pte_t; |
91 | typedef HV_PTE pgd_t; | 79 | typedef HV_PTE pgd_t; |
92 | typedef HV_PTE pgprot_t; | 80 | typedef HV_PTE pgprot_t; |
diff --git a/arch/tile/include/asm/pgalloc.h b/arch/tile/include/asm/pgalloc.h index cf52791a5501..e919c0bdc22d 100644 --- a/arch/tile/include/asm/pgalloc.h +++ b/arch/tile/include/asm/pgalloc.h | |||
@@ -41,9 +41,9 @@ | |||
41 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) | 41 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) |
42 | { | 42 | { |
43 | #ifdef CONFIG_64BIT | 43 | #ifdef CONFIG_64BIT |
44 | set_pte_order(pmdp, pmd, L2_USER_PGTABLE_ORDER); | 44 | set_pte(pmdp, pmd); |
45 | #else | 45 | #else |
46 | set_pte_order(&pmdp->pud.pgd, pmd.pud.pgd, L2_USER_PGTABLE_ORDER); | 46 | set_pte(&pmdp->pud.pgd, pmd.pud.pgd); |
47 | #endif | 47 | #endif |
48 | } | 48 | } |
49 | 49 | ||
@@ -100,6 +100,9 @@ pte_t *get_prealloc_pte(unsigned long pfn); | |||
100 | /* During init, we can shatter kernel huge pages if needed. */ | 100 | /* During init, we can shatter kernel huge pages if needed. */ |
101 | void shatter_pmd(pmd_t *pmd); | 101 | void shatter_pmd(pmd_t *pmd); |
102 | 102 | ||
103 | /* After init, a more complex technique is required. */ | ||
104 | void shatter_huge_page(unsigned long addr); | ||
105 | |||
103 | #ifdef __tilegx__ | 106 | #ifdef __tilegx__ |
104 | /* We share a single page allocator for both L1 and L2 page tables. */ | 107 | /* We share a single page allocator for both L1 and L2 page tables. */ |
105 | #if HV_L1_SIZE != HV_L2_SIZE | 108 | #if HV_L1_SIZE != HV_L2_SIZE |
diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h index a6604e9485da..1a20b7ef8ea2 100644 --- a/arch/tile/include/asm/pgtable.h +++ b/arch/tile/include/asm/pgtable.h | |||
@@ -233,15 +233,23 @@ static inline void __pte_clear(pte_t *ptep) | |||
233 | #define pgd_ERROR(e) \ | 233 | #define pgd_ERROR(e) \ |
234 | pr_err("%s:%d: bad pgd 0x%016llx.\n", __FILE__, __LINE__, pgd_val(e)) | 234 | pr_err("%s:%d: bad pgd 0x%016llx.\n", __FILE__, __LINE__, pgd_val(e)) |
235 | 235 | ||
236 | /* Return PA and protection info for a given kernel VA. */ | ||
237 | int va_to_cpa_and_pte(void *va, phys_addr_t *cpa, pte_t *pte); | ||
238 | |||
239 | /* | ||
240 | * __set_pte() ensures we write the 64-bit PTE with 32-bit words in | ||
241 | * the right order on 32-bit platforms and also allows us to write | ||
242 | * hooks to check valid PTEs, etc., if we want. | ||
243 | */ | ||
244 | void __set_pte(pte_t *ptep, pte_t pte); | ||
245 | |||
236 | /* | 246 | /* |
237 | * set_pte_order() sets the given PTE and also sanity-checks the | 247 | * set_pte() sets the given PTE and also sanity-checks the |
238 | * requested PTE against the page homecaching. Unspecified parts | 248 | * requested PTE against the page homecaching. Unspecified parts |
239 | * of the PTE are filled in when it is written to memory, i.e. all | 249 | * of the PTE are filled in when it is written to memory, i.e. all |
240 | * caching attributes if "!forcecache", or the home cpu if "anyhome". | 250 | * caching attributes if "!forcecache", or the home cpu if "anyhome". |
241 | */ | 251 | */ |
242 | extern void set_pte_order(pte_t *ptep, pte_t pte, int order); | 252 | extern void set_pte(pte_t *ptep, pte_t pte); |
243 | |||
244 | #define set_pte(ptep, pteval) set_pte_order(ptep, pteval, 0) | ||
245 | #define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) | 253 | #define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) |
246 | #define set_pte_atomic(pteptr, pteval) set_pte(pteptr, pteval) | 254 | #define set_pte_atomic(pteptr, pteval) set_pte(pteptr, pteval) |
247 | 255 | ||
@@ -293,21 +301,6 @@ extern void check_mm_caching(struct mm_struct *prev, struct mm_struct *next); | |||
293 | #define __swp_entry_to_pte(swp) ((pte_t) { (((long long) ((swp).val)) << 32) }) | 301 | #define __swp_entry_to_pte(swp) ((pte_t) { (((long long) ((swp).val)) << 32) }) |
294 | 302 | ||
295 | /* | 303 | /* |
296 | * clone_pgd_range(pgd_t *dst, pgd_t *src, int count); | ||
297 | * | ||
298 | * dst - pointer to pgd range anwhere on a pgd page | ||
299 | * src - "" | ||
300 | * count - the number of pgds to copy. | ||
301 | * | ||
302 | * dst and src can be on the same page, but the range must not overlap, | ||
303 | * and must not cross a page boundary. | ||
304 | */ | ||
305 | static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) | ||
306 | { | ||
307 | memcpy(dst, src, count * sizeof(pgd_t)); | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * Conversion functions: convert a page and protection to a page entry, | 304 | * Conversion functions: convert a page and protection to a page entry, |
312 | * and a page entry and page directory to the page they refer to. | 305 | * and a page entry and page directory to the page they refer to. |
313 | */ | 306 | */ |
diff --git a/arch/tile/include/asm/pgtable_32.h b/arch/tile/include/asm/pgtable_32.h index 53ec34884744..9f98529761fd 100644 --- a/arch/tile/include/asm/pgtable_32.h +++ b/arch/tile/include/asm/pgtable_32.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define PGDIR_SIZE HV_PAGE_SIZE_LARGE | 24 | #define PGDIR_SIZE HV_PAGE_SIZE_LARGE |
25 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | 25 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) |
26 | #define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT)) | 26 | #define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT)) |
27 | #define SIZEOF_PGD (PTRS_PER_PGD * sizeof(pgd_t)) | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * The level-2 index is defined by the difference between the huge | 30 | * The level-2 index is defined by the difference between the huge |
@@ -33,6 +34,7 @@ | |||
33 | * this nomenclature is somewhat confusing. | 34 | * this nomenclature is somewhat confusing. |
34 | */ | 35 | */ |
35 | #define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL)) | 36 | #define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL)) |
37 | #define SIZEOF_PTE (PTRS_PER_PTE * sizeof(pte_t)) | ||
36 | 38 | ||
37 | #ifndef __ASSEMBLY__ | 39 | #ifndef __ASSEMBLY__ |
38 | 40 | ||
@@ -94,7 +96,6 @@ static inline int pgd_addr_invalid(unsigned long addr) | |||
94 | */ | 96 | */ |
95 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | 97 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG |
96 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT | 98 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT |
97 | #define __HAVE_ARCH_PTEP_GET_AND_CLEAR | ||
98 | 99 | ||
99 | extern int ptep_test_and_clear_young(struct vm_area_struct *, | 100 | extern int ptep_test_and_clear_young(struct vm_area_struct *, |
100 | unsigned long addr, pte_t *); | 101 | unsigned long addr, pte_t *); |
@@ -110,6 +111,11 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, | |||
110 | return pte; | 111 | return pte; |
111 | } | 112 | } |
112 | 113 | ||
114 | static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval) | ||
115 | { | ||
116 | set_pte(&pmdp->pud.pgd, pmdval.pud.pgd); | ||
117 | } | ||
118 | |||
113 | /* Create a pmd from a PTFN. */ | 119 | /* Create a pmd from a PTFN. */ |
114 | static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot) | 120 | static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot) |
115 | { | 121 | { |
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h index a9e7c8760334..e6889474038a 100644 --- a/arch/tile/include/asm/processor.h +++ b/arch/tile/include/asm/processor.h | |||
@@ -269,7 +269,6 @@ extern char chip_model[64]; | |||
269 | /* Data on which physical memory controller corresponds to which NUMA node. */ | 269 | /* Data on which physical memory controller corresponds to which NUMA node. */ |
270 | extern int node_controller[]; | 270 | extern int node_controller[]; |
271 | 271 | ||
272 | |||
273 | /* Do we dump information to the console when a user application crashes? */ | 272 | /* Do we dump information to the console when a user application crashes? */ |
274 | extern int show_crashinfo; | 273 | extern int show_crashinfo; |
275 | 274 | ||
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h index ac6d343129d3..6be2246e015c 100644 --- a/arch/tile/include/asm/ptrace.h +++ b/arch/tile/include/asm/ptrace.h | |||
@@ -141,6 +141,9 @@ struct single_step_state { | |||
141 | /* Single-step the instruction at regs->pc */ | 141 | /* Single-step the instruction at regs->pc */ |
142 | extern void single_step_once(struct pt_regs *regs); | 142 | extern void single_step_once(struct pt_regs *regs); |
143 | 143 | ||
144 | /* Clean up after execve(). */ | ||
145 | extern void single_step_execve(void); | ||
146 | |||
144 | struct task_struct; | 147 | struct task_struct; |
145 | 148 | ||
146 | extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, | 149 | extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, |
diff --git a/arch/tile/include/asm/spinlock_32.h b/arch/tile/include/asm/spinlock_32.h index 88efdde8dd2b..a8f2c6e31a87 100644 --- a/arch/tile/include/asm/spinlock_32.h +++ b/arch/tile/include/asm/spinlock_32.h | |||
@@ -78,13 +78,6 @@ void arch_spin_unlock_wait(arch_spinlock_t *lock); | |||
78 | #define _RD_COUNT_SHIFT 24 | 78 | #define _RD_COUNT_SHIFT 24 |
79 | #define _RD_COUNT_WIDTH 8 | 79 | #define _RD_COUNT_WIDTH 8 |
80 | 80 | ||
81 | /* Internal functions; do not use. */ | ||
82 | void arch_read_lock_slow(arch_rwlock_t *, u32); | ||
83 | int arch_read_trylock_slow(arch_rwlock_t *); | ||
84 | void arch_read_unlock_slow(arch_rwlock_t *); | ||
85 | void arch_write_lock_slow(arch_rwlock_t *, u32); | ||
86 | void arch_write_unlock_slow(arch_rwlock_t *, u32); | ||
87 | |||
88 | /** | 81 | /** |
89 | * arch_read_can_lock() - would read_trylock() succeed? | 82 | * arch_read_can_lock() - would read_trylock() succeed? |
90 | */ | 83 | */ |
@@ -104,94 +97,32 @@ static inline int arch_write_can_lock(arch_rwlock_t *rwlock) | |||
104 | /** | 97 | /** |
105 | * arch_read_lock() - acquire a read lock. | 98 | * arch_read_lock() - acquire a read lock. |
106 | */ | 99 | */ |
107 | static inline void arch_read_lock(arch_rwlock_t *rwlock) | 100 | void arch_read_lock(arch_rwlock_t *rwlock); |
108 | { | ||
109 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
110 | if (unlikely(val << _RD_COUNT_WIDTH)) { | ||
111 | arch_read_lock_slow(rwlock, val); | ||
112 | return; | ||
113 | } | ||
114 | rwlock->lock = val + (1 << _RD_COUNT_SHIFT); | ||
115 | } | ||
116 | 101 | ||
117 | /** | 102 | /** |
118 | * arch_read_lock() - acquire a write lock. | 103 | * arch_write_lock() - acquire a write lock. |
119 | */ | 104 | */ |
120 | static inline void arch_write_lock(arch_rwlock_t *rwlock) | 105 | void arch_write_lock(arch_rwlock_t *rwlock); |
121 | { | ||
122 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
123 | if (unlikely(val != 0)) { | ||
124 | arch_write_lock_slow(rwlock, val); | ||
125 | return; | ||
126 | } | ||
127 | rwlock->lock = 1 << _WR_NEXT_SHIFT; | ||
128 | } | ||
129 | 106 | ||
130 | /** | 107 | /** |
131 | * arch_read_trylock() - try to acquire a read lock. | 108 | * arch_read_trylock() - try to acquire a read lock. |
132 | */ | 109 | */ |
133 | static inline int arch_read_trylock(arch_rwlock_t *rwlock) | 110 | int arch_read_trylock(arch_rwlock_t *rwlock); |
134 | { | ||
135 | int locked; | ||
136 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
137 | if (unlikely(val & 1)) | ||
138 | return arch_read_trylock_slow(rwlock); | ||
139 | locked = (val << _RD_COUNT_WIDTH) == 0; | ||
140 | rwlock->lock = val + (locked << _RD_COUNT_SHIFT); | ||
141 | return locked; | ||
142 | } | ||
143 | 111 | ||
144 | /** | 112 | /** |
145 | * arch_write_trylock() - try to acquire a write lock. | 113 | * arch_write_trylock() - try to acquire a write lock. |
146 | */ | 114 | */ |
147 | static inline int arch_write_trylock(arch_rwlock_t *rwlock) | 115 | int arch_write_trylock(arch_rwlock_t *rwlock); |
148 | { | ||
149 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
150 | |||
151 | /* | ||
152 | * If a tns is in progress, or there's a waiting or active locker, | ||
153 | * or active readers, we can't take the lock, so give up. | ||
154 | */ | ||
155 | if (unlikely(val != 0)) { | ||
156 | if (!(val & 1)) | ||
157 | rwlock->lock = val; | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* Set the "next" field to mark it locked. */ | ||
162 | rwlock->lock = 1 << _WR_NEXT_SHIFT; | ||
163 | return 1; | ||
164 | } | ||
165 | 116 | ||
166 | /** | 117 | /** |
167 | * arch_read_unlock() - release a read lock. | 118 | * arch_read_unlock() - release a read lock. |
168 | */ | 119 | */ |
169 | static inline void arch_read_unlock(arch_rwlock_t *rwlock) | 120 | void arch_read_unlock(arch_rwlock_t *rwlock); |
170 | { | ||
171 | u32 val; | ||
172 | mb(); /* guarantee anything modified under the lock is visible */ | ||
173 | val = __insn_tns((int *)&rwlock->lock); | ||
174 | if (unlikely(val & 1)) { | ||
175 | arch_read_unlock_slow(rwlock); | ||
176 | return; | ||
177 | } | ||
178 | rwlock->lock = val - (1 << _RD_COUNT_SHIFT); | ||
179 | } | ||
180 | 121 | ||
181 | /** | 122 | /** |
182 | * arch_write_unlock() - release a write lock. | 123 | * arch_write_unlock() - release a write lock. |
183 | */ | 124 | */ |
184 | static inline void arch_write_unlock(arch_rwlock_t *rwlock) | 125 | void arch_write_unlock(arch_rwlock_t *rwlock); |
185 | { | ||
186 | u32 val; | ||
187 | mb(); /* guarantee anything modified under the lock is visible */ | ||
188 | val = __insn_tns((int *)&rwlock->lock); | ||
189 | if (unlikely(val != (1 << _WR_NEXT_SHIFT))) { | ||
190 | arch_write_unlock_slow(rwlock, val); | ||
191 | return; | ||
192 | } | ||
193 | rwlock->lock = 0; | ||
194 | } | ||
195 | 126 | ||
196 | #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) | 127 | #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) |
197 | #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) | 128 | #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) |
diff --git a/arch/tile/include/asm/stack.h b/arch/tile/include/asm/stack.h index f908473c322d..4d97a2db932e 100644 --- a/arch/tile/include/asm/stack.h +++ b/arch/tile/include/asm/stack.h | |||
@@ -18,13 +18,14 @@ | |||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <asm/backtrace.h> | 20 | #include <asm/backtrace.h> |
21 | #include <asm/page.h> | ||
21 | #include <hv/hypervisor.h> | 22 | #include <hv/hypervisor.h> |
22 | 23 | ||
23 | /* Everything we need to keep track of a backtrace iteration */ | 24 | /* Everything we need to keep track of a backtrace iteration */ |
24 | struct KBacktraceIterator { | 25 | struct KBacktraceIterator { |
25 | BacktraceIterator it; | 26 | BacktraceIterator it; |
26 | struct task_struct *task; /* task we are backtracing */ | 27 | struct task_struct *task; /* task we are backtracing */ |
27 | HV_PTE *pgtable; /* page table for user space access */ | 28 | pte_t *pgtable; /* page table for user space access */ |
28 | int end; /* iteration complete. */ | 29 | int end; /* iteration complete. */ |
29 | int new_context; /* new context is starting */ | 30 | int new_context; /* new context is starting */ |
30 | int profile; /* profiling, so stop on async intrpt */ | 31 | int profile; /* profiling, so stop on async intrpt */ |
diff --git a/arch/tile/include/asm/system.h b/arch/tile/include/asm/system.h index 5388850deeb2..23d1842f4839 100644 --- a/arch/tile/include/asm/system.h +++ b/arch/tile/include/asm/system.h | |||
@@ -90,7 +90,24 @@ | |||
90 | #endif | 90 | #endif |
91 | 91 | ||
92 | #if !CHIP_HAS_MF_WAITS_FOR_VICTIMS() | 92 | #if !CHIP_HAS_MF_WAITS_FOR_VICTIMS() |
93 | int __mb_incoherent(void); /* Helper routine for mb_incoherent(). */ | 93 | #include <hv/syscall_public.h> |
94 | /* | ||
95 | * Issue an uncacheable load to each memory controller, then | ||
96 | * wait until those loads have completed. | ||
97 | */ | ||
98 | static inline void __mb_incoherent(void) | ||
99 | { | ||
100 | long clobber_r10; | ||
101 | asm volatile("swint2" | ||
102 | : "=R10" (clobber_r10) | ||
103 | : "R10" (HV_SYS_fence_incoherent) | ||
104 | : "r0", "r1", "r2", "r3", "r4", | ||
105 | "r5", "r6", "r7", "r8", "r9", | ||
106 | "r11", "r12", "r13", "r14", | ||
107 | "r15", "r16", "r17", "r18", "r19", | ||
108 | "r20", "r21", "r22", "r23", "r24", | ||
109 | "r25", "r26", "r27", "r28", "r29"); | ||
110 | } | ||
94 | #endif | 111 | #endif |
95 | 112 | ||
96 | /* Fence to guarantee visibility of stores to incoherent memory. */ | 113 | /* Fence to guarantee visibility of stores to incoherent memory. */ |
diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h index 3872f2b345d2..9e8e9c4dfa2a 100644 --- a/arch/tile/include/asm/thread_info.h +++ b/arch/tile/include/asm/thread_info.h | |||
@@ -68,6 +68,7 @@ struct thread_info { | |||
68 | #else | 68 | #else |
69 | #define THREAD_SIZE_ORDER (0) | 69 | #define THREAD_SIZE_ORDER (0) |
70 | #endif | 70 | #endif |
71 | #define THREAD_SIZE_PAGES (1 << THREAD_SIZE_ORDER) | ||
71 | 72 | ||
72 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) | 73 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |
73 | #define LOG2_THREAD_SIZE (PAGE_SHIFT + THREAD_SIZE_ORDER) | 74 | #define LOG2_THREAD_SIZE (PAGE_SHIFT + THREAD_SIZE_ORDER) |
diff --git a/arch/tile/include/asm/timex.h b/arch/tile/include/asm/timex.h index 3baf5fc4c0a1..29921f0b86da 100644 --- a/arch/tile/include/asm/timex.h +++ b/arch/tile/include/asm/timex.h | |||
@@ -38,6 +38,9 @@ static inline cycles_t get_cycles(void) | |||
38 | 38 | ||
39 | cycles_t get_clock_rate(void); | 39 | cycles_t get_clock_rate(void); |
40 | 40 | ||
41 | /* Convert nanoseconds to core clock cycles. */ | ||
42 | cycles_t ns2cycles(unsigned long nsecs); | ||
43 | |||
41 | /* Called at cpu initialization to set some low-level constants. */ | 44 | /* Called at cpu initialization to set some low-level constants. */ |
42 | void setup_clock(void); | 45 | void setup_clock(void); |
43 | 46 | ||