xref: /linux/arch/s390/mm/gmap_helpers.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
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