| 1 | /* |
| 2 | * QEMU page protection declarations. |
| 3 | * |
| 4 | * Copyright (c) 2003 Fabrice Bellard |
| 5 | * |
| 6 | * SPDX-License-Identifier: LGPL-2.1+ |
| 7 | */ |
| 8 | #ifndef USER_PAGE_PROTECTION_H |
| 9 | #define USER_PAGE_PROTECTION_H |
| 10 | |
| 11 | #ifndef CONFIG_USER_ONLY |
| 12 | #error Cannot include this header from system emulation |
| 13 | #endif |
| 14 | |
| 15 | #include "exec/vaddr.h" |
| 16 | #include "exec/translation-block.h" |
| 17 | |
| 18 | int page_unprotect(CPUState *cpu, tb_page_addr_t address, uintptr_t pc); |
| 19 | |
| 20 | int page_get_flags(vaddr address); |
| 21 | |
| 22 | /** |
| 23 | * page_set_flags: |
| 24 | * @start: first byte of range |
| 25 | * @last: last byte of range |
| 26 | * @set_flags: flags to set |
| 27 | * @clr_flags: flags to clear |
| 28 | * Context: holding mmap lock |
| 29 | * |
| 30 | * Modify the flags of a page and invalidate the code if necessary. |
| 31 | * The flag PAGE_WRITE_ORG is positioned automatically depending |
| 32 | * on PAGE_WRITE. The mmap_lock should already be held. |
| 33 | * |
| 34 | * For each page, flags = (flags & ~clr_flags) | set_flags. |
| 35 | * If clr_flags includes PAGE_VALID, this indicates a new mapping |
| 36 | * and page_reset_target_data will be called as well. |
| 37 | */ |
| 38 | void page_set_flags(vaddr start, vaddr last, int set_flags, int clr_flags); |
| 39 | |
| 40 | void page_reset_target_data(vaddr start, vaddr last); |
| 41 | |
| 42 | /** |
| 43 | * page_check_range |
| 44 | * @start: first byte of range |
| 45 | * @len: length of range |
| 46 | * @flags: flags required for each page |
| 47 | * |
| 48 | * Return true if every page in [@start, @start+@len) has @flags set. |
| 49 | * Return false if any page is unmapped. Thus testing flags == 0 is |
| 50 | * equivalent to testing for flags == PAGE_VALID. |
| 51 | */ |
| 52 | bool page_check_range(vaddr start, vaddr last, int flags); |
| 53 | |
| 54 | /** |
| 55 | * page_check_range_empty: |
| 56 | * @start: first byte of range |
| 57 | * @last: last byte of range |
| 58 | * Context: holding mmap lock |
| 59 | * |
| 60 | * Return true if the entire range [@start, @last] is unmapped. |
| 61 | * The memory lock must be held so that the caller will can ensure |
| 62 | * the result stays true until a new mapping can be installed. |
| 63 | */ |
| 64 | bool page_check_range_empty(vaddr start, vaddr last); |
| 65 | |
| 66 | /** |
| 67 | * page_find_range_empty |
| 68 | * @min: first byte of search range |
| 69 | * @max: last byte of search range |
| 70 | * @len: size of the hole required |
| 71 | * @align: alignment of the hole required (power of 2) |
| 72 | * |
| 73 | * If there is a range [x, x+@len) within [@min, @max] such that |
| 74 | * x % @align == 0, then return x. Otherwise return -1. |
| 75 | * The memory lock must be held, as the caller will want to ensure |
| 76 | * the returned range stays empty until a new mapping can be installed. |
| 77 | */ |
| 78 | vaddr page_find_range_empty(vaddr min, vaddr max, vaddr len, vaddr align); |
| 79 | |
| 80 | /** |
| 81 | * page_get_target_data |
| 82 | * @address: guest virtual address |
| 83 | * @size: per-page size |
| 84 | * |
| 85 | * Return @size bytes of out-of-band data to associate |
| 86 | * with the guest page at @address, allocating it if necessary. The |
| 87 | * caller should already have verified that the address is valid. |
| 88 | * The value of @size must be the same for every call. |
| 89 | * |
| 90 | * The memory will be freed when the guest page is deallocated, |
| 91 | * e.g. with the munmap system call. |
| 92 | */ |
| 93 | __attribute__((returns_nonnull)) |
| 94 | void *page_get_target_data(vaddr address, size_t size); |
| 95 | |
| 96 | typedef int (*walk_memory_regions_fn)(void *, vaddr, vaddr, int); |
| 97 | int walk_memory_regions(void *, walk_memory_regions_fn); |
| 98 | |
| 99 | void page_dump(FILE *f); |
| 100 | |
| 101 | #endif |