Skip to content

Commit f96eddb

Browse files
author
Fox Snowpatch
committed
1 parent 7b23713 commit f96eddb

File tree

6 files changed

+39
-42
lines changed

6 files changed

+39
-42
lines changed

arch/powerpc/include/asm/mmu_context.h

-9
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,6 @@ static inline void enter_lazy_tlb(struct mm_struct *mm,
260260

261261
extern void arch_exit_mmap(struct mm_struct *mm);
262262

263-
static inline void arch_unmap(struct mm_struct *mm,
264-
unsigned long start, unsigned long end)
265-
{
266-
unsigned long vdso_base = (unsigned long)mm->context.vdso;
267-
268-
if (start <= vdso_base && vdso_base < end)
269-
mm->context.vdso = NULL;
270-
}
271-
272263
#ifdef CONFIG_PPC_MEM_KEYS
273264
bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write,
274265
bool execute, bool foreign);

arch/powerpc/kernel/vdso.c

+24-11
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,21 @@ static int vdso64_mremap(const struct vm_special_mapping *sm, struct vm_area_str
8181
return vdso_mremap(sm, new_vma, &vdso64_end - &vdso64_start);
8282
}
8383

84+
static void vdso_close(const struct vm_special_mapping *sm, struct vm_area_struct *vma)
85+
{
86+
struct mm_struct *mm = vma->vm_mm;
87+
88+
/*
89+
* close() is called for munmap() but also for mremap(). In the mremap()
90+
* case the vdso pointer has already been updated by the mremap() hook
91+
* above, so it must not be set to NULL here.
92+
*/
93+
if (vma->vm_start != (unsigned long)mm->context.vdso)
94+
return;
95+
96+
mm->context.vdso = NULL;
97+
}
98+
8499
static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
85100
struct vm_area_struct *vma, struct vm_fault *vmf);
86101

@@ -92,11 +107,13 @@ static struct vm_special_mapping vvar_spec __ro_after_init = {
92107
static struct vm_special_mapping vdso32_spec __ro_after_init = {
93108
.name = "[vdso]",
94109
.mremap = vdso32_mremap,
110+
.close = vdso_close,
95111
};
96112

97113
static struct vm_special_mapping vdso64_spec __ro_after_init = {
98114
.name = "[vdso]",
99115
.mremap = vdso64_mremap,
116+
.close = vdso_close,
100117
};
101118

102119
#ifdef CONFIG_TIME_NS
@@ -197,13 +214,6 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int
197214
/* Add required alignment. */
198215
vdso_base = ALIGN(vdso_base, VDSO_ALIGNMENT);
199216

200-
/*
201-
* Put vDSO base into mm struct. We need to do this before calling
202-
* install_special_mapping or the perf counter mmap tracking code
203-
* will fail to recognise it as a vDSO.
204-
*/
205-
mm->context.vdso = (void __user *)vdso_base + vvar_size;
206-
207217
vma = _install_special_mapping(mm, vdso_base, vvar_size,
208218
VM_READ | VM_MAYREAD | VM_IO |
209219
VM_DONTDUMP | VM_PFNMAP, &vvar_spec);
@@ -223,10 +233,15 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int
223233
vma = _install_special_mapping(mm, vdso_base + vvar_size, vdso_size,
224234
VM_READ | VM_EXEC | VM_MAYREAD |
225235
VM_MAYWRITE | VM_MAYEXEC, vdso_spec);
226-
if (IS_ERR(vma))
236+
if (IS_ERR(vma)) {
227237
do_munmap(mm, vdso_base, vvar_size, NULL);
238+
return PTR_ERR(vma);
239+
}
240+
241+
// Now that the mappings are in place, set the mm VDSO pointer
242+
mm->context.vdso = (void __user *)vdso_base + vvar_size;
228243

229-
return PTR_ERR_OR_ZERO(vma);
244+
return 0;
230245
}
231246

232247
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
@@ -240,8 +255,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
240255
return -EINTR;
241256

242257
rc = __arch_setup_additional_pages(bprm, uses_interp);
243-
if (rc)
244-
mm->context.vdso = NULL;
245258

246259
mmap_write_unlock(mm);
247260
return rc;

arch/x86/include/asm/mmu_context.h

-5
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,6 @@ static inline bool is_64bit_mm(struct mm_struct *mm)
232232
}
233233
#endif
234234

235-
static inline void arch_unmap(struct mm_struct *mm, unsigned long start,
236-
unsigned long end)
237-
{
238-
}
239-
240235
/*
241236
* We only want to enforce protection keys on the current process
242237
* because we effectively have no access to PKRU for other

include/asm-generic/mm_hooks.h

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
/*
3-
* Define generic no-op hooks for arch_dup_mmap, arch_exit_mmap
4-
* and arch_unmap to be included in asm-FOO/mmu_context.h for any
5-
* arch FOO which doesn't need to hook these.
3+
* Define generic no-op hooks for arch_dup_mmap and arch_exit_mmap
4+
* to be included in asm-FOO/mmu_context.h for any arch FOO which
5+
* doesn't need to hook these.
66
*/
77
#ifndef _ASM_GENERIC_MM_HOOKS_H
88
#define _ASM_GENERIC_MM_HOOKS_H
@@ -17,11 +17,6 @@ static inline void arch_exit_mmap(struct mm_struct *mm)
1717
{
1818
}
1919

20-
static inline void arch_unmap(struct mm_struct *mm,
21-
unsigned long start, unsigned long end)
22-
{
23-
}
24-
2520
static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
2621
bool write, bool execute, bool foreign)
2722
{

include/linux/mm_types.h

+3
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,9 @@ struct vm_special_mapping {
13131313

13141314
int (*mremap)(const struct vm_special_mapping *sm,
13151315
struct vm_area_struct *new_vma);
1316+
1317+
void (*close)(const struct vm_special_mapping *sm,
1318+
struct vm_area_struct *vma);
13161319
};
13171320

13181321
enum tlb_flush_reason {

mm/mmap.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -2789,7 +2789,7 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma,
27892789
*
27902790
* This function takes a @mas that is either pointing to the previous VMA or set
27912791
* to MA_START and sets it up to remove the mapping(s). The @len will be
2792-
* aligned and any arch_unmap work will be preformed.
2792+
* aligned.
27932793
*
27942794
* Return: 0 on success and drops the lock if so directed, error and leaves the
27952795
* lock held otherwise.
@@ -2809,16 +2809,12 @@ int do_vmi_munmap(struct vma_iterator *vmi, struct mm_struct *mm,
28092809
return -EINVAL;
28102810

28112811
/*
2812-
* Check if memory is sealed before arch_unmap.
2813-
* Prevent unmapping a sealed VMA.
2812+
* Check if memory is sealed, prevent unmapping a sealed VMA.
28142813
* can_modify_mm assumes we have acquired the lock on MM.
28152814
*/
28162815
if (unlikely(!can_modify_mm(mm, start, end)))
28172816
return -EPERM;
28182817

2819-
/* arch_unmap() might do unmaps itself. */
2820-
arch_unmap(mm, start, end);
2821-
28222818
/* Find the first overlapping VMA */
28232819
vma = vma_find(vmi, end);
28242820
if (!vma) {
@@ -3232,14 +3228,12 @@ int do_vma_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma,
32323228
struct mm_struct *mm = vma->vm_mm;
32333229

32343230
/*
3235-
* Check if memory is sealed before arch_unmap.
3236-
* Prevent unmapping a sealed VMA.
3231+
* Check if memory is sealed, prevent unmapping a sealed VMA.
32373232
* can_modify_mm assumes we have acquired the lock on MM.
32383233
*/
32393234
if (unlikely(!can_modify_mm(mm, start, end)))
32403235
return -EPERM;
32413236

3242-
arch_unmap(mm, start, end);
32433237
return do_vmi_align_munmap(vmi, vma, mm, start, end, uf, unlock);
32443238
}
32453239

@@ -3620,10 +3614,16 @@ void vm_stat_account(struct mm_struct *mm, vm_flags_t flags, long npages)
36203614
static vm_fault_t special_mapping_fault(struct vm_fault *vmf);
36213615

36223616
/*
3617+
* Close hook, called for unmap() and on the old vma for mremap().
3618+
*
36233619
* Having a close hook prevents vma merging regardless of flags.
36243620
*/
36253621
static void special_mapping_close(struct vm_area_struct *vma)
36263622
{
3623+
const struct vm_special_mapping *sm = vma->vm_private_data;
3624+
3625+
if (sm->close)
3626+
sm->close(sm, vma);
36273627
}
36283628

36293629
static const char *special_mapping_name(struct vm_area_struct *vma)

0 commit comments

Comments
 (0)