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 */
try_get_locked_pte(struct mm_struct * mm,unsigned long vmaddr,spinlock_t ** ptl)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 */
gmap_helper_zap_one_page(struct mm_struct * mm,unsigned long vmaddr)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 */
gmap_helper_discard(struct mm_struct * mm,unsigned long vmaddr,unsigned long end)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 */
gmap_helper_try_set_pte_unused(struct mm_struct * mm,unsigned long vmaddr)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
find_zeropage_pte_entry(pte_t * pte,unsigned long addr,unsigned long end,struct mm_walk * walk)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 */
__gmap_helper_unshare_zeropages(struct mm_struct * mm)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 */
gmap_helper_disable_cow_sharing(void)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