forked from mirrors/linux
		
	mm: simplify compat_sys_move_pages
The compat move_pages() implementation uses compat_alloc_user_space() for converting the pointer array. Moving the compat handling into the function itself is a bit simpler and lets us avoid the compat_alloc_user_space() call. Link: https://lkml.kernel.org/r/20210727144859.4150043-4-arnd@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Eric Biederman <ebiederm@xmission.com> Cc: Feng Tang <feng.tang@intel.com> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: Helge Deller <deller@gmx.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Paul Mackerras <paulus@samba.org> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									5d700a0fd7
								
							
						
					
					
						commit
						5b1b561ba7
					
				
					 1 changed files with 30 additions and 15 deletions
				
			
		
							
								
								
									
										45
									
								
								mm/migrate.c
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								mm/migrate.c
									
									
									
									
									
								
							| 
						 | 
					@ -1900,6 +1900,23 @@ static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages,
 | 
				
			||||||
	mmap_read_unlock(mm);
 | 
						mmap_read_unlock(mm);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int get_compat_pages_array(const void __user *chunk_pages[],
 | 
				
			||||||
 | 
									  const void __user * __user *pages,
 | 
				
			||||||
 | 
									  unsigned long chunk_nr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						compat_uptr_t __user *pages32 = (compat_uptr_t __user *)pages;
 | 
				
			||||||
 | 
						compat_uptr_t p;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < chunk_nr; i++) {
 | 
				
			||||||
 | 
							if (get_user(p, pages32 + i))
 | 
				
			||||||
 | 
								return -EFAULT;
 | 
				
			||||||
 | 
							chunk_pages[i] = compat_ptr(p);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Determine the nodes of a user array of pages and store it in
 | 
					 * Determine the nodes of a user array of pages and store it in
 | 
				
			||||||
 * a user array of status.
 | 
					 * a user array of status.
 | 
				
			||||||
| 
						 | 
					@ -1919,8 +1936,15 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
 | 
				
			||||||
		if (chunk_nr > DO_PAGES_STAT_CHUNK_NR)
 | 
							if (chunk_nr > DO_PAGES_STAT_CHUNK_NR)
 | 
				
			||||||
			chunk_nr = DO_PAGES_STAT_CHUNK_NR;
 | 
								chunk_nr = DO_PAGES_STAT_CHUNK_NR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (copy_from_user(chunk_pages, pages, chunk_nr * sizeof(*chunk_pages)))
 | 
							if (in_compat_syscall()) {
 | 
				
			||||||
			break;
 | 
								if (get_compat_pages_array(chunk_pages, pages,
 | 
				
			||||||
 | 
											   chunk_nr))
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if (copy_from_user(chunk_pages, pages,
 | 
				
			||||||
 | 
									      chunk_nr * sizeof(*chunk_pages)))
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status);
 | 
							do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2025,23 +2049,14 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_COMPAT
 | 
					#ifdef CONFIG_COMPAT
 | 
				
			||||||
COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages,
 | 
					COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages,
 | 
				
			||||||
		       compat_uptr_t __user *, pages32,
 | 
							       compat_uptr_t __user *, pages,
 | 
				
			||||||
		       const int __user *, nodes,
 | 
							       const int __user *, nodes,
 | 
				
			||||||
		       int __user *, status,
 | 
							       int __user *, status,
 | 
				
			||||||
		       int, flags)
 | 
							       int, flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const void __user * __user *pages;
 | 
						return kernel_move_pages(pid, nr_pages,
 | 
				
			||||||
	int i;
 | 
									 (const void __user *__user *)pages,
 | 
				
			||||||
 | 
									 nodes, status, flags);
 | 
				
			||||||
	pages = compat_alloc_user_space(nr_pages * sizeof(void *));
 | 
					 | 
				
			||||||
	for (i = 0; i < nr_pages; i++) {
 | 
					 | 
				
			||||||
		compat_uptr_t p;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (get_user(p, pages32 + i) ||
 | 
					 | 
				
			||||||
			put_user(compat_ptr(p), pages + i))
 | 
					 | 
				
			||||||
			return -EFAULT;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return kernel_move_pages(pid, nr_pages, pages, nodes, status, flags);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif /* CONFIG_COMPAT */
 | 
					#endif /* CONFIG_COMPAT */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue