Skip to content

Commit 63ae602

Browse files
committed
Merge branch 'gup_flag-cleanups'
Merge the gup_flags cleanups from Lorenzo Stoakes: "This patch series adjusts functions in the get_user_pages* family such that desired FOLL_* flags are passed as an argument rather than implied by flags. The purpose of this change is to make the use of FOLL_FORCE explicit so it is easier to grep for and clearer to callers that this flag is being used. The use of FOLL_FORCE is an issue as it overrides missing VM_READ/VM_WRITE flags for the VMA whose pages we are reading from/writing to, which can result in surprising behaviour. The patch series came out of the discussion around commit 38e0885 ("mm: check VMA flags to avoid invalid PROT_NONE NUMA balancing"), which addressed a BUG_ON() being triggered when a page was faulted in with PROT_NONE set but having been overridden by FOLL_FORCE. do_numa_page() was run on the assumption the page _must_ be one marked for NUMA node migration as an actual PROT_NONE page would have been dealt with prior to this code path, however FOLL_FORCE introduced a situation where this assumption did not hold. See https://marc.info/?l=linux-mm&m=147585445805166 for the patch proposal" Additionally, there's a fix for an ancient bug related to FOLL_FORCE and FOLL_WRITE by me. [ This branch was rebased recently to add a few more acked-by's and reviewed-by's ] * gup_flag-cleanups: mm: replace access_process_vm() write parameter with gup_flags mm: replace access_remote_vm() write parameter with gup_flags mm: replace __access_remote_vm() write parameter with gup_flags mm: replace get_user_pages_remote() write/force parameters with gup_flags mm: replace get_user_pages() write/force parameters with gup_flags mm: replace get_vaddr_frames() write/force parameters with gup_flags mm: replace get_user_pages_locked() write/force parameters with gup_flags mm: replace get_user_pages_unlocked() write/force parameters with gup_flags mm: remove write/force parameters from __get_user_pages_unlocked() mm: remove write/force parameters from __get_user_pages_locked() mm: remove gup_flags FOLL_WRITE games from __get_user_pages()
2 parents 1a1891d + f307ab6 commit 63ae602

File tree

61 files changed

+273
-189
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+273
-189
lines changed

arch/alpha/kernel/ptrace.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,16 @@ put_reg(struct task_struct *task, unsigned long regno, unsigned long data)
157157
static inline int
158158
read_int(struct task_struct *task, unsigned long addr, int * data)
159159
{
160-
int copied = access_process_vm(task, addr, data, sizeof(int), 0);
160+
int copied = access_process_vm(task, addr, data, sizeof(int),
161+
FOLL_FORCE);
161162
return (copied == sizeof(int)) ? 0 : -EIO;
162163
}
163164

164165
static inline int
165166
write_int(struct task_struct *task, unsigned long addr, int data)
166167
{
167-
int copied = access_process_vm(task, addr, &data, sizeof(int), 1);
168+
int copied = access_process_vm(task, addr, &data, sizeof(int),
169+
FOLL_FORCE | FOLL_WRITE);
168170
return (copied == sizeof(int)) ? 0 : -EIO;
169171
}
170172

