diff options
Diffstat (limited to 'mm/mmap.c')
-rw-r--r-- | mm/mmap.c | 16 |
1 files changed, 9 insertions, 7 deletions
@@ -116,13 +116,15 @@ static pgprot_t vm_pgprot_modify(pgprot_t oldprot, unsigned long vm_flags) | |||
116 | void vma_set_page_prot(struct vm_area_struct *vma) | 116 | void vma_set_page_prot(struct vm_area_struct *vma) |
117 | { | 117 | { |
118 | unsigned long vm_flags = vma->vm_flags; | 118 | unsigned long vm_flags = vma->vm_flags; |
119 | pgprot_t vm_page_prot; | ||
119 | 120 | ||
120 | vma->vm_page_prot = vm_pgprot_modify(vma->vm_page_prot, vm_flags); | 121 | vm_page_prot = vm_pgprot_modify(vma->vm_page_prot, vm_flags); |
121 | if (vma_wants_writenotify(vma)) { | 122 | if (vma_wants_writenotify(vma, vm_page_prot)) { |
122 | vm_flags &= ~VM_SHARED; | 123 | vm_flags &= ~VM_SHARED; |
123 | vma->vm_page_prot = vm_pgprot_modify(vma->vm_page_prot, | 124 | vm_page_prot = vm_pgprot_modify(vm_page_prot, vm_flags); |
124 | vm_flags); | ||
125 | } | 125 | } |
126 | /* remove_protection_ptes reads vma->vm_page_prot without mmap_sem */ | ||
127 | WRITE_ONCE(vma->vm_page_prot, vm_page_prot); | ||
126 | } | 128 | } |
127 | 129 | ||
128 | /* | 130 | /* |
@@ -1386,7 +1388,7 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg) | |||
1386 | * to the private version (using protection_map[] without the | 1388 | * to the private version (using protection_map[] without the |
1387 | * VM_SHARED bit). | 1389 | * VM_SHARED bit). |
1388 | */ | 1390 | */ |
1389 | int vma_wants_writenotify(struct vm_area_struct *vma) | 1391 | int vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot) |
1390 | { | 1392 | { |
1391 | vm_flags_t vm_flags = vma->vm_flags; | 1393 | vm_flags_t vm_flags = vma->vm_flags; |
1392 | const struct vm_operations_struct *vm_ops = vma->vm_ops; | 1394 | const struct vm_operations_struct *vm_ops = vma->vm_ops; |
@@ -1401,8 +1403,8 @@ int vma_wants_writenotify(struct vm_area_struct *vma) | |||
1401 | 1403 | ||
1402 | /* The open routine did something to the protections that pgprot_modify | 1404 | /* The open routine did something to the protections that pgprot_modify |
1403 | * won't preserve? */ | 1405 | * won't preserve? */ |
1404 | if (pgprot_val(vma->vm_page_prot) != | 1406 | if (pgprot_val(vm_page_prot) != |
1405 | pgprot_val(vm_pgprot_modify(vma->vm_page_prot, vm_flags))) | 1407 | pgprot_val(vm_pgprot_modify(vm_page_prot, vm_flags))) |
1406 | return 0; | 1408 | return 0; |
1407 | 1409 | ||
1408 | /* Do we need to track softdirty? */ | 1410 | /* Do we need to track softdirty? */ |