Skip to content

Commit 1b6867d

Browse files
avaginctmarinas
authored andcommitted
arm64/vdso: Zap vvar pages when switching to a time namespace
The order of vvar pages depends on whether a task belongs to the root time namespace or not. In the root time namespace, a task doesn't have a per-namespace page. In a non-root namespace, the VVAR page which contains the system-wide VDSO data is replaced with a namespace specific page that contains clock offsets. Whenever a task changes its namespace, the VVAR page tables are cleared and then they will be re-faulted with a corresponding layout. A task can switch its time namespace only if its ->mm isn't shared with another task. Signed-off-by: Andrei Vagin <[email protected]> Reviewed-by: Vincenzo Frascino <[email protected]> Reviewed-by: Dmitry Safonov <[email protected]> Reviewed-by: Christian Brauner <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent d53b5c0 commit 1b6867d

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

arch/arm64/kernel/vdso.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,37 @@ static int __vdso_init(enum vdso_abi abi)
124124
return 0;
125125
}
126126

127+
#ifdef CONFIG_TIME_NS
128+
/*
129+
* The vvar mapping contains data for a specific time namespace, so when a task
130+
* changes namespace we must unmap its vvar data for the old namespace.
131+
* Subsequent faults will map in data for the new namespace.
132+
*
133+
* For more details see timens_setup_vdso_data().
134+
*/
135+
int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
136+
{
137+
struct mm_struct *mm = task->mm;
138+
struct vm_area_struct *vma;
139+
140+
mmap_read_lock(mm);
141+
142+
for (vma = mm->mmap; vma; vma = vma->vm_next) {
143+
unsigned long size = vma->vm_end - vma->vm_start;
144+
145+
if (vma_is_special_mapping(vma, vdso_info[VDSO_ABI_AA64].dm))
146+
zap_page_range(vma, vma->vm_start, size);
147+
#ifdef CONFIG_COMPAT_VDSO
148+
if (vma_is_special_mapping(vma, vdso_info[VDSO_ABI_AA32].dm))
149+
zap_page_range(vma, vma->vm_start, size);
150+
#endif
151+
}
152+
153+
mmap_read_unlock(mm);
154+
return 0;
155+
}
156+
#endif
157+
127158
static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
128159
struct vm_area_struct *vma, struct vm_fault *vmf)
129160
{

0 commit comments

Comments
 (0)