@@ -281,7 +283,8 @@ long arch_ptrace(struct task_struct *child, long request,
281283
/* When I and D space are separate, these will need to be fixed. */
282284
case PTRACE_PEEKTEXT: /* read word at location addr. */
283285
case PTRACE_PEEKDATA:
284-
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
286+
copied = access_process_vm(child, addr, &tmp, sizeof(tmp),
287+
FOLL_FORCE);
285288
ret = -EIO;
286289
if (copied != sizeof(tmp))
287290
break;

arch/blackfin/kernel/ptrace.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ long arch_ptrace(struct task_struct *child, long request,
271271
case BFIN_MEM_ACCESS_CORE:
272272
case BFIN_MEM_ACCESS_CORE_ONLY:
273273
copied = access_process_vm(child, addr, &tmp,
274-
to_copy, 0);
274+
to_copy, FOLL_FORCE);
275275
if (copied)
276276
break;
277277

@@ -324,7 +324,8 @@ long arch_ptrace(struct task_struct *child, long request,
324324
case BFIN_MEM_ACCESS_CORE:
325325
case BFIN_MEM_ACCESS_CORE_ONLY:
326326
copied = access_process_vm(child, addr, &data,
327-
to_copy, 1);
327+
to_copy,
328+
FOLL_FORCE | FOLL_WRITE);
328329
break;
329330
case BFIN_MEM_ACCESS_DMA:
330331
if (safe_dma_memcpy(paddr, &data, to_copy))

arch/cris/arch-v32/drivers/cryptocop.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2722,7 +2722,6 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig
27222722
err = get_user_pages((unsigned long int)(oper.indata + prev_ix),
27232723
noinpages,
27242724
0, /* read access only for in data */
2725-
0, /* no force */
27262725
inpages,
27272726
NULL);
27282727

@@ -2736,8 +2735,7 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig
27362735
if (oper.do_cipher){
27372736
err = get_user_pages((unsigned long int)oper.cipher_outdata,
27382737
nooutpages,
2739-
1, /* write access for out data */
2740-
0, /* no force */
2738+
FOLL_WRITE, /* write access for out data */
27412739
outpages,
27422740
NULL);
27432741
up_read(&current->mm->mmap_sem);

arch/cris/arch-v32/kernel/ptrace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ long arch_ptrace(struct task_struct *child, long request,
147147
/* The trampoline page is globally mapped, no page table to traverse.*/
148148
tmp = *(unsigned long*)addr;
149149
} else {
150-
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
150+
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), FOLL_FORCE);
151151

152152
if (copied != sizeof(tmp))
153153
break;
@@ -279,7 +279,7 @@ static int insn_size(struct task_struct *child, unsigned long pc)
279279
int opsize = 0;
280280

281281
/* Read the opcode at pc (do what PTRACE_PEEKTEXT would do). */
282-
copied = access_process_vm(child, pc, &opcode, sizeof(opcode), 0);
282+
copied = access_process_vm(child, pc, &opcode, sizeof(opcode), FOLL_FORCE);
283283
if (copied != sizeof(opcode))
284284
return 0;
285285

arch/ia64/kernel/err_inject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ store_virtual_to_phys(struct device *dev, struct device_attribute *attr,
142142
u64 virt_addr=simple_strtoull(buf, NULL, 16);
143143
int ret;
144144

145-
ret = get_user_pages(virt_addr, 1, VM_READ, 0, NULL, NULL);
145+
ret = get_user_pages(virt_addr, 1, FOLL_WRITE, NULL, NULL);
146146
if (ret<=0) {
147147
#ifdef ERR_INJ_DEBUG
148148
printk("Virtual address %lx is not existing.\n",virt_addr);

arch/ia64/kernel/ptrace.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ ia64_peek (struct task_struct *child, struct switch_stack *child_stack,
453453
return 0;
454454
}
455455
}
456-
copied = access_process_vm(child, addr, &ret, sizeof(ret), 0);
456+
copied = access_process_vm(child, addr, &ret, sizeof(ret), FOLL_FORCE);
457457
if (copied != sizeof(ret))
458458
return -EIO;
459459
*val = ret;
@@ -489,7 +489,8 @@ ia64_poke (struct task_struct *child, struct switch_stack *child_stack,
489489
*ia64_rse_skip_regs(krbs, regnum) = val;
490490
}
491491
}
492-
} else if (access_process_vm(child, addr, &val, sizeof(val), 1)
492+
} else if (access_process_vm(child, addr, &val, sizeof(val),
493+
FOLL_FORCE | FOLL_WRITE)
493494
!= sizeof(val))
494495
return -EIO;
495496
return 0;
@@ -543,7 +544,8 @@ ia64_sync_user_rbs (struct task_struct *child, struct switch_stack *sw,
543544
ret = ia64_peek(child, sw, user_rbs_end, addr, &val);
544545
if (ret < 0)
545546
return ret;
546-
if (access_process_vm(child, addr, &val, sizeof(val), 1)
547+
if (access_process_vm(child, addr, &val, sizeof(val),
548+
FOLL_FORCE | FOLL_WRITE)
547549
!= sizeof(val))
548550
return -EIO;
549551
}
@@ -559,7 +561,8 @@ ia64_sync_kernel_rbs (struct task_struct *child, struct switch_stack *sw,
559561

560562
/* now copy word for word from user rbs to kernel rbs: */
561563
for (addr = user_rbs_start; addr < user_rbs_end; addr += 8) {
562-
if (access_process_vm(child, addr, &val, sizeof(val), 0)
564+
if (access_process_vm(child, addr, &val, sizeof(val),
565+
FOLL_FORCE)
563566
!= sizeof(val))
564567
return -EIO;
565568

@@ -1156,7 +1159,8 @@ arch_ptrace (struct task_struct *child, long request,
11561159
case PTRACE_PEEKTEXT:
11571160
case PTRACE_PEEKDATA:
11581161
/* read word at location addr */
1159-
if (access_process_vm(child, addr, &data, sizeof(data), 0)
1162+
if (access_process_vm(child, addr, &data, sizeof(data),
1163+
FOLL_FORCE)
11601164
!= sizeof(data))
11611165
return -EIO;
11621166
/* ensure return value is not mistaken for error code */

arch/m32r/kernel/ptrace.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,8 @@ unregister_all_debug_traps(struct task_struct *child)
493493
int i;
494494

495495
for (i = 0; i < p->nr_trap; i++)
496-
access_process_vm(child, p->addr[i], &p->insn[i], sizeof(p->insn[i]), 1);
496+
access_process_vm(child, p->addr[i], &p->insn[i], sizeof(p->insn[i]),
497+
FOLL_FORCE | FOLL_WRITE);
497498
p->nr_trap = 0;
498499
}
499500

@@ -537,7 +538,8 @@ embed_debug_trap(struct task_struct *child, unsigned long next_pc)
537538
unsigned long next_insn, code;
538539
unsigned long addr = next_pc & ~3;
539540

540-
if (access_process_vm(child, addr, &next_insn, sizeof(next_insn), 0)
541+
if (access_process_vm(child, addr, &next_insn, sizeof(next_insn),
542+
FOLL_FORCE)
541543
!= sizeof(next_insn)) {
542544
return -1; /* error */
543545
}
@@ -546,7 +548,8 @@ embed_debug_trap(struct task_struct *child, unsigned long next_pc)
546548
if (register_debug_trap(child, next_pc, next_insn, &code)) {
547549
return -1; /* error */
548550
}
549-
if (access_process_vm(child, addr, &code, sizeof(code), 1)
551+
if (access_process_vm(child, addr, &code, sizeof(code),
552+
FOLL_FORCE | FOLL_WRITE)
550553
!= sizeof(code)) {
551554
return -1; /* error */
552555
}
@@ -562,7 +565,8 @@ withdraw_debug_trap(struct pt_regs *regs)
562565
addr = (regs->bpc - 2) & ~3;
563566
regs->bpc -= 2;
564567
if (unregister_debug_trap(current, addr, &code)) {
565-
access_process_vm(current, addr, &code, sizeof(code), 1);
568+
access_process_vm(current, addr, &code, sizeof(code),
569+
FOLL_FORCE | FOLL_WRITE);
566570
invalidate_cache();
567571
}
568572
}
@@ -589,7 +593,8 @@ void user_enable_single_step(struct task_struct *child)
589593
/* Compute next pc. */
590594
pc = get_stack_long(child, PT_BPC);
591595

592-
if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
596+
if (access_process_vm(child, pc&~3, &insn, sizeof(insn),
597+
FOLL_FORCE)
593598
!= sizeof(insn))
594599
return;
595600

arch/mips/kernel/ptrace32.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
7070
break;
7171

7272
copied = access_process_vm(child, (u64)addrOthers, &tmp,
73-
sizeof(tmp), 0);
73+
sizeof(tmp), FOLL_FORCE);
7474
if (copied != sizeof(tmp))
7575
break;
7676
ret = put_user(tmp, (u32 __user *) (unsigned long) data);
@@ -179,7 +179,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
179179
break;
180180
ret = 0;
181181
if (access_process_vm(child, (u64)addrOthers, &data,
182-
sizeof(data), 1) == sizeof(data))
182+
sizeof(data),
183+
FOLL_FORCE | FOLL_WRITE) == sizeof(data))
183184
break;
184185
ret = -EIO;
185186
break;

arch/mips/mm/gup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
287287
pages += nr;
288288

289289
ret = get_user_pages_unlocked(start, (end - start) >> PAGE_SHIFT,
290-
write, 0, pages);
290+
pages, write ? FOLL_WRITE : 0);
291291

292292
/* Have to be a bit careful with return values */
293293
if (nr > 0) {

arch/powerpc/kernel/ptrace32.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
7474
break;
7575

7676
copied = access_process_vm(child, (u64)addrOthers, &tmp,
77-
sizeof(tmp), 0);
77+
sizeof(tmp), FOLL_FORCE);
7878
if (copied != sizeof(tmp))
7979
break;
8080
ret = put_user(tmp, (u32 __user *)data);
@@ -179,7 +179,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
179179
break;
180180
ret = 0;
181181
if (access_process_vm(child, (u64)addrOthers, &tmp,
182-
sizeof(tmp), 1) == sizeof(tmp))
182+
sizeof(tmp),
183+
FOLL_FORCE | FOLL_WRITE) == sizeof(tmp))
183184
break;
184185
ret = -EIO;
185186
break;

0 commit comments

Comments
 (0)