1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
7 #include <linux/module.h>
8 #include <linux/sched/signal.h>
10 #include <asm/pgtable.h>
11 #include <asm/tlbflush.h>
12 #include <as-layout.h>
16 #include <kern_util.h>
18 struct host_vm_change
{
20 enum { NONE
, MMAP
, MUNMAP
, MPROTECT
} type
;
47 #define INIT_HVC(mm, force, userspace) \
48 ((struct host_vm_change) \
49 { .ops = { { .type = NONE } }, \
52 .userspace = userspace, \
56 static void report_enomem(void)
58 printk(KERN_ERR
"UML ran out of memory on the host side! "
59 "This can happen due to a memory limitation or "
60 "vm.max_map_count has been reached.\n");
63 static int do_ops(struct host_vm_change
*hvc
, int end
,
66 struct host_vm_op
*op
;
69 for (i
= 0; i
< end
&& !ret
; i
++) {
74 ret
= map(&hvc
->mm
->context
.id
, op
->u
.mmap
.addr
,
75 op
->u
.mmap
.len
, op
->u
.mmap
.prot
,
77 op
->u
.mmap
.offset
, finished
,
80 map_memory(op
->u
.mmap
.addr
, op
->u
.mmap
.offset
,
81 op
->u
.mmap
.len
, 1, 1, 1);
85 ret
= unmap(&hvc
->mm
->context
.id
,
87 op
->u
.munmap
.len
, finished
,
90 ret
= os_unmap_memory(
91 (void *) op
->u
.munmap
.addr
,
97 ret
= protect(&hvc
->mm
->context
.id
,
101 finished
, &hvc
->data
);
103 ret
= os_protect_memory(
104 (void *) op
->u
.mprotect
.addr
,
109 printk(KERN_ERR
"Unknown op type %d in do_ops\n",
122 static int add_mmap(unsigned long virt
, unsigned long phys
, unsigned long len
,
123 unsigned int prot
, struct host_vm_change
*hvc
)
126 struct host_vm_op
*last
;
127 int fd
= -1, ret
= 0;
130 fd
= phys_mapping(phys
, &offset
);
133 if (hvc
->index
!= 0) {
134 last
= &hvc
->ops
[hvc
->index
- 1];
135 if ((last
->type
== MMAP
) &&
136 (last
->u
.mmap
.addr
+ last
->u
.mmap
.len
== virt
) &&
137 (last
->u
.mmap
.prot
== prot
) && (last
->u
.mmap
.fd
== fd
) &&
138 (last
->u
.mmap
.offset
+ last
->u
.mmap
.len
== offset
)) {
139 last
->u
.mmap
.len
+= len
;
144 if (hvc
->index
== ARRAY_SIZE(hvc
->ops
)) {
145 ret
= do_ops(hvc
, ARRAY_SIZE(hvc
->ops
), 0);
149 hvc
->ops
[hvc
->index
++] = ((struct host_vm_op
)
151 .u
= { .mmap
= { .addr
= virt
,
160 static int add_munmap(unsigned long addr
, unsigned long len
,
161 struct host_vm_change
*hvc
)
163 struct host_vm_op
*last
;
166 if ((addr
>= STUB_START
) && (addr
< STUB_END
))
169 if (hvc
->index
!= 0) {
170 last
= &hvc
->ops
[hvc
->index
- 1];
171 if ((last
->type
== MUNMAP
) &&
172 (last
->u
.munmap
.addr
+ last
->u
.mmap
.len
== addr
)) {
173 last
->u
.munmap
.len
+= len
;
178 if (hvc
->index
== ARRAY_SIZE(hvc
->ops
)) {
179 ret
= do_ops(hvc
, ARRAY_SIZE(hvc
->ops
), 0);
183 hvc
->ops
[hvc
->index
++] = ((struct host_vm_op
)
185 .u
= { .munmap
= { .addr
= addr
,
190 static int add_mprotect(unsigned long addr
, unsigned long len
,
191 unsigned int prot
, struct host_vm_change
*hvc
)
193 struct host_vm_op
*last
;
196 if (hvc
->index
!= 0) {
197 last
= &hvc
->ops
[hvc
->index
- 1];
198 if ((last
->type
== MPROTECT
) &&
199 (last
->u
.mprotect
.addr
+ last
->u
.mprotect
.len
== addr
) &&
200 (last
->u
.mprotect
.prot
== prot
)) {
201 last
->u
.mprotect
.len
+= len
;
206 if (hvc
->index
== ARRAY_SIZE(hvc
->ops
)) {
207 ret
= do_ops(hvc
, ARRAY_SIZE(hvc
->ops
), 0);
211 hvc
->ops
[hvc
->index
++] = ((struct host_vm_op
)
213 .u
= { .mprotect
= { .addr
= addr
,
219 #define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
221 static inline int update_pte_range(pmd_t
*pmd
, unsigned long addr
,
223 struct host_vm_change
*hvc
)
226 int r
, w
, x
, prot
, ret
= 0;
228 pte
= pte_offset_kernel(pmd
, addr
);
230 if ((addr
>= STUB_START
) && (addr
< STUB_END
))
236 if (!pte_young(*pte
)) {
239 } else if (!pte_dirty(*pte
))
242 prot
= ((r
? UM_PROT_READ
: 0) | (w
? UM_PROT_WRITE
: 0) |
243 (x
? UM_PROT_EXEC
: 0));
244 if (hvc
->force
|| pte_newpage(*pte
)) {
245 if (pte_present(*pte
)) {
246 if (pte_newpage(*pte
))
247 ret
= add_mmap(addr
, pte_val(*pte
) & PAGE_MASK
,
248 PAGE_SIZE
, prot
, hvc
);
250 ret
= add_munmap(addr
, PAGE_SIZE
, hvc
);
251 } else if (pte_newprot(*pte
))
252 ret
= add_mprotect(addr
, PAGE_SIZE
, prot
, hvc
);
253 *pte
= pte_mkuptodate(*pte
);
254 } while (pte
++, addr
+= PAGE_SIZE
, ((addr
< end
) && !ret
));
258 static inline int update_pmd_range(pud_t
*pud
, unsigned long addr
,
260 struct host_vm_change
*hvc
)
266 pmd
= pmd_offset(pud
, addr
);
268 next
= pmd_addr_end(addr
, end
);
269 if (!pmd_present(*pmd
)) {
270 if (hvc
->force
|| pmd_newpage(*pmd
)) {
271 ret
= add_munmap(addr
, next
- addr
, hvc
);
272 pmd_mkuptodate(*pmd
);
275 else ret
= update_pte_range(pmd
, addr
, next
, hvc
);
276 } while (pmd
++, addr
= next
, ((addr
< end
) && !ret
));
280 static inline int update_pud_range(p4d_t
*p4d
, unsigned long addr
,
282 struct host_vm_change
*hvc
)
288 pud
= pud_offset(p4d
, addr
);
290 next
= pud_addr_end(addr
, end
);
291 if (!pud_present(*pud
)) {
292 if (hvc
->force
|| pud_newpage(*pud
)) {
293 ret
= add_munmap(addr
, next
- addr
, hvc
);
294 pud_mkuptodate(*pud
);
297 else ret
= update_pmd_range(pud
, addr
, next
, hvc
);
298 } while (pud
++, addr
= next
, ((addr
< end
) && !ret
));
302 static inline int update_p4d_range(pgd_t
*pgd
, unsigned long addr
,
304 struct host_vm_change
*hvc
)
310 p4d
= p4d_offset(pgd
, addr
);
312 next
= p4d_addr_end(addr
, end
);
313 if (!p4d_present(*p4d
)) {
314 if (hvc
->force
|| p4d_newpage(*p4d
)) {
315 ret
= add_munmap(addr
, next
- addr
, hvc
);
316 p4d_mkuptodate(*p4d
);
319 ret
= update_pud_range(p4d
, addr
, next
, hvc
);
320 } while (p4d
++, addr
= next
, ((addr
< end
) && !ret
));
324 void fix_range_common(struct mm_struct
*mm
, unsigned long start_addr
,
325 unsigned long end_addr
, int force
)
328 struct host_vm_change hvc
;
329 unsigned long addr
= start_addr
, next
;
330 int ret
= 0, userspace
= 1;
332 hvc
= INIT_HVC(mm
, force
, userspace
);
333 pgd
= pgd_offset(mm
, addr
);
335 next
= pgd_addr_end(addr
, end_addr
);
336 if (!pgd_present(*pgd
)) {
337 if (force
|| pgd_newpage(*pgd
)) {
338 ret
= add_munmap(addr
, next
- addr
, &hvc
);
339 pgd_mkuptodate(*pgd
);
342 ret
= update_p4d_range(pgd
, addr
, next
, &hvc
);
343 } while (pgd
++, addr
= next
, ((addr
< end_addr
) && !ret
));
346 ret
= do_ops(&hvc
, hvc
.index
, 1);
348 /* This is not an else because ret is modified above */
350 printk(KERN_ERR
"fix_range_common: failed, killing current "
351 "process: %d\n", task_tgid_vnr(current
));
352 /* We are under mmap_sem, release it such that current can terminate */
353 up_write(¤t
->mm
->mmap_sem
);
355 do_signal(¤t
->thread
.regs
);
359 static int flush_tlb_kernel_range_common(unsigned long start
, unsigned long end
)
361 struct mm_struct
*mm
;
367 unsigned long addr
, last
;
368 int updated
= 0, err
= 0, force
= 0, userspace
= 0;
369 struct host_vm_change hvc
;
372 hvc
= INIT_HVC(mm
, force
, userspace
);
373 for (addr
= start
; addr
< end
;) {
374 pgd
= pgd_offset(mm
, addr
);
375 if (!pgd_present(*pgd
)) {
376 last
= ADD_ROUND(addr
, PGDIR_SIZE
);
379 if (pgd_newpage(*pgd
)) {
381 err
= add_munmap(addr
, last
- addr
, &hvc
);
383 panic("munmap failed, errno = %d\n",
390 p4d
= p4d_offset(pgd
, addr
);
391 if (!p4d_present(*p4d
)) {
392 last
= ADD_ROUND(addr
, P4D_SIZE
);
395 if (p4d_newpage(*p4d
)) {
397 err
= add_munmap(addr
, last
- addr
, &hvc
);
399 panic("munmap failed, errno = %d\n",
406 pud
= pud_offset(p4d
, addr
);
407 if (!pud_present(*pud
)) {
408 last
= ADD_ROUND(addr
, PUD_SIZE
);
411 if (pud_newpage(*pud
)) {
413 err
= add_munmap(addr
, last
- addr
, &hvc
);
415 panic("munmap failed, errno = %d\n",
422 pmd
= pmd_offset(pud
, addr
);
423 if (!pmd_present(*pmd
)) {
424 last
= ADD_ROUND(addr
, PMD_SIZE
);
427 if (pmd_newpage(*pmd
)) {
429 err
= add_munmap(addr
, last
- addr
, &hvc
);
431 panic("munmap failed, errno = %d\n",
438 pte
= pte_offset_kernel(pmd
, addr
);
439 if (!pte_present(*pte
) || pte_newpage(*pte
)) {
441 err
= add_munmap(addr
, PAGE_SIZE
, &hvc
);
443 panic("munmap failed, errno = %d\n",
445 if (pte_present(*pte
))
446 err
= add_mmap(addr
, pte_val(*pte
) & PAGE_MASK
,
449 else if (pte_newprot(*pte
)) {
451 err
= add_mprotect(addr
, PAGE_SIZE
, 0, &hvc
);
456 err
= do_ops(&hvc
, hvc
.index
, 1);
459 panic("flush_tlb_kernel failed, errno = %d\n", err
);
463 void flush_tlb_page(struct vm_area_struct
*vma
, unsigned long address
)
470 struct mm_struct
*mm
= vma
->vm_mm
;
472 int r
, w
, x
, prot
, err
= 0;
475 address
&= PAGE_MASK
;
476 pgd
= pgd_offset(mm
, address
);
477 if (!pgd_present(*pgd
))
480 p4d
= p4d_offset(pgd
, address
);
481 if (!p4d_present(*p4d
))
484 pud
= pud_offset(p4d
, address
);
485 if (!pud_present(*pud
))
488 pmd
= pmd_offset(pud
, address
);
489 if (!pmd_present(*pmd
))
492 pte
= pte_offset_kernel(pmd
, address
);
497 if (!pte_young(*pte
)) {
500 } else if (!pte_dirty(*pte
)) {
504 mm_id
= &mm
->context
.id
;
505 prot
= ((r
? UM_PROT_READ
: 0) | (w
? UM_PROT_WRITE
: 0) |
506 (x
? UM_PROT_EXEC
: 0));
507 if (pte_newpage(*pte
)) {
508 if (pte_present(*pte
)) {
509 unsigned long long offset
;
512 fd
= phys_mapping(pte_val(*pte
) & PAGE_MASK
, &offset
);
513 err
= map(mm_id
, address
, PAGE_SIZE
, prot
, fd
, offset
,
516 else err
= unmap(mm_id
, address
, PAGE_SIZE
, 1, &flush
);
518 else if (pte_newprot(*pte
))
519 err
= protect(mm_id
, address
, PAGE_SIZE
, prot
, 1, &flush
);
528 *pte
= pte_mkuptodate(*pte
);
533 printk(KERN_ERR
"Failed to flush page for address 0x%lx\n", address
);
537 void flush_tlb_all(void)
540 * Don't bother flushing if this address space is about to be
543 if (atomic_read(¤t
->mm
->mm_users
) == 0)
546 flush_tlb_mm(current
->mm
);
549 void flush_tlb_kernel_range(unsigned long start
, unsigned long end
)
551 flush_tlb_kernel_range_common(start
, end
);
554 void flush_tlb_kernel_vm(void)
556 flush_tlb_kernel_range_common(start_vm
, end_vm
);
559 void __flush_tlb_one(unsigned long addr
)
561 flush_tlb_kernel_range_common(addr
, addr
+ PAGE_SIZE
);
564 static void fix_range(struct mm_struct
*mm
, unsigned long start_addr
,
565 unsigned long end_addr
, int force
)
568 * Don't bother flushing if this address space is about to be
571 if (atomic_read(&mm
->mm_users
) == 0)
574 fix_range_common(mm
, start_addr
, end_addr
, force
);
577 void flush_tlb_range(struct vm_area_struct
*vma
, unsigned long start
,
580 if (vma
->vm_mm
== NULL
)
581 flush_tlb_kernel_range_common(start
, end
);
582 else fix_range(vma
->vm_mm
, start
, end
, 0);
584 EXPORT_SYMBOL(flush_tlb_range
);
586 void flush_tlb_mm_range(struct mm_struct
*mm
, unsigned long start
,
589 fix_range(mm
, start
, end
, 0);
592 void flush_tlb_mm(struct mm_struct
*mm
)
594 struct vm_area_struct
*vma
= mm
->mmap
;
596 while (vma
!= NULL
) {
597 fix_range(mm
, vma
->vm_start
, vma
->vm_end
, 0);
602 void force_flush_all(void)
604 struct mm_struct
*mm
= current
->mm
;
605 struct vm_area_struct
*vma
= mm
->mmap
;
607 while (vma
!= NULL
) {
608 fix_range(mm
, vma
->vm_start
, vma
->vm_end
, 1);