mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	vdso/timens: Refactor copy-pasted find_timens_vvar_page() helper into one copy
find_timens_vvar_page() is not architecture-specific, as can be seen from how all five per-architecture versions of it are the same. (arm64, powerpc and riscv are exactly the same; x86 and s390 have two characters difference inside a comment, less blank lines, and mark the !CONFIG_TIME_NS version as inline.) Refactor the five copies into a central copy in kernel/time/namespace.c. Signed-off-by: Jann Horn <jannh@google.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20221130115320.2918447-1-jannh@google.com
This commit is contained in:
		
							parent
							
								
									e0d3da982c
								
							
						
					
					
						commit
						d6c494e8ee
					
				
					 7 changed files with 24 additions and 109 deletions
				
			
		| 
						 | 
					@ -151,28 +151,6 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
 | 
				
			||||||
	mmap_read_unlock(mm);
 | 
						mmap_read_unlock(mm);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (likely(vma->vm_mm == current->mm))
 | 
					 | 
				
			||||||
		return current->nsproxy->time_ns->vvar_page;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * VM_PFNMAP | VM_IO protect .fault() handler from being called
 | 
					 | 
				
			||||||
	 * through interfaces like /proc/$pid/mem or
 | 
					 | 
				
			||||||
	 * process_vm_{readv,writev}() as long as there's no .access()
 | 
					 | 
				
			||||||
	 * in special_mapping_vmops.
 | 
					 | 
				
			||||||
	 * For more details check_vma_flags() and __access_remote_vm()
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	WARN(1, "vvar_page accessed remotely");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
static struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 | 
					static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,28 +129,6 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (likely(vma->vm_mm == current->mm))
 | 
					 | 
				
			||||||
		return current->nsproxy->time_ns->vvar_page;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * VM_PFNMAP | VM_IO protect .fault() handler from being called
 | 
					 | 
				
			||||||
	 * through interfaces like /proc/$pid/mem or
 | 
					 | 
				
			||||||
	 * process_vm_{readv,writev}() as long as there's no .access()
 | 
					 | 
				
			||||||
	 * in special_mapping_vmops.
 | 
					 | 
				
			||||||
	 * For more details check_vma_flags() and __access_remote_vm()
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	WARN(1, "vvar_page accessed remotely");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
static struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 | 
					static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,28 +137,6 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
 | 
				
			||||||
	mmap_read_unlock(mm);
 | 
						mmap_read_unlock(mm);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (likely(vma->vm_mm == current->mm))
 | 
					 | 
				
			||||||
		return current->nsproxy->time_ns->vvar_page;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * VM_PFNMAP | VM_IO protect .fault() handler from being called
 | 
					 | 
				
			||||||
	 * through interfaces like /proc/$pid/mem or
 | 
					 | 
				
			||||||
	 * process_vm_{readv,writev}() as long as there's no .access()
 | 
					 | 
				
			||||||
	 * in special_mapping_vmops.
 | 
					 | 
				
			||||||
	 * For more details check_vma_flags() and __access_remote_vm()
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	WARN(1, "vvar_page accessed remotely");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
static struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 | 
					static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,21 +44,6 @@ struct vdso_data *arch_get_vdso_data(void *vvar_page)
 | 
				
			||||||
	return (struct vdso_data *)(vvar_page);
 | 
						return (struct vdso_data *)(vvar_page);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (likely(vma->vm_mm == current->mm))
 | 
					 | 
				
			||||||
		return current->nsproxy->time_ns->vvar_page;
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * VM_PFNMAP | VM_IO protect .fault() handler from being called
 | 
					 | 
				
			||||||
	 * through interfaces like /proc/$pid/mem or
 | 
					 | 
				
			||||||
	 * process_vm_{readv,writev}() as long as there's no .access()
 | 
					 | 
				
			||||||
	 * in special_mapping_vmops().
 | 
					 | 
				
			||||||
	 * For more details check_vma_flags() and __access_remote_vm()
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	WARN(1, "vvar_page accessed remotely");
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * The VVAR page layout depends on whether a task belongs to the root or
 | 
					 * The VVAR page layout depends on whether a task belongs to the root or
 | 
				
			||||||
 * non-root time namespace. Whenever a task changes its namespace, the VVAR
 | 
					 * non-root time namespace. Whenever a task changes its namespace, the VVAR
 | 
				
			||||||
| 
						 | 
					@ -84,11 +69,6 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
 | 
				
			||||||
	mmap_read_unlock(mm);
 | 
						mmap_read_unlock(mm);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
static inline struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 | 
					static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,24 +98,6 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_TIME_NS
 | 
					#ifdef CONFIG_TIME_NS
 | 
				
			||||||
static struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (likely(vma->vm_mm == current->mm))
 | 
					 | 
				
			||||||
		return current->nsproxy->time_ns->vvar_page;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * VM_PFNMAP | VM_IO protect .fault() handler from being called
 | 
					 | 
				
			||||||
	 * through interfaces like /proc/$pid/mem or
 | 
					 | 
				
			||||||
	 * process_vm_{readv,writev}() as long as there's no .access()
 | 
					 | 
				
			||||||
	 * in special_mapping_vmops().
 | 
					 | 
				
			||||||
	 * For more details check_vma_flags() and __access_remote_vm()
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	WARN(1, "vvar_page accessed remotely");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * The vvar page layout depends on whether a task belongs to the root or
 | 
					 * The vvar page layout depends on whether a task belongs to the root or
 | 
				
			||||||
 * non-root time namespace. Whenever a task changes its namespace, the VVAR
 | 
					 * non-root time namespace. Whenever a task changes its namespace, the VVAR
 | 
				
			||||||
| 
						 | 
					@ -140,11 +122,6 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
static inline struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 | 
					static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,7 @@ struct time_namespace *copy_time_ns(unsigned long flags,
 | 
				
			||||||
void free_time_ns(struct time_namespace *ns);
 | 
					void free_time_ns(struct time_namespace *ns);
 | 
				
			||||||
void timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk);
 | 
					void timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk);
 | 
				
			||||||
struct vdso_data *arch_get_vdso_data(void *vvar_page);
 | 
					struct vdso_data *arch_get_vdso_data(void *vvar_page);
 | 
				
			||||||
 | 
					struct page *find_timens_vvar_page(struct vm_area_struct *vma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void put_time_ns(struct time_namespace *ns)
 | 
					static inline void put_time_ns(struct time_namespace *ns)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -141,6 +142,11 @@ static inline void timens_on_fork(struct nsproxy *nsproxy,
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void timens_add_monotonic(struct timespec64 *ts) { }
 | 
					static inline void timens_add_monotonic(struct timespec64 *ts) { }
 | 
				
			||||||
static inline void timens_add_boottime(struct timespec64 *ts) { }
 | 
					static inline void timens_add_boottime(struct timespec64 *ts) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -192,6 +192,24 @@ static void timens_setup_vdso_data(struct vdso_data *vdata,
 | 
				
			||||||
	offset[CLOCK_BOOTTIME_ALARM]	= boottime;
 | 
						offset[CLOCK_BOOTTIME_ALARM]	= boottime;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct page *find_timens_vvar_page(struct vm_area_struct *vma)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (likely(vma->vm_mm == current->mm))
 | 
				
			||||||
 | 
							return current->nsproxy->time_ns->vvar_page;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * VM_PFNMAP | VM_IO protect .fault() handler from being called
 | 
				
			||||||
 | 
						 * through interfaces like /proc/$pid/mem or
 | 
				
			||||||
 | 
						 * process_vm_{readv,writev}() as long as there's no .access()
 | 
				
			||||||
 | 
						 * in special_mapping_vmops().
 | 
				
			||||||
 | 
						 * For more details check_vma_flags() and __access_remote_vm()
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WARN(1, "vvar_page accessed remotely");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Protects possibly multiple offsets writers racing each other
 | 
					 * Protects possibly multiple offsets writers racing each other
 | 
				
			||||||
 * and tasks entering the namespace.
 | 
					 * and tasks entering the namespace.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue