1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Helper functions for KVM guest address space mapping code 4 * 5 * Copyright IBM Corp. 2007, 2025 6 */ 7 8 #include <linux/export.h> 9 #include <linux/mm_types.h> 10 #include <linux/mmap_lock.h> 11 #include <linux/mm.h> 12 #include <linux/hugetlb.h> 13 #include <linux/swap.h> 14 #include <linux/leafops.h> 15 #include <linux/pagewalk.h> 16 #include <linux/ksm.h> 17 #include <asm/gmap_helpers.h> 18 19 /** 20 * try_get_locked_pte() - like get_locked_pte(), but atomic and with trylock 21 * @mm: the mm 22 * @vmaddr: the userspace virtual address whose pte is to be found 23 * @ptl: will be set to the pointer to the lock used to lock the pte in case 24 * of success. 25 * 26 * This function returns the pointer to the pte corresponding to @addr in @mm, 27 * similarly to get_locked_pte(). Unlike get_locked_pte(), no attempt is made 28 * to allocate missing page tables. If a missing or large entry is found, the 29 * function will return NULL. If the ptl lock is contended, %-EAGAIN is 30 * returned. 31 * 32 * In case of success, *@ptl will point to the locked pte lock for the returned 33 * pte, like get_locked_pte() does. 34 * 35 * Context: mmap_lock or vma lock for read or for write needs to be held. 36 * Return: 37 * * %NULL if the pte cannot be reached. 38 * * %-EAGAIN if the pte can be reached, but cannot be locked. 39 * * the pointer to the pte corresponding to @addr in @mm, if it can be reached 40 * and locked. 41 */ 42 pte_t *try_get_locked_pte(struct mm_struct *mm, unsigned long vmaddr, spinlock_t **ptl) 43 __context_unsafe(/* Returns nonnull if lock taken or not taken */) 44 { 45 pmd_t *pmdp, pmd, pmdval; 46 pud_t *pudp, pud; 47 p4d_t *p4dp, p4d; 48 pgd_t *pgdp, pgd; 49 pte_t *ptep; 50 51 pgdp = pgd_offset(mm, vmaddr); 52 pgd = pgdp_get(pgdp); 53 if (pgd_none(pgd) || !pgd_present(pgd)) 54 return NULL; 55 p4dp = p4d_offset_lockless(pgdp, pgd, vmaddr); 56 p4d = p4dp_get(p4dp); 57 if (p4d_none(p4d) || !p4d_present(p4d)) 58 return NULL; 59 pudp = pud_offset_lockless(p4dp, p4d, vmaddr); 60 pud = pudp_get(pudp); 61 if (pud_none(pud) || pud_leaf(pud) || !pud_present(pud)) 62 return NULL; 63 pmdp = pmd_offset_lockless(pudp, pud, vmaddr); 64 pmd = pmdp_get_lockless(pmdp); 65 if (pmd_none(pmd) || pmd_leaf(pmd) || !pmd_present(pmd)) 66 return NULL; 67 ptep = pte_offset_map_rw_nolock(mm, pmdp, vmaddr, &pmdval, ptl); 68 if (!ptep) 69 return NULL; 70 71 if (spin_trylock(*ptl)) { 72 if (unlikely(!pmd_same(pmdval, pmdp_get_lockless(pmdp)))) { 73 pte_unmap_unlock(ptep, *ptl); 74 return ERR_PTR(-EAGAIN); 75 } 76 return ptep; 77 } 78 79 pte_unmap(ptep); 80 return ERR_PTR(-EAGAIN); 81 } 82 EXPORT_SYMBOL_GPL(try_get_locked_pte); 83 84 /** 85 * gmap_helper_zap_one_page() - discard a page if it was swapped. 86 * @mm: the mm 87 * @vmaddr: the userspace virtual address that needs to be discarded 88 * 89 * If the given address maps to a swap entry, discard it. 90 * 91 * Context: needs to be called while holding the mmap lock. 92 */ 93 void gmap_helper_zap_one_page(struct mm_struct *mm, unsigned long vmaddr) 94 __context_unsafe(/* pte_unmap_unlock() not instrumented */) 95 { 96 struct vm_area_struct *vma; 97 spinlock_t *ptl; /* Lock for the host (userspace) page table */ 98 softleaf_t sl; 99 pte_t *ptep; 100 101 mmap_assert_locked(mm); 102 103 /* Find the vm address for the guest address */ 104 vma = vma_lookup(mm, vmaddr); 105 if (!vma || is_vm_hugetlb_page(vma)) 106 return; 107 108 /* Get pointer to the page table entry */ 109 ptep = try_get_locked_pte(mm, vmaddr, &ptl); 110 if (IS_ERR_OR_NULL(ptep)) 111 return; 112 sl = softleaf_from_pte(*ptep); 113 if (pte_swap(*ptep) && softleaf_is_swap(sl)) { 114 dec_mm_counter(mm, MM_SWAPENTS); 115 swap_put_entries_direct(sl, 1); 116 pte_clear(mm, vmaddr, ptep); 117 } 118 pte_unmap_unlock(ptep, ptl); 119 } 120 EXPORT_SYMBOL_GPL(gmap_helper_zap_one_page); 121 122 /** 123 * gmap_helper_discard() - discard user pages in the given range 124 * @mm: the mm 125 * @vmaddr: starting userspace address 126 * @end: end address (first address outside the range) 127 * 128 * All userpace pages in the range [@vamddr, @end) are discarded and unmapped. 129 * 130 * Context: needs to be called while holding the mmap lock. 131 */ 132 void gmap_helper_discard(struct mm_struct *mm, unsigned long vmaddr, unsigned long end) 133 { 134 struct vm_area_struct *vma; 135 136 mmap_assert_locked(mm); 137 138 while (vmaddr < end) { 139 vma = find_vma_intersection(mm, vmaddr, end); 140 if (!vma) 141 return; 142 if (!is_vm_hugetlb_page(vma)) 143 zap_vma_range(vma, vmaddr, min(end, vma->vm_end) - vmaddr); 144 vmaddr = vma->vm_end; 145 } 146 } 147 EXPORT_SYMBOL_GPL(gmap_helper_discard); 148 149 /** 150 * gmap_helper_try_set_pte_unused() - mark a pte entry as unused 151 * @mm: the mm 152 * @vmaddr: the userspace address whose pte is to be marked 153 * 154 * Mark the pte corresponding the given address as unused. This will cause 155 * core mm code to just drop this page instead of swapping it. 156 * 157 * This function needs to be called with interrupts disabled (for example 158 * while holding a spinlock), or while holding the mmap lock. Normally this 159 * function is called as a result of an unmap operation, and thus KVM common 160 * code will already hold kvm->mmu_lock in write mode. 161 * 162 * Context: Needs to be called while holding the mmap lock or with interrupts 163 * disabled. 164 */ 165 void gmap_helper_try_set_pte_unused(struct mm_struct *mm, unsigned long vmaddr) 166 __context_unsafe(/* pte_unmap_unlock() not instrumented */) 167 { 168 spinlock_t *ptl; /* Lock for the host (userspace) page table */ 169 pte_t *ptep; 170 171 /* 172 * Several paths exists that takes the ptl lock and then call the 173 * mmu_notifier, which takes the mmu_lock. The unmap path, instead, 174 * takes the mmu_lock in write mode first, and then potentially 175 * calls this function, which takes the ptl lock. This can lead to a 176 * deadlock. 177 * The unused page mechanism is only an optimization, if the 178 * _PAGE_UNUSED bit is not set, the unused page is swapped as normal 179 * instead of being discarded. 180 * If the lock is contended the bit is not set and the deadlock is 181 * avoided. 182 */ 183 ptep = try_get_locked_pte(mm, vmaddr, &ptl); 184 if (IS_ERR_OR_NULL(ptep)) 185 return; 186 187 if (pte_present(*ptep)) 188 __atomic64_or(_PAGE_UNUSED, (long *)ptep); 189 pte_unmap_unlock(ptep, ptl); 190 } 191 EXPORT_SYMBOL_GPL(gmap_helper_try_set_pte_unused); 192 193 static int find_zeropage_pte_entry(pte_t *pte, unsigned long addr, 194 unsigned long end, struct mm_walk *walk) 195 { 196 unsigned long *found_addr = walk->private; 197 198 /* Return 1 of the page is a zeropage. */ 199 if (is_zero_pfn(pte_pfn(*pte))) { 200 /* 201 * Shared zeropage in e.g., a FS DAX mapping? We cannot do the 202 * right thing and likely don't care: FAULT_FLAG_UNSHARE 203 * currently only works in COW mappings, which is also where 204 * mm_forbids_zeropage() is checked. 205 */ 206 if (!vma_is_cow_mapping(walk->vma)) 207 return -EFAULT; 208 209 *found_addr = addr; 210 return 1; 211 } 212 return 0; 213 } 214 215 static const struct mm_walk_ops find_zeropage_ops = { 216 .pte_entry = find_zeropage_pte_entry, 217 .walk_lock = PGWALK_WRLOCK, 218 }; 219 220 /** __gmap_helper_unshare_zeropages() - unshare all shared zeropages 221 * @mm: the mm whose zero pages are to be unshared 222 * 223 * Unshare all shared zeropages, replacing them by anonymous pages. Note that 224 * we cannot simply zap all shared zeropages, because this could later 225 * trigger unexpected userfaultfd missing events. 226 * 227 * This must be called after mm->context.allow_cow_sharing was 228 * set to 0, to avoid future mappings of shared zeropages. 229 * 230 * mm contracts with s390, that even if mm were to remove a page table, 231 * and racing with walk_page_range_vma() calling pte_offset_map_lock() 232 * would fail, it will never insert a page table containing empty zero 233 * pages once mm_forbids_zeropage(mm) i.e. 234 * mm->context.allow_cow_sharing is set to 0. 235 */ 236 static int __gmap_helper_unshare_zeropages(struct mm_struct *mm) 237 { 238 struct vm_area_struct *vma; 239 VMA_ITERATOR(vmi, mm, 0); 240 unsigned long addr; 241 vm_fault_t fault; 242 int rc; 243 244 for_each_vma(vmi, vma) { 245 /* 246 * We could only look at COW mappings, but it's more future 247 * proof to catch unexpected zeropages in other mappings and 248 * fail. 249 */ 250 if ((vma->vm_flags & VM_PFNMAP) || is_vm_hugetlb_page(vma)) 251 continue; 252 addr = vma->vm_start; 253 254 retry: 255 rc = walk_page_range_vma(vma, addr, vma->vm_end, 256 &find_zeropage_ops, &addr); 257 if (rc < 0) 258 return rc; 259 else if (!rc) 260 continue; 261 262 /* addr was updated by find_zeropage_pte_entry() */ 263 fault = handle_mm_fault(vma, addr, 264 FAULT_FLAG_UNSHARE | FAULT_FLAG_REMOTE, 265 NULL); 266 if (fault & VM_FAULT_OOM) 267 return -ENOMEM; 268 /* 269 * See break_ksm(): even after handle_mm_fault() returned 0, we 270 * must start the lookup from the current address, because 271 * handle_mm_fault() may back out if there's any difficulty. 272 * 273 * VM_FAULT_SIGBUS and VM_FAULT_SIGSEGV are unexpected but 274 * maybe they could trigger in the future on concurrent 275 * truncation. In that case, the shared zeropage would be gone 276 * and we can simply retry and make progress. 277 */ 278 goto retry; 279 } 280 281 return 0; 282 } 283 284 /** 285 * gmap_helper_disable_cow_sharing() - disable all COW sharing 286 * 287 * Disable most COW-sharing of memory pages for the whole process: 288 * (1) Disable KSM and unmerge/unshare any KSM pages. 289 * (2) Disallow shared zeropages and unshare any zerpages that are mapped. 290 * 291 * Not that we currently don't bother with COW-shared pages that are shared 292 * with parent/child processes due to fork(). 293 */ 294 int gmap_helper_disable_cow_sharing(void) 295 { 296 struct mm_struct *mm = current->mm; 297 int rc; 298 299 mmap_assert_write_locked(mm); 300 301 if (!mm->context.allow_cow_sharing) 302 return 0; 303 304 mm->context.allow_cow_sharing = 0; 305 306 /* Replace all shared zeropages by anonymous pages. */ 307 rc = __gmap_helper_unshare_zeropages(mm); 308 /* 309 * Make sure to disable KSM (if enabled for the whole process or 310 * individual VMAs). Note that nothing currently hinders user space 311 * from re-enabling it. 312 */ 313 if (!rc) 314 rc = ksm_disable(mm); 315 if (rc) 316 mm->context.allow_cow_sharing = 1; 317 return rc; 318 } 319 EXPORT_SYMBOL_GPL(gmap_helper_disable_cow_sharing); 320