Skip to content

Commit a6d3bd2

Browse files
committed
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
2 parents 2409c87 + 72d0ac0 commit a6d3bd2

File tree

4 files changed

+26
-23
lines changed

4 files changed

+26
-23
lines changed

arch/arm64/include/asm/pgtable.h

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
/*
2525
* Software defined PTE bits definition.
2626
*/
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 */
2829
#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */
2930
#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
3031
#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
@@ -60,9 +61,12 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
6061

6162
extern pgprot_t pgprot_default;
6263

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)
6468

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)
6670
#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
6771
#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
6872
#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;
7276
#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY)
7377
#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY)
7478

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)
7680
#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
7781
#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
7882
#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;
125129
/*
126130
* The following only work if pte_present(). Undefined behaviour otherwise.
127131
*/
128-
#define pte_present(pte) (pte_val(pte) & PTE_VALID)
132+
#define pte_present(pte) (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE))
129133
#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY)
130134
#define pte_young(pte) (pte_val(pte) & PTE_AF)
131135
#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL)
132136
#define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY))
133137
#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
134138

135-
#define pte_present_exec_user(pte) \
136-
((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \
137-
(PTE_VALID | PTE_USER))
139+
#define pte_valid_user(pte) \
140+
((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
138141

139142
#define PTE_BIT_FUNC(fn,op) \
140143
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);
157160
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
158161
pte_t *ptep, pte_t pte)
159162
{
160-
if (pte_present_exec_user(pte))
161-
__sync_icache_dcache(pte, addr);
162-
if (!pte_dirty(pte))
163-
pte = pte_wrprotect(pte);
163+
if (pte_valid_user(pte)) {
164+
if (pte_exec(pte))
165+
__sync_icache_dcache(pte, addr);
166+
if (!pte_dirty(pte))
167+
pte = pte_wrprotect(pte);
168+
}
169+
164170
set_pte(ptep, pte);
165171
}
166172

@@ -170,9 +176,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
170176
#define pte_huge(pte) ((pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_HUGEPAGE)
171177
#define pte_mkhuge(pte) (__pte((pte_val(pte) & ~PTE_TYPE_MASK) | PTE_TYPE_HUGEPAGE))
172178

173-
#define __pgprot_modify(prot,mask,bits) \
174-
__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
175-
176179
#define __HAVE_ARCH_PTE_SPECIAL
177180

178181
/*
@@ -264,7 +267,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
264267

265268
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
266269
{
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;
268272
pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
269273
return pte;
270274
}

arch/arm64/include/asm/unistd32.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,13 @@ __SYSCALL(370, sys_name_to_handle_at)
395395
__SYSCALL(371, compat_sys_open_by_handle_at)
396396
__SYSCALL(372, compat_sys_clock_adjtime)
397397
__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 */
398403

399-
#define __NR_compat_syscalls 374
404+
#define __NR_compat_syscalls 379
400405

401406
/*
402407
* Compat syscall numbers used by the AArch64 kernel.

arch/arm64/kernel/vdso.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,6 @@ void update_vsyscall(struct timekeeper *tk)
252252

253253
void update_vsyscall_tz(void)
254254
{
255-
++vdso_data->tb_seq_count;
256-
smp_wmb();
257255
vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
258256
vdso_data->tz_dsttime = sys_tz.tz_dsttime;
259-
smp_wmb();
260-
++vdso_data->tb_seq_count;
261257
}

arch/arm64/kernel/vdso/gettimeofday.S

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ ENTRY(__kernel_gettimeofday)
7373
/* If tz is NULL, return 0. */
7474
cbz x1, 3f
7575
ldp w4, w5, [vdso_data, #VDSO_TZ_MINWEST]
76-
seqcnt_read w9
77-
seqcnt_check w9, 1b
7876
stp w4, w5, [x1, #TZ_MINWEST]
7977
3:
8078
mov x0, xzr

0 commit comments

Comments
 (0)