diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-16 12:44:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-16 12:44:40 -0500 |
commit | a6d3bd274b85218bf7dda925d14db81e1a8268b3 (patch) | |
tree | bb18def4472ed572b4844cb682642a4fab4c5b2a | |
parent | 2409c873be56278ea41c345b453f76813e5c3fed (diff) | |
parent | 72d0ac048f3ded4022cf1cc72f54073f6fcad72f (diff) |
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64
Pull arm64 fixes from Catalin Marinas:
- Page protection fixes, including proper PAGE_NONE handling
- Timezone vdso sequence counting fix
- Additional compat syscall wiring
* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64:
arm64: compat: add syscall table entries for new syscalls
arm64: mm: introduce present, faulting entries for PAGE_NONE
arm64: mm: only wrprotect clean ptes if they are present
arm64: vdso: remove broken, redundant sequence counting for timezones
-rw-r--r-- | arch/arm64/include/asm/pgtable.h | 36 | ||||
-rw-r--r-- | arch/arm64/include/asm/unistd32.h | 7 | ||||
-rw-r--r-- | arch/arm64/kernel/vdso.c | 4 | ||||
-rw-r--r-- | arch/arm64/kernel/vdso/gettimeofday.S | 2 |
4 files changed, 26 insertions, 23 deletions
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 64b133949502..e333a243bfcc 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
@@ -24,7 +24,8 @@ | |||
24 | /* | 24 | /* |
25 | * Software defined PTE bits definition. | 25 | * Software defined PTE bits definition. |
26 | */ | 26 | */ |
27 | #define PTE_VALID (_AT(pteval_t, 1) << 0) /* pte_present() check */ | 27 | #define PTE_VALID (_AT(pteval_t, 1) << 0) |
28 | #define PTE_PROT_NONE (_AT(pteval_t, 1) << 1) /* only when !PTE_VALID */ | ||
28 | #define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */ | 29 | #define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */ |
29 | #define PTE_DIRTY (_AT(pteval_t, 1) << 55) | 30 | #define PTE_DIRTY (_AT(pteval_t, 1) << 55) |
30 | #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) | 31 | #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) |
@@ -60,9 +61,12 @@ extern void __pgd_error(const char *file, int line, unsigned long val); | |||
60 | 61 | ||
61 | extern pgprot_t pgprot_default; | 62 | extern pgprot_t pgprot_default; |
62 | 63 | ||
63 | #define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) | 64 | #define __pgprot_modify(prot,mask,bits) \ |
65 | __pgprot((pgprot_val(prot) & ~(mask)) | (bits)) | ||
66 | |||
67 | #define _MOD_PROT(p, b) __pgprot_modify(p, 0, b) | ||
64 | 68 | ||
65 | #define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | 69 | #define PAGE_NONE __pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE) |
66 | #define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) | 70 | #define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) |
67 | #define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) | 71 | #define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) |
68 | #define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | 72 | #define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) |
@@ -72,7 +76,7 @@ extern pgprot_t pgprot_default; | |||
72 | #define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) | 76 | #define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) |
73 | #define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) | 77 | #define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) |
74 | 78 | ||
75 | #define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | 79 | #define __PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE) |
76 | #define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) | 80 | #define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) |
77 | #define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) | 81 | #define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) |
78 | #define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | 82 | #define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) |
@@ -125,16 +129,15 @@ extern struct page *empty_zero_page; | |||
125 | /* | 129 | /* |
126 | * The following only work if pte_present(). Undefined behaviour otherwise. | 130 | * The following only work if pte_present(). Undefined behaviour otherwise. |
127 | */ | 131 | */ |
128 | #define pte_present(pte) (pte_val(pte) & PTE_VALID) | 132 | #define pte_present(pte) (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)) |
129 | #define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY) | 133 | #define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY) |
130 | #define pte_young(pte) (pte_val(pte) & PTE_AF) | 134 | #define pte_young(pte) (pte_val(pte) & PTE_AF) |
131 | #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) | 135 | #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) |
132 | #define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) | 136 | #define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) |
133 | #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) | 137 | #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) |
134 | 138 | ||
135 | #define pte_present_exec_user(pte) \ | 139 | #define pte_valid_user(pte) \ |
136 | ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \ | 140 | ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) |
137 | (PTE_VALID | PTE_USER)) | ||
138 | 141 | ||
139 | #define PTE_BIT_FUNC(fn,op) \ | 142 | #define PTE_BIT_FUNC(fn,op) \ |
140 | static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } | 143 | static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } |
@@ -157,10 +160,13 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); | |||
157 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | 160 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, |
158 | pte_t *ptep, pte_t pte) | 161 | pte_t *ptep, pte_t pte) |
159 | { | 162 | { |
160 | if (pte_present_exec_user(pte)) | 163 | if (pte_valid_user(pte)) { |
161 | __sync_icache_dcache(pte, addr); | 164 | if (pte_exec(pte)) |
162 | if (!pte_dirty(pte)) | 165 | __sync_icache_dcache(pte, addr); |
163 | pte = pte_wrprotect(pte); | 166 | if (!pte_dirty(pte)) |
167 | pte = pte_wrprotect(pte); | ||
168 | } | ||
169 | |||
164 | set_pte(ptep, pte); | 170 | set_pte(ptep, pte); |
165 | } | 171 | } |
166 | 172 | ||
@@ -170,9 +176,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
170 | #define pte_huge(pte) ((pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_HUGEPAGE) | 176 | #define pte_huge(pte) ((pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_HUGEPAGE) |
171 | #define pte_mkhuge(pte) (__pte((pte_val(pte) & ~PTE_TYPE_MASK) | PTE_TYPE_HUGEPAGE)) | 177 | #define pte_mkhuge(pte) (__pte((pte_val(pte) & ~PTE_TYPE_MASK) | PTE_TYPE_HUGEPAGE)) |
172 | 178 | ||
173 | #define __pgprot_modify(prot,mask,bits) \ | ||
174 | __pgprot((pgprot_val(prot) & ~(mask)) | (bits)) | ||
175 | |||
176 | #define __HAVE_ARCH_PTE_SPECIAL | 179 | #define __HAVE_ARCH_PTE_SPECIAL |
177 | 180 | ||
178 | /* | 181 | /* |
@@ -264,7 +267,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) | |||
264 | 267 | ||
265 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 268 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
266 | { | 269 | { |
267 | const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY; | 270 | const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | |
271 | PTE_PROT_NONE | PTE_VALID; | ||
268 | pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); | 272 | pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); |
269 | return pte; | 273 | return pte; |
270 | } | 274 | } |
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index 58432625fdb3..5ef47ba3ed45 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h | |||
@@ -395,8 +395,13 @@ __SYSCALL(370, sys_name_to_handle_at) | |||
395 | __SYSCALL(371, compat_sys_open_by_handle_at) | 395 | __SYSCALL(371, compat_sys_open_by_handle_at) |
396 | __SYSCALL(372, compat_sys_clock_adjtime) | 396 | __SYSCALL(372, compat_sys_clock_adjtime) |
397 | __SYSCALL(373, sys_syncfs) | 397 | __SYSCALL(373, sys_syncfs) |
398 | __SYSCALL(374, compat_sys_sendmmsg) | ||
399 | __SYSCALL(375, sys_setns) | ||
400 | __SYSCALL(376, compat_sys_process_vm_readv) | ||
401 | __SYSCALL(377, compat_sys_process_vm_writev) | ||
402 | __SYSCALL(378, sys_ni_syscall) /* 378 for kcmp */ | ||
398 | 403 | ||
399 | #define __NR_compat_syscalls 374 | 404 | #define __NR_compat_syscalls 379 |
400 | 405 | ||
401 | /* | 406 | /* |
402 | * Compat syscall numbers used by the AArch64 kernel. | 407 | * Compat syscall numbers used by the AArch64 kernel. |
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index c958cb84d75f..6a389dc1bd49 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c | |||
@@ -252,10 +252,6 @@ void update_vsyscall(struct timekeeper *tk) | |||
252 | 252 | ||
253 | void update_vsyscall_tz(void) | 253 | void update_vsyscall_tz(void) |
254 | { | 254 | { |
255 | ++vdso_data->tb_seq_count; | ||
256 | smp_wmb(); | ||
257 | vdso_data->tz_minuteswest = sys_tz.tz_minuteswest; | 255 | vdso_data->tz_minuteswest = sys_tz.tz_minuteswest; |
258 | vdso_data->tz_dsttime = sys_tz.tz_dsttime; | 256 | vdso_data->tz_dsttime = sys_tz.tz_dsttime; |
259 | smp_wmb(); | ||
260 | ++vdso_data->tb_seq_count; | ||
261 | } | 257 | } |
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S index 8bf658d974f9..f0a6d10b5211 100644 --- a/arch/arm64/kernel/vdso/gettimeofday.S +++ b/arch/arm64/kernel/vdso/gettimeofday.S | |||
@@ -73,8 +73,6 @@ ENTRY(__kernel_gettimeofday) | |||
73 | /* If tz is NULL, return 0. */ | 73 | /* If tz is NULL, return 0. */ |
74 | cbz x1, 3f | 74 | cbz x1, 3f |
75 | ldp w4, w5, [vdso_data, #VDSO_TZ_MINWEST] | 75 | ldp w4, w5, [vdso_data, #VDSO_TZ_MINWEST] |
76 | seqcnt_read w9 | ||
77 | seqcnt_check w9, 1b | ||
78 | stp w4, w5, [x1, #TZ_MINWEST] | 76 | stp w4, w5, [x1, #TZ_MINWEST] |
79 | 3: | 77 | 3: |
80 | mov x0, xzr | 78 | mov x0, xzr |