xref: /linux/arch/s390/kvm/gmap/dat.c (revision 148ab873d8194cb44f29474da3b4428fa2e100d1)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  KVM guest address space mapping code
4  *
5  *    Copyright IBM Corp. 2007, 2020, 2024
6  *    Author(s): Claudio Imbrenda <imbrenda@linux.ibm.com>
7  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
8  *		 David Hildenbrand <david@redhat.com>
9  *		 Janosch Frank <frankja@linux.ibm.com>
10  */
11 
12 #include <linux/kernel.h>
13 #include <linux/pagewalk.h>
14 #include <linux/swap.h>
15 #include <linux/smp.h>
16 #include <linux/spinlock.h>
17 #include <linux/slab.h>
18 #include <linux/swapops.h>
19 #include <linux/ksm.h>
20 #include <linux/mm.h>
21 #include <linux/mman.h>
22 #include <linux/pgtable.h>
23 #include <linux/kvm_types.h>
24 #include <linux/kvm_host.h>
25 #include <linux/pgalloc.h>
26 
27 #include <asm/page-states.h>
28 #include <asm/tlb.h>
29 #include "dat.h"
30 
31 int kvm_s390_mmu_cache_topup(struct kvm_s390_mmu_cache *mc)
32 {
33 	void *o;
34 
35 	for ( ; mc->n_crsts < KVM_S390_MMU_CACHE_N_CRSTS; mc->n_crsts++) {
36 		o = (void *)__get_free_pages(GFP_KERNEL_ACCOUNT | __GFP_COMP, CRST_ALLOC_ORDER);
37 		if (!o)
38 			return -ENOMEM;
39 		mc->crsts[mc->n_crsts] = o;
40 	}
41 	for ( ; mc->n_pts < KVM_S390_MMU_CACHE_N_PTS; mc->n_pts++) {
42 		o = (void *)__get_free_page(GFP_KERNEL_ACCOUNT);
43 		if (!o)
44 			return -ENOMEM;
45 		mc->pts[mc->n_pts] = o;
46 	}
47 	for ( ; mc->n_rmaps < KVM_S390_MMU_CACHE_N_RMAPS; mc->n_rmaps++) {
48 		o = kzalloc_obj(struct vsie_rmap, GFP_KERNEL_ACCOUNT);
49 		if (!o)
50 			return -ENOMEM;
51 		mc->rmaps[mc->n_rmaps] = o;
52 	}
53 	return 0;
54 }
55 
56 static inline struct page_table *dat_alloc_pt_noinit(struct kvm_s390_mmu_cache *mc)
57 {
58 	struct page_table *res;
59 
60 	res = kvm_s390_mmu_cache_alloc_pt(mc);
61 	if (res)
62 		__arch_set_page_dat(res, 1);
63 	return res;
64 }
65 
66 static inline struct crst_table *dat_alloc_crst_noinit(struct kvm_s390_mmu_cache *mc)
67 {
68 	struct crst_table *res;
69 
70 	res = kvm_s390_mmu_cache_alloc_crst(mc);
71 	if (res)
72 		__arch_set_page_dat(res, 1UL << CRST_ALLOC_ORDER);
73 	return res;
74 }
75 
76 struct crst_table *dat_alloc_crst_sleepable(unsigned long init)
77 {
78 	struct page *page;
79 	void *virt;
80 
81 	page = alloc_pages(GFP_KERNEL_ACCOUNT | __GFP_COMP, CRST_ALLOC_ORDER);
82 	if (!page)
83 		return NULL;
84 	virt = page_to_virt(page);
85 	__arch_set_page_dat(virt, 1UL << CRST_ALLOC_ORDER);
86 	crst_table_init(virt, init);
87 	return virt;
88 }
89 
90 void dat_free_level(struct crst_table *table, bool owns_ptes)
91 {
92 	unsigned int i;
93 
94 	for (i = 0; i < _CRST_ENTRIES; i++) {
95 		if (table->crstes[i].h.fc || table->crstes[i].h.i)
96 			continue;
97 		if (!is_pmd(table->crstes[i]))
98 			dat_free_level(dereference_crste(table->crstes[i]), owns_ptes);
99 		else if (owns_ptes)
100 			dat_free_pt(dereference_pmd(table->crstes[i].pmd));
101 	}
102 	dat_free_crst(table);
103 }
104 
105 int dat_set_asce_limit(struct kvm_s390_mmu_cache *mc, union asce *asce, int newtype)
106 {
107 	struct crst_table *table;
108 	union crste crste;
109 
110 	while (asce->dt > newtype) {
111 		table = dereference_asce(*asce);
112 		crste = table->crstes[0];
113 		if (crste.h.fc)
114 			return 0;
115 		if (!crste.h.i) {
116 			asce->rsto = crste.h.fc0.to;
117 			dat_free_crst(table);
118 		} else {
119 			crste.h.tt--;
120 			crst_table_init((void *)table, crste.val);
121 		}
122 		asce->dt--;
123 	}
124 	while (asce->dt < newtype) {
125 		crste = _crste_fc0(asce->rsto, asce->dt + 1);
126 		table = dat_alloc_crst_noinit(mc);
127 		if (!table)
128 			return -ENOMEM;
129 		crst_table_init((void *)table, _CRSTE_HOLE(crste.h.tt).val);
130 		table->crstes[0] = crste;
131 		asce->rsto = __pa(table) >> PAGE_SHIFT;
132 		asce->dt++;
133 	}
134 	return 0;
135 }
136 
137 /**
138  * dat_crstep_xchg_atomic() - Atomically exchange a gmap CRSTE with another.
139  * @crstep: Pointer to the CRST entry.
140  * @old: Expected old value.
141  * @new: Replacement entry.
142  * @gfn: The affected guest address.
143  * @asce: The asce of the address space.
144  *
145  * This function is needed to atomically exchange a CRSTE that potentially
146  * maps a prefix area, without having to invalidate it inbetween.
147  *
148  * Context: This function is assumed to be called with kvm->mmu_lock held.
149  *
150  * Return: %true if the exchange was successful.
151  */
152 bool __must_check dat_crstep_xchg_atomic(union crste *crstep, union crste old, union crste new,
153 					 gfn_t gfn, union asce asce)
154 {
155 	if (old.h.i)
156 		return arch_try_cmpxchg((long *)crstep, &old.val, new.val);
157 	if (cpu_has_edat2())
158 		return crdte_crste(crstep, old, new, gfn, asce);
159 	return cspg_crste(crstep, old, new);
160 }
161 
162 static void dat_set_storage_key_from_pgste(union pte pte, union pgste pgste)
163 {
164 	union skey nkey = { .acc = pgste.acc, .fp = pgste.fp };
165 
166 	page_set_storage_key(pte_origin(pte), nkey.skey, 0);
167 }
168 
169 static void dat_move_storage_key(union pte old, union pte new)
170 {
171 	page_set_storage_key(pte_origin(new), page_get_storage_key(pte_origin(old)), 1);
172 }
173 
174 static union pgste dat_save_storage_key_into_pgste(union pte pte, union pgste pgste)
175 {
176 	union skey skey;
177 
178 	skey.skey = page_get_storage_key(pte_origin(pte));
179 
180 	pgste.acc = skey.acc;
181 	pgste.fp = skey.fp;
182 	pgste.gr |= skey.r;
183 	pgste.gc |= skey.c;
184 
185 	return pgste;
186 }
187 
188 union pgste __dat_ptep_xchg(union pte *ptep, union pgste pgste, union pte new, gfn_t gfn,
189 			    union asce asce, bool uses_skeys)
190 {
191 	union pte old = READ_ONCE(*ptep);
192 
193 	/* Updating only the software bits while holding the pgste lock. */
194 	if (!((ptep->val ^ new.val) & ~_PAGE_SW_BITS)) {
195 		WRITE_ONCE(ptep->swbyte, new.swbyte);
196 		return pgste;
197 	}
198 
199 	if (!old.h.i) {
200 		unsigned long opts = IPTE_GUEST_ASCE | (pgste.nodat ? IPTE_NODAT : 0);
201 
202 		if (machine_has_tlb_guest())
203 			__ptep_ipte(gfn_to_gpa(gfn), (void *)ptep, opts, asce.val, IPTE_GLOBAL);
204 		else
205 			__ptep_ipte(gfn_to_gpa(gfn), (void *)ptep, 0, 0, IPTE_GLOBAL);
206 	}
207 
208 	if (uses_skeys) {
209 		if (old.h.i && !new.h.i)
210 			/* Invalid to valid: restore storage keys from PGSTE. */
211 			dat_set_storage_key_from_pgste(new, pgste);
212 		else if (!old.h.i && new.h.i)
213 			/* Valid to invalid: save storage keys to PGSTE. */
214 			pgste = dat_save_storage_key_into_pgste(old, pgste);
215 		else if (!old.h.i && !new.h.i)
216 			/* Valid to valid: move storage keys. */
217 			if (old.h.pfra != new.h.pfra)
218 				dat_move_storage_key(old, new);
219 		/* Invalid to invalid: nothing to do. */
220 	}
221 
222 	WRITE_ONCE(*ptep, new);
223 	return pgste;
224 }
225 
226 /*
227  * dat_split_ste() - Split a segment table entry into page table entries.
228  *
229  * Context: This function is assumed to be called with kvm->mmu_lock held.
230  *
231  * Return: 0 in case of success, -ENOMEM if running out of memory.
232  */
233 static int dat_split_ste(struct kvm_s390_mmu_cache *mc, union pmd *pmdp, gfn_t gfn,
234 			 union asce asce, bool uses_skeys)
235 {
236 	union pgste pgste_init;
237 	struct page_table *pt;
238 	union pmd new, old;
239 	union pte init;
240 	int i;
241 
242 	BUG_ON(!mc);
243 	old = READ_ONCE(*pmdp);
244 
245 	/* Already split, nothing to do. */
246 	if (!old.h.i && !old.h.fc)
247 		return 0;
248 
249 	pt = dat_alloc_pt_noinit(mc);
250 	if (!pt)
251 		return -ENOMEM;
252 	new.val = virt_to_phys(pt);
253 
254 	while (old.h.i || old.h.fc) {
255 		init.val = pmd_origin_large(old);
256 		init.h.p = old.h.p;
257 		init.h.i = old.h.i;
258 		init.s.d = old.s.fc1.d;
259 		init.s.w = old.s.fc1.w;
260 		init.s.y = old.s.fc1.y;
261 		init.s.sd = old.s.fc1.sd;
262 		init.s.pr = old.s.fc1.pr;
263 		pgste_init.val = 0;
264 		if (old.h.fc) {
265 			for (i = 0; i < _PAGE_ENTRIES; i++)
266 				pt->ptes[i].val = init.val | i * PAGE_SIZE;
267 			/* No need to take locks as the page table is not installed yet. */
268 			pgste_init.prefix_notif = old.s.fc1.prefix_notif;
269 			pgste_init.vsie_notif = old.s.fc1.vsie_notif;
270 			pgste_init.vsie_gmem = old.s.fc1.vsie_notif;
271 			pgste_init.pcl = uses_skeys && init.h.i;
272 			dat_init_pgstes(pt, pgste_init.val);
273 		} else {
274 			dat_init_page_table(pt, init.val, 0);
275 		}
276 
277 		if (dat_pmdp_xchg_atomic(pmdp, old, new, gfn, asce)) {
278 			if (!pgste_init.pcl)
279 				return 0;
280 			for (i = 0; i < _PAGE_ENTRIES; i++) {
281 				union pgste pgste = pt->pgstes[i];
282 
283 				pgste = dat_save_storage_key_into_pgste(pt->ptes[i], pgste);
284 				pgste_set_unlock(pt->ptes + i, pgste);
285 			}
286 			return 0;
287 		}
288 		old = READ_ONCE(*pmdp);
289 	}
290 
291 	dat_free_pt(pt);
292 	return 0;
293 }
294 
295 /*
296  * dat_split_crste() - Split a crste into smaller crstes.
297  *
298  * Context: This function is assumed to be called with kvm->mmu_lock held.
299  *
300  * Return: %0 in case of success, %-ENOMEM if running out of memory.
301  */
302 static int dat_split_crste(struct kvm_s390_mmu_cache *mc, union crste *crstep,
303 			   gfn_t gfn, union asce asce, bool uses_skeys)
304 {
305 	struct crst_table *table;
306 	union crste old, new, init;
307 	int i;
308 
309 	old = READ_ONCE(*crstep);
310 	if (is_pmd(old))
311 		return dat_split_ste(mc, &crstep->pmd, gfn, asce, uses_skeys);
312 
313 	BUG_ON(!mc);
314 
315 	/* Already split, nothing to do. */
316 	if (!old.h.i && !old.h.fc)
317 		return 0;
318 
319 	table = dat_alloc_crst_noinit(mc);
320 	if (!table)
321 		return -ENOMEM;
322 
323 	new.val = virt_to_phys(table);
324 	new.h.tt = old.h.tt;
325 	new.h.fc0.tl = _REGION_ENTRY_LENGTH;
326 
327 	while (old.h.i || old.h.fc) {
328 		init = old;
329 		init.h.tt--;
330 		if (old.h.fc) {
331 			for (i = 0; i < _CRST_ENTRIES; i++)
332 				table->crstes[i].val = init.val | i * HPAGE_SIZE;
333 		} else {
334 			crst_table_init((void *)table, init.val);
335 		}
336 		if (dat_crstep_xchg_atomic(crstep, old, new, gfn, asce))
337 			return 0;
338 		old = READ_ONCE(*crstep);
339 	}
340 
341 	dat_free_crst(table);
342 	return 0;
343 }
344 
345 /**
346  * dat_entry_walk() - Walk the gmap page tables.
347  * @mc: Cache to use to allocate dat tables, if needed; can be NULL if neither
348  *      %DAT_WALK_SPLIT or %DAT_WALK_ALLOC is specified in @flags.
349  * @gfn: Guest frame.
350  * @asce: The ASCE of the address space.
351  * @flags: Flags from WALK_* macros.
352  * @walk_level: Level to walk to, from LEVEL_* macros.
353  * @last: Will be filled the last visited non-pte DAT entry.
354  * @ptepp: Will be filled the last visited pte entry, if any, otherwise NULL.
355  *
356  * Returns a table entry pointer for the given guest address and @walk_level.
357  *
358  * The @flags have the following meanings:
359  * * %DAT_WALK_IGN_HOLES: consider holes as normal table entries
360  * * %DAT_WALK_ALLOC: allocate new tables to reach the requested level, if needed
361  * * %DAT_WALK_SPLIT: split existing large pages to reach the requested level, if needed
362  * * %DAT_WALK_LEAF: return successfully whenever a large page is encountered
363  * * %DAT_WALK_ANY: return successfully even if the requested level could not be reached
364  * * %DAT_WALK_CONTINUE: walk to the requested level with the specified flags, and then try to
365  *                       continue walking to ptes with only DAT_WALK_ANY
366  * * %DAT_WALK_USES_SKEYS: storage keys are in use
367  *
368  * Context: called with kvm->mmu_lock held.
369  *
370  * Return:
371  * * %PGM_ADDRESSING if the requested address lies outside memory
372  * * a PIC number if the requested address lies in a memory hole of type _DAT_TOKEN_PIC
373  * * %-EFAULT if the requested address lies inside a memory hole of a different type
374  * * %-EINVAL if the given ASCE is not compatible with the requested level
375  * * %-EFBIG if the requested level could not be reached because a larger frame was found
376  * * %-ENOENT if the requested level could not be reached for other reasons
377  * * %-ENOMEM if running out of memory while allocating or splitting a table
378  */
379 int dat_entry_walk(struct kvm_s390_mmu_cache *mc, gfn_t gfn, union asce asce, int flags,
380 		   int walk_level, union crste **last, union pte **ptepp)
381 {
382 	union vaddress vaddr = { .addr = gfn_to_gpa(gfn) };
383 	bool continue_anyway = flags & DAT_WALK_CONTINUE;
384 	bool uses_skeys = flags & DAT_WALK_USES_SKEYS;
385 	bool ign_holes = flags & DAT_WALK_IGN_HOLES;
386 	bool allocate = flags & DAT_WALK_ALLOC;
387 	bool split = flags & DAT_WALK_SPLIT;
388 	bool leaf = flags & DAT_WALK_LEAF;
389 	bool any = flags & DAT_WALK_ANY;
390 	struct page_table *pgtable;
391 	struct crst_table *table;
392 	union crste entry;
393 	int rc;
394 
395 	*last = NULL;
396 	*ptepp = NULL;
397 	if (WARN_ON_ONCE(unlikely(!asce.val)))
398 		return -EINVAL;
399 	if (WARN_ON_ONCE(unlikely(walk_level > asce.dt)))
400 		return -EINVAL;
401 	if (!asce_contains_gfn(asce, gfn))
402 		return PGM_ADDRESSING;
403 
404 	table = dereference_asce(asce);
405 	if (asce.dt >= ASCE_TYPE_REGION1) {
406 		*last = table->crstes + vaddr.rfx;
407 		entry = READ_ONCE(**last);
408 		if (WARN_ON_ONCE(entry.h.tt != TABLE_TYPE_REGION1))
409 			return -EINVAL;
410 		if (crste_hole(entry) && !ign_holes)
411 			return entry.tok.type == _DAT_TOKEN_PIC ? entry.tok.par : -EFAULT;
412 		if (walk_level == TABLE_TYPE_REGION1)
413 			return 0;
414 		if (entry.pgd.h.i) {
415 			if (!allocate)
416 				return any ? 0 : -ENOENT;
417 			rc = dat_split_crste(mc, *last, gfn, asce, uses_skeys);
418 			if (rc)
419 				return rc;
420 			entry = READ_ONCE(**last);
421 		}
422 		table = dereference_crste(entry.pgd);
423 	}
424 
425 	if (asce.dt >= ASCE_TYPE_REGION2) {
426 		*last = table->crstes + vaddr.rsx;
427 		entry = READ_ONCE(**last);
428 		if (WARN_ON_ONCE(entry.h.tt != TABLE_TYPE_REGION2))
429 			return -EINVAL;
430 		if (crste_hole(entry) && !ign_holes)
431 			return entry.tok.type == _DAT_TOKEN_PIC ? entry.tok.par : -EFAULT;
432 		if (walk_level == TABLE_TYPE_REGION2)
433 			return 0;
434 		if (entry.p4d.h.i) {
435 			if (!allocate)
436 				return any ? 0 : -ENOENT;
437 			rc = dat_split_crste(mc, *last, gfn, asce, uses_skeys);
438 			if (rc)
439 				return rc;
440 			entry = READ_ONCE(**last);
441 		}
442 		table = dereference_crste(entry.p4d);
443 	}
444 
445 	if (asce.dt >= ASCE_TYPE_REGION3) {
446 		*last = table->crstes + vaddr.rtx;
447 		entry = READ_ONCE(**last);
448 		if (WARN_ON_ONCE(entry.h.tt != TABLE_TYPE_REGION3))
449 			return -EINVAL;
450 		if (crste_hole(entry) && !ign_holes)
451 			return entry.tok.type == _DAT_TOKEN_PIC ? entry.tok.par : -EFAULT;
452 		if (walk_level == TABLE_TYPE_REGION3 &&
453 		    continue_anyway && !entry.pud.h.fc && !entry.h.i) {
454 			walk_level = TABLE_TYPE_PAGE_TABLE;
455 			allocate = false;
456 		}
457 		if (walk_level == TABLE_TYPE_REGION3 || ((leaf || any) && entry.pud.h.fc))
458 			return 0;
459 		if (entry.pud.h.i && !entry.pud.h.fc) {
460 			if (!allocate)
461 				return any ? 0 : -ENOENT;
462 			rc = dat_split_crste(mc, *last, gfn, asce, uses_skeys);
463 			if (rc)
464 				return rc;
465 			entry = READ_ONCE(**last);
466 		}
467 		if (walk_level <= TABLE_TYPE_SEGMENT && entry.pud.h.fc) {
468 			if (!split)
469 				return -EFBIG;
470 			rc = dat_split_crste(mc, *last, gfn, asce, uses_skeys);
471 			if (rc)
472 				return rc;
473 			entry = READ_ONCE(**last);
474 		}
475 		table = dereference_crste(entry.pud);
476 	}
477 
478 	*last = table->crstes + vaddr.sx;
479 	entry = READ_ONCE(**last);
480 	if (WARN_ON_ONCE(entry.h.tt != TABLE_TYPE_SEGMENT))
481 		return -EINVAL;
482 	if (crste_hole(entry) && !ign_holes)
483 		return entry.tok.type == _DAT_TOKEN_PIC ? entry.tok.par : -EFAULT;
484 	if (continue_anyway && !entry.pmd.h.fc && !entry.h.i) {
485 		walk_level = TABLE_TYPE_PAGE_TABLE;
486 		allocate = false;
487 	}
488 	if (walk_level == TABLE_TYPE_SEGMENT || ((leaf || any) && entry.pmd.h.fc))
489 		return 0;
490 
491 	if (entry.pmd.h.i && !entry.pmd.h.fc) {
492 		if (!allocate)
493 			return any ? 0 : -ENOENT;
494 		rc = dat_split_ste(mc, &(*last)->pmd, gfn, asce, uses_skeys);
495 		if (rc)
496 			return rc;
497 		entry = READ_ONCE(**last);
498 	}
499 	if (walk_level <= TABLE_TYPE_PAGE_TABLE && entry.pmd.h.fc) {
500 		if (!split)
501 			return -EFBIG;
502 		rc = dat_split_ste(mc, &(*last)->pmd, gfn, asce, uses_skeys);
503 		if (rc)
504 			return rc;
505 		entry = READ_ONCE(**last);
506 	}
507 	pgtable = dereference_pmd(entry.pmd);
508 	*ptepp = pgtable->ptes + vaddr.px;
509 	if (pte_hole(**ptepp) && !ign_holes)
510 		return (*ptepp)->tok.type == _DAT_TOKEN_PIC ? (*ptepp)->tok.par : -EFAULT;
511 	return 0;
512 }
513 
514 static long dat_pte_walk_range(gfn_t gfn, gfn_t end, struct page_table *table, struct dat_walk *w)
515 {
516 	unsigned int idx = gfn & (_PAGE_ENTRIES - 1);
517 	long rc = 0;
518 
519 	for ( ; gfn < end; idx++, gfn++) {
520 		if (pte_hole(READ_ONCE(table->ptes[idx]))) {
521 			if (!(w->flags & DAT_WALK_IGN_HOLES))
522 				return -EFAULT;
523 			if (!(w->flags & DAT_WALK_ANY))
524 				continue;
525 		}
526 
527 		rc = w->ops->pte_entry(table->ptes + idx, gfn, gfn + 1, w);
528 		if (rc)
529 			break;
530 	}
531 	return rc;
532 }
533 
534 static long dat_crste_walk_range(gfn_t start, gfn_t end, struct crst_table *table,
535 				 struct dat_walk *walk)
536 {
537 	unsigned long idx, cur_shift, cur_size;
538 	dat_walk_op the_op;
539 	union crste crste;
540 	gfn_t cur, next;
541 	long rc = 0;
542 
543 	cur_shift = 8 + table->crstes[0].h.tt * 11;
544 	idx = (start >> cur_shift) & (_CRST_ENTRIES - 1);
545 	cur_size = 1UL << cur_shift;
546 
547 	for (cur = ALIGN_DOWN(start, cur_size); cur < end; idx++, cur = next) {
548 		next = cur + cur_size;
549 		walk->last = table->crstes + idx;
550 		crste = READ_ONCE(*walk->last);
551 
552 		if (crste_hole(crste)) {
553 			if (!(walk->flags & DAT_WALK_IGN_HOLES))
554 				return -EFAULT;
555 			if (!(walk->flags & DAT_WALK_ANY))
556 				continue;
557 		}
558 
559 		the_op = walk->ops->crste_ops[crste.h.tt];
560 		if (the_op) {
561 			rc = the_op(walk->last, cur, next, walk);
562 			crste = READ_ONCE(*walk->last);
563 		}
564 		if (rc)
565 			break;
566 		if (!crste.h.i && !crste.h.fc) {
567 			if (!is_pmd(crste))
568 				rc = dat_crste_walk_range(max(start, cur), min(end, next),
569 							  _dereference_crste(crste), walk);
570 			else if (walk->ops->pte_entry)
571 				rc = dat_pte_walk_range(max(start, cur), min(end, next),
572 							dereference_pmd(crste.pmd), walk);
573 			if (rc)
574 				break;
575 		}
576 	}
577 	return rc;
578 }
579 
580 /**
581  * _dat_walk_gfn_range() - Walk DAT tables.
582  * @start: The first guest page frame to walk.
583  * @end: The guest page frame immediately after the last one to walk.
584  * @asce: The ASCE of the guest mapping.
585  * @ops: The gmap_walk_ops that will be used to perform the walk.
586  * @flags: Flags from WALK_* (currently only WALK_IGN_HOLES is supported).
587  * @priv: Will be passed as-is to the callbacks.
588  *
589  * Any callback returning non-zero causes the walk to stop immediately.
590  *
591  * Return: %-EINVAL in case of error, %-EFAULT if @start is too high for the
592  *         given ASCE unless the DAT_WALK_IGN_HOLES flag is specified,
593  *         otherwise it returns whatever the callbacks return.
594  */
595 long _dat_walk_gfn_range(gfn_t start, gfn_t end, union asce asce,
596 			 const struct dat_walk_ops *ops, int flags, void *priv)
597 {
598 	struct crst_table *table = dereference_asce(asce);
599 	struct dat_walk walk = {
600 		.ops	= ops,
601 		.asce	= asce,
602 		.priv	= priv,
603 		.flags	= flags,
604 		.start	= start,
605 		.end	= end,
606 	};
607 
608 	if (WARN_ON_ONCE(unlikely(!asce.val)))
609 		return -EINVAL;
610 	if (!asce_contains_gfn(asce, start))
611 		return (flags & DAT_WALK_IGN_HOLES) ? 0 : -EFAULT;
612 
613 	return dat_crste_walk_range(start, min(end, asce_end(asce)), table, &walk);
614 }
615 
616 #if KVM_S390_MANAGES_S390_GUEST
617 int dat_get_storage_key(union asce asce, gfn_t gfn, union skey *skey)
618 {
619 	union crste *crstep;
620 	union pgste pgste;
621 	union pte *ptep;
622 	int rc;
623 
624 again:
625 	skey->skey = 0;
626 	rc = dat_entry_walk(NULL, gfn, asce, DAT_WALK_ANY, TABLE_TYPE_PAGE_TABLE, &crstep, &ptep);
627 	if (rc)
628 		return rc;
629 
630 	if (!ptep) {
631 		union crste crste = READ_ONCE(*crstep);
632 
633 		if (!crste_leaf(crste) && !crste.h.i)
634 			goto again;
635 		if (!crste.s.fc1.pr)
636 			return 0;
637 
638 		skey->skey = page_get_storage_key(large_crste_to_phys(crste, gfn));
639 		return 0;
640 	}
641 	pgste = pgste_get_lock(ptep);
642 	if (ptep->h.i) {
643 		skey->acc = pgste.acc;
644 		skey->fp = pgste.fp;
645 	} else {
646 		skey->skey = page_get_storage_key(pte_origin(*ptep));
647 	}
648 	skey->r |= pgste.gr;
649 	skey->c |= pgste.gc;
650 	pgste_set_unlock(ptep, pgste);
651 	return 0;
652 }
653 
654 static void dat_update_ptep_sd(union pgste old, union pgste pgste, union pte *ptep)
655 {
656 	if (pgste.acc != old.acc || pgste.fp != old.fp || pgste.gr != old.gr || pgste.gc != old.gc)
657 		__atomic64_or(_PAGE_SD, &ptep->val);
658 }
659 
660 int dat_set_storage_key(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t gfn,
661 			union skey skey, bool nq)
662 {
663 	union pgste pgste, old;
664 	union crste *crstep;
665 	union pte *ptep;
666 	int rc;
667 
668 again:
669 	rc = dat_entry_walk(mc, gfn, asce, DAT_WALK_LEAF_ALLOC, TABLE_TYPE_PAGE_TABLE,
670 			    &crstep, &ptep);
671 	if (rc)
672 		return rc;
673 
674 	if (!ptep) {
675 		union crste crste = READ_ONCE(*crstep);
676 
677 		/* A large page has been split concurrently, try again */
678 		if (!crste_leaf(crste))
679 			goto again;
680 
681 		page_set_storage_key(large_crste_to_phys(crste, gfn), skey.skey, !nq);
682 		return 0;
683 	}
684 
685 	old = pgste_get_lock(ptep);
686 	pgste = old;
687 
688 	pgste.acc = skey.acc;
689 	pgste.fp = skey.fp;
690 	pgste.gc = skey.c;
691 	pgste.gr = skey.r;
692 
693 	if (!ptep->h.i) {
694 		union skey old_skey;
695 
696 		old_skey.skey = page_get_storage_key(pte_origin(*ptep));
697 		pgste.hc |= old_skey.c;
698 		pgste.hr |= old_skey.r;
699 		old_skey.c = old.gc;
700 		old_skey.r = old.gr;
701 		skey.r = 0;
702 		skey.c = 0;
703 		page_set_storage_key(pte_origin(*ptep), skey.skey, !nq);
704 	}
705 
706 	dat_update_ptep_sd(old, pgste, ptep);
707 	pgste_set_unlock(ptep, pgste);
708 	return 0;
709 }
710 
711 static bool page_cond_set_storage_key(phys_addr_t paddr, union skey skey, union skey *oldkey,
712 				      bool nq, bool mr, bool mc)
713 {
714 	oldkey->skey = page_get_storage_key(paddr);
715 	if (oldkey->acc == skey.acc && oldkey->fp == skey.fp &&
716 	    (oldkey->r == skey.r || mr) && (oldkey->c == skey.c || mc))
717 		return false;
718 	page_set_storage_key(paddr, skey.skey, !nq);
719 	return true;
720 }
721 
722 int dat_cond_set_storage_key(struct kvm_s390_mmu_cache *mmc, union asce asce, gfn_t gfn,
723 			     union skey skey, union skey *oldkey, bool nq, bool mr, bool mc)
724 {
725 	union pgste pgste, old;
726 	union crste *crstep;
727 	union skey prev;
728 	union pte *ptep;
729 	int rc;
730 
731 again:
732 	rc = dat_entry_walk(mmc, gfn, asce, DAT_WALK_LEAF_ALLOC, TABLE_TYPE_PAGE_TABLE,
733 			    &crstep, &ptep);
734 	if (rc)
735 		return rc;
736 
737 	if (!ptep) {
738 		union crste crste = READ_ONCE(*crstep);
739 
740 		/* A large page has been split concurrently, try again */
741 		if (!crste_leaf(crste))
742 			goto again;
743 		if (!oldkey)
744 			oldkey = &prev;
745 
746 		return page_cond_set_storage_key(large_crste_to_phys(crste, gfn), skey, oldkey,
747 						 nq, mr, mc);
748 	}
749 
750 	old = pgste_get_lock(ptep);
751 	pgste = old;
752 
753 	rc = 1;
754 	pgste.acc = skey.acc;
755 	pgste.fp = skey.fp;
756 	pgste.gc = skey.c;
757 	pgste.gr = skey.r;
758 	prev.skey = 0;
759 
760 	if (!ptep->h.i) {
761 		rc = page_cond_set_storage_key(pte_origin(*ptep), skey, &prev, nq, mr, mc);
762 		pgste.hc |= prev.c;
763 		pgste.hr |= prev.r;
764 		prev.c |= old.gc;
765 		prev.r |= old.gr;
766 	} else {
767 		prev.acc = old.acc;
768 		prev.fp = old.fp;
769 		prev.c = old.gc;
770 		prev.r = old.gr;
771 	}
772 	if (oldkey)
773 		*oldkey = prev;
774 
775 	dat_update_ptep_sd(old, pgste, ptep);
776 	pgste_set_unlock(ptep, pgste);
777 	return rc;
778 }
779 
780 int dat_reset_reference_bit(union asce asce, gfn_t gfn, union skey *skey)
781 {
782 	union pgste pgste, old;
783 	union crste *crstep;
784 	union pte *ptep;
785 	int rc;
786 
787 	skey->skey = 0;
788 again:
789 	rc = dat_entry_walk(NULL, gfn, asce, DAT_WALK_ANY, TABLE_TYPE_PAGE_TABLE, &crstep, &ptep);
790 	if (rc)
791 		return rc;
792 
793 	if (!ptep) {
794 		union crste crste = READ_ONCE(*crstep);
795 
796 		/* A large page has been split concurrently, try again */
797 		if (!crste_leaf(crste) && !crste.h.i)
798 			goto again;
799 		if (!crste.s.fc1.pr)
800 			return 0;
801 		skey->skey = page_reset_referenced(large_crste_to_phys(crste, gfn)) << 1;
802 		return 0;
803 	}
804 	old = pgste_get_lock(ptep);
805 	pgste = old;
806 
807 	if (!ptep->h.i) {
808 		skey->skey = page_reset_referenced(pte_origin(*ptep)) << 1;
809 		pgste.hr = skey->r;
810 	}
811 	skey->r |= pgste.gr;
812 	skey->c |= pgste.gc;
813 	pgste.gr = 0;
814 
815 	dat_update_ptep_sd(old, pgste, ptep);
816 	pgste_set_unlock(ptep, pgste);
817 	return 0;
818 }
819 
820 static long dat_reset_skeys_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
821 {
822 	union pgste pgste;
823 
824 	pgste = pgste_get_lock(ptep);
825 	pgste.acc = 0;
826 	pgste.fp = 0;
827 	pgste.gr = 0;
828 	pgste.gc = 0;
829 	if (ptep->s.pr)
830 		page_set_storage_key(pte_origin(*ptep), PAGE_DEFAULT_KEY, 1);
831 	pgste_set_unlock(ptep, pgste);
832 
833 	if (need_resched())
834 		return next;
835 	return 0;
836 }
837 
838 static long dat_reset_skeys_crste(union crste *crstep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
839 {
840 	phys_addr_t addr, end, origin = crste_origin_large(*crstep);
841 
842 	if (!crstep->h.fc || !crstep->s.fc1.pr)
843 		return 0;
844 
845 	addr = ((max(gfn, walk->start) - gfn) << PAGE_SHIFT) + origin;
846 	end = ((min(next, walk->end) - gfn) << PAGE_SHIFT) + origin;
847 	while (ALIGN(addr + 1, _SEGMENT_SIZE) <= end)
848 		addr = sske_frame(addr, PAGE_DEFAULT_KEY);
849 	for ( ; addr < end; addr += PAGE_SIZE)
850 		page_set_storage_key(addr, PAGE_DEFAULT_KEY, 1);
851 
852 	if (need_resched())
853 		return next;
854 	return 0;
855 }
856 
857 long dat_reset_skeys(union asce asce, gfn_t start)
858 {
859 	const struct dat_walk_ops ops = {
860 		.pte_entry = dat_reset_skeys_pte,
861 		.pmd_entry = dat_reset_skeys_crste,
862 		.pud_entry = dat_reset_skeys_crste,
863 	};
864 
865 	return _dat_walk_gfn_range(start, asce_end(asce), asce, &ops, DAT_WALK_IGN_HOLES, NULL);
866 }
867 #endif /* KVM_S390_MANAGES_S390_GUEST */
868 
869 static long _dat_slot_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
870 {
871 	union pte new_pte, pte = READ_ONCE(*ptep);
872 	union pgste pgste;
873 
874 	new_pte = walk->priv ? _PTE_EMPTY : _PTE_TOK(_DAT_TOKEN_PIC, PGM_ADDRESSING);
875 
876 	/* Table entry already in the desired state. */
877 	if (pte.val == new_pte.val)
878 		return 0;
879 
880 	pgste = pgste_get_lock(ptep);
881 	pgste = __dat_ptep_xchg(ptep, pgste, new_pte, gfn, walk->asce, false);
882 	pgste.cmma_d = 0;
883 	pgste_set_unlock(ptep, pgste);
884 
885 	return 0;
886 }
887 
888 static long _dat_slot_crste(union crste *crstep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
889 {
890 	union crste new_crste, crste = READ_ONCE(*crstep);
891 	struct kvm_s390_mmu_cache *mc = walk->priv;
892 
893 	new_crste = mc ? _CRSTE_EMPTY(crste.h.tt) : _CRSTE_HOLE(crste.h.tt);
894 
895 	/* Table entry already in the desired state. */
896 	if (crste.val == new_crste.val)
897 		return 0;
898 
899 	/* This table entry needs to be updated. */
900 	if (walk->start <= gfn && walk->end >= next) {
901 		if (!dat_crstep_xchg_atomic(crstep, crste, new_crste, gfn, walk->asce))
902 			return -EINVAL;
903 		/* A lower level table was present, needs to be freed. */
904 		if (!crste.h.fc && !crste.h.i) {
905 			if (is_pmd(crste))
906 				dat_free_pt(dereference_pmd(crste.pmd));
907 			else
908 				dat_free_level(dereference_crste(crste), true);
909 		}
910 		return 0;
911 	}
912 
913 	/* A lower level table is present, things will handled there. */
914 	if (!crste.h.fc && !crste.h.i)
915 		return 0;
916 	/* Split (install a lower level table), and handle things there. */
917 	if (mc)
918 		return dat_split_crste(mc, crstep, gfn, walk->asce, false);
919 	/* A large page should never cross memslots boundaries */
920 	return -EINVAL;
921 }
922 
923 static const struct dat_walk_ops dat_slot_ops = {
924 	.pte_entry = _dat_slot_pte,
925 	.crste_ops = { _dat_slot_crste, _dat_slot_crste, _dat_slot_crste, _dat_slot_crste, },
926 };
927 
928 int dat_set_slot(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t start, gfn_t end)
929 {
930 	return _dat_walk_gfn_range(start, end, asce, &dat_slot_ops,
931 				   DAT_WALK_IGN_HOLES | DAT_WALK_ANY, mc);
932 }
933 
934 static void pgste_set_unlock_multiple(union pte *first, int n, union pgste *pgstes)
935 {
936 	int i;
937 
938 	for (i = 0; i < n; i++)
939 		pgste_set_unlock(first + i, pgstes[i]);
940 }
941 
942 static bool pgste_get_trylock_multiple(union pte *first, int n, union pgste *pgstes)
943 {
944 	int i;
945 
946 	for (i = 0; i < n; i++) {
947 		if (!pgste_get_trylock(first + i, pgstes + i))
948 			break;
949 	}
950 	if (i == n)
951 		return true;
952 	pgste_set_unlock_multiple(first, i, pgstes);
953 	return false;
954 }
955 
956 unsigned long dat_get_ptval(struct page_table *table, struct ptval_param param)
957 {
958 	union pgste pgstes[4] = {};
959 	unsigned long res = 0;
960 	int i, n;
961 
962 	n = param.len + 1;
963 
964 	while (!pgste_get_trylock_multiple(table->ptes + param.offset, n, pgstes))
965 		cpu_relax();
966 
967 	for (i = 0; i < n; i++)
968 		res = res << 16 | pgstes[i].val16;
969 
970 	pgste_set_unlock_multiple(table->ptes + param.offset, n, pgstes);
971 	return res;
972 }
973 
974 void dat_set_ptval(struct page_table *table, struct ptval_param param, unsigned long val)
975 {
976 	union pgste pgstes[4] = {};
977 	int i, n;
978 
979 	n = param.len + 1;
980 
981 	while (!pgste_get_trylock_multiple(table->ptes + param.offset, n, pgstes))
982 		cpu_relax();
983 
984 	for (i = param.len; i >= 0; i--) {
985 		pgstes[i].val16 = val;
986 		val = val >> 16;
987 	}
988 
989 	pgste_set_unlock_multiple(table->ptes + param.offset, n, pgstes);
990 }
991 
992 static long _dat_test_young_pte(union pte *ptep, gfn_t start, gfn_t end, struct dat_walk *walk)
993 {
994 	return ptep->s.y;
995 }
996 
997 static long _dat_test_young_crste(union crste *crstep, gfn_t start, gfn_t end,
998 				  struct dat_walk *walk)
999 {
1000 	return crstep->h.fc && crstep->s.fc1.y;
1001 }
1002 
1003 static const struct dat_walk_ops test_age_ops = {
1004 	.pte_entry = _dat_test_young_pte,
1005 	.pmd_entry = _dat_test_young_crste,
1006 	.pud_entry = _dat_test_young_crste,
1007 };
1008 
1009 /**
1010  * dat_test_age_gfn() - Test young.
1011  * @asce: The ASCE whose address range is to be tested.
1012  * @start: The first guest frame of the range to check.
1013  * @end: The guest frame after the last in the range.
1014  *
1015  * Context: called by KVM common code with the kvm mmu write lock held.
1016  *
1017  * Return: %true if any page in the given range is young, otherwise %false.
1018  */
1019 bool dat_test_age_gfn(union asce asce, gfn_t start, gfn_t end)
1020 {
1021 	return _dat_walk_gfn_range(start, end, asce, &test_age_ops, 0, NULL) > 0;
1022 }
1023 
1024 #if KVM_S390_MANAGES_S390_GUEST
1025 static long dat_set_pn_crste(union crste *crstep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
1026 {
1027 	union crste newcrste, oldcrste;
1028 	int *n = walk->priv;
1029 
1030 	do {
1031 		oldcrste = READ_ONCE(*crstep);
1032 		if (!oldcrste.h.fc || oldcrste.h.i || oldcrste.h.p)
1033 			return 0;
1034 		if (oldcrste.s.fc1.prefix_notif)
1035 			break;
1036 		newcrste = oldcrste;
1037 		newcrste.s.fc1.prefix_notif = 1;
1038 	} while (!dat_crstep_xchg_atomic(crstep, oldcrste, newcrste, gfn, walk->asce));
1039 	*n = 2;
1040 	return 0;
1041 }
1042 
1043 static long dat_set_pn_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
1044 {
1045 	int *n = walk->priv;
1046 	union pgste pgste;
1047 
1048 	pgste = pgste_get_lock(ptep);
1049 	if (!ptep->h.i && !ptep->h.p) {
1050 		pgste.prefix_notif = 1;
1051 		*n += 1;
1052 	}
1053 	pgste_set_unlock(ptep, pgste);
1054 	return 0;
1055 }
1056 
1057 int dat_set_prefix_notif_bit(union asce asce, gfn_t gfn)
1058 {
1059 	static const struct dat_walk_ops ops = {
1060 		.pte_entry = dat_set_pn_pte,
1061 		.pmd_entry = dat_set_pn_crste,
1062 		.pud_entry = dat_set_pn_crste,
1063 	};
1064 
1065 	int n = 0;
1066 
1067 	_dat_walk_gfn_range(gfn, gfn + 2, asce, &ops, DAT_WALK_IGN_HOLES, &n);
1068 	if (n != 2)
1069 		return -EAGAIN;
1070 	return 0;
1071 }
1072 
1073 /**
1074  * dat_perform_essa() - Perform ESSA actions on the PGSTE.
1075  * @asce: The asce to operate on.
1076  * @gfn: The guest page frame to operate on.
1077  * @orc: The specific action to perform, see the ESSA_SET_* macros.
1078  * @state: The storage attributes to be returned to the guest.
1079  * @dirty: Returns whether the function dirtied a previously clean entry.
1080  *
1081  * Context: Called with kvm->mmu_lock held.
1082  *
1083  * Return:
1084  * * %1 if the page state has been altered and the page is to be added to the CBRL
1085  * * %0 if the page state has been altered, but the page is not to be added to the CBRL
1086  * * %-1 if the page state has not been altered and the page is not to be added to the CBRL
1087  */
1088 int dat_perform_essa(union asce asce, gfn_t gfn, int orc, union essa_state *state, bool *dirty)
1089 {
1090 	union crste *crstep;
1091 	union pgste pgste;
1092 	union pte *ptep;
1093 	int res = 0;
1094 
1095 	if (dat_entry_walk(NULL, gfn, asce, 0, TABLE_TYPE_PAGE_TABLE, &crstep, &ptep)) {
1096 		*state = (union essa_state) { .exception = 1 };
1097 		return -1;
1098 	}
1099 
1100 	pgste = pgste_get_lock(ptep);
1101 
1102 	*state = (union essa_state) {
1103 		.content = (ptep->h.i << 1) + (ptep->h.i && pgste.zero),
1104 		.nodat = pgste.nodat,
1105 		.usage = pgste.usage,
1106 		};
1107 
1108 	switch (orc) {
1109 	case ESSA_GET_STATE:
1110 		res = -1;
1111 		break;
1112 	case ESSA_SET_STABLE:
1113 		pgste.usage = PGSTE_GPS_USAGE_STABLE;
1114 		pgste.nodat = 0;
1115 		break;
1116 	case ESSA_SET_UNUSED:
1117 		pgste.usage = PGSTE_GPS_USAGE_UNUSED;
1118 		if (ptep->h.i)
1119 			res = 1;
1120 		break;
1121 	case ESSA_SET_VOLATILE:
1122 		pgste.usage = PGSTE_GPS_USAGE_VOLATILE;
1123 		if (ptep->h.i)
1124 			res = 1;
1125 		break;
1126 	case ESSA_SET_POT_VOLATILE:
1127 		if (!ptep->h.i) {
1128 			pgste.usage = PGSTE_GPS_USAGE_POT_VOLATILE;
1129 		} else if (pgste.zero) {
1130 			pgste.usage = PGSTE_GPS_USAGE_VOLATILE;
1131 		} else if (!pgste.gc) {
1132 			pgste.usage = PGSTE_GPS_USAGE_VOLATILE;
1133 			res = 1;
1134 		}
1135 		break;
1136 	case ESSA_SET_STABLE_RESIDENT:
1137 		pgste.usage = PGSTE_GPS_USAGE_STABLE;
1138 		/*
1139 		 * Since the resident state can go away any time after this
1140 		 * call, we will not make this page resident. We can revisit
1141 		 * this decision if a guest will ever start using this.
1142 		 */
1143 		break;
1144 	case ESSA_SET_STABLE_IF_RESIDENT:
1145 		if (!ptep->h.i)
1146 			pgste.usage = PGSTE_GPS_USAGE_STABLE;
1147 		break;
1148 	case ESSA_SET_STABLE_NODAT:
1149 		pgste.usage = PGSTE_GPS_USAGE_STABLE;
1150 		pgste.nodat = 1;
1151 		break;
1152 	default:
1153 		WARN_ONCE(1, "Invalid ORC!");
1154 		res = -1;
1155 		break;
1156 	}
1157 	/* If we are discarding a page, set it to logical zero. */
1158 	pgste.zero = res == 1;
1159 	if (orc > 0) {
1160 		*dirty = !pgste.cmma_d;
1161 		pgste.cmma_d = 1;
1162 	}
1163 
1164 	pgste_set_unlock(ptep, pgste);
1165 
1166 	return res;
1167 }
1168 
1169 static long dat_reset_cmma_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
1170 {
1171 	union pgste pgste;
1172 
1173 	pgste = pgste_get_lock(ptep);
1174 	pgste.usage = 0;
1175 	pgste.nodat = 0;
1176 	pgste.cmma_d = 0;
1177 	pgste_set_unlock(ptep, pgste);
1178 	if (need_resched())
1179 		return next;
1180 	return 0;
1181 }
1182 
1183 long dat_reset_cmma(union asce asce, gfn_t start)
1184 {
1185 	const struct dat_walk_ops dat_reset_cmma_ops = {
1186 		.pte_entry = dat_reset_cmma_pte,
1187 	};
1188 
1189 	return _dat_walk_gfn_range(start, asce_end(asce), asce, &dat_reset_cmma_ops,
1190 				   DAT_WALK_IGN_HOLES, NULL);
1191 }
1192 
1193 struct dat_get_cmma_state {
1194 	gfn_t start;
1195 	gfn_t end;
1196 	unsigned int count;
1197 	u8 *values;
1198 	atomic64_t *remaining;
1199 };
1200 
1201 static long __dat_peek_cmma_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
1202 {
1203 	struct dat_get_cmma_state *state = walk->priv;
1204 	union pgste pgste;
1205 
1206 	pgste = pgste_get_lock(ptep);
1207 	state->values[gfn - walk->start] = pgste.usage | (pgste.nodat << 6);
1208 	pgste_set_unlock(ptep, pgste);
1209 	state->end = next;
1210 
1211 	return 0;
1212 }
1213 
1214 static long __dat_peek_cmma_crste(union crste *crstep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
1215 {
1216 	struct dat_get_cmma_state *state = walk->priv;
1217 
1218 	if (crstep->h.i)
1219 		state->end = min(walk->end, next);
1220 	return 0;
1221 }
1222 
1223 int dat_peek_cmma(gfn_t start, union asce asce, unsigned int *count, u8 *values)
1224 {
1225 	const struct dat_walk_ops ops = {
1226 		.pte_entry = __dat_peek_cmma_pte,
1227 		.pmd_entry = __dat_peek_cmma_crste,
1228 		.pud_entry = __dat_peek_cmma_crste,
1229 		.p4d_entry = __dat_peek_cmma_crste,
1230 		.pgd_entry = __dat_peek_cmma_crste,
1231 	};
1232 	struct dat_get_cmma_state state = { .values = values, };
1233 	int rc;
1234 
1235 	rc = _dat_walk_gfn_range(start, start + *count, asce, &ops, DAT_WALK_DEFAULT, &state);
1236 	*count = state.end >= start ? state.end - start : 0;
1237 	/* Return success if at least one value was saved, otherwise an error. */
1238 	return (rc == -EFAULT && *count > 0) ? 0 : rc;
1239 }
1240 
1241 static long __dat_get_cmma_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
1242 {
1243 	struct dat_get_cmma_state *state = walk->priv;
1244 	union pgste pgste;
1245 
1246 	if (state->start != -1) {
1247 		if ((gfn - state->end) > KVM_S390_MAX_BIT_DISTANCE)
1248 			return 1;
1249 		if (gfn - state->start >= state->count)
1250 			return 1;
1251 	}
1252 
1253 	if (!READ_ONCE(*pgste_of(ptep)).cmma_d)
1254 		return 0;
1255 
1256 	pgste = pgste_get_lock(ptep);
1257 	if (pgste.cmma_d) {
1258 		if (state->start == -1)
1259 			state->start = gfn;
1260 		pgste.cmma_d = 0;
1261 		atomic64_dec(state->remaining);
1262 		state->values[gfn - state->start] = pgste.usage | pgste.nodat << 6;
1263 		state->end = next;
1264 	}
1265 	pgste_set_unlock(ptep, pgste);
1266 	return 0;
1267 }
1268 
1269 int dat_get_cmma(union asce asce, gfn_t *start, unsigned int *count, u8 *values, atomic64_t *rem)
1270 {
1271 	const struct dat_walk_ops ops = { .pte_entry = __dat_get_cmma_pte, };
1272 	struct dat_get_cmma_state state = {
1273 		.remaining = rem,
1274 		.values = values,
1275 		.count = *count,
1276 		.start = -1,
1277 	};
1278 
1279 	_dat_walk_gfn_range(*start, asce_end(asce), asce, &ops, DAT_WALK_IGN_HOLES, &state);
1280 	/* If no dirty pages were found, wrap around and continue searching */
1281 	if (*start && state.start == -1)
1282 		_dat_walk_gfn_range(0, *start, asce, &ops, DAT_WALK_IGN_HOLES, &state);
1283 
1284 	if (state.start == -1) {
1285 		*count = 0;
1286 	} else {
1287 		*count = state.end - state.start;
1288 		*start = state.start;
1289 	}
1290 
1291 	return 0;
1292 }
1293 
1294 struct dat_set_cmma_state {
1295 	unsigned long mask;
1296 	const u8 *bits;
1297 };
1298 
1299 static long __dat_set_cmma_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
1300 {
1301 	struct dat_set_cmma_state *state = walk->priv;
1302 	union pgste pgste, tmp;
1303 
1304 	tmp.val = (state->bits[gfn - walk->start] << 24) & state->mask;
1305 
1306 	pgste = pgste_get_lock(ptep);
1307 	pgste.usage = tmp.usage;
1308 	pgste.nodat = tmp.nodat;
1309 	pgste_set_unlock(ptep, pgste);
1310 
1311 	return 0;
1312 }
1313 
1314 /**
1315  * dat_set_cmma_bits() - Set CMMA bits for a range of guest pages.
1316  * @mc: Cache used for allocations.
1317  * @asce: The ASCE of the guest.
1318  * @gfn: The guest frame of the fist page whose CMMA bits are to set.
1319  * @count: How many pages need to be processed.
1320  * @mask: Which PGSTE bits should be set.
1321  * @bits: Points to an array with the CMMA attributes.
1322  *
1323  * This function sets the CMMA attributes for the given pages. If the input
1324  * buffer has zero length, no action is taken, otherwise the attributes are
1325  * set and the mm->context.uses_cmm flag is set.
1326  *
1327  * Each byte in @bits contains new values for bits 32-39 of the PGSTE.
1328  * Currently, only the fields NT and US are applied.
1329  *
1330  * Return: %0 in case of success, a negative error value otherwise.
1331  */
1332 int dat_set_cmma_bits(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t gfn,
1333 		      unsigned long count, unsigned long mask, const uint8_t *bits)
1334 {
1335 	const struct dat_walk_ops ops = { .pte_entry = __dat_set_cmma_pte, };
1336 	struct dat_set_cmma_state state = { .mask = mask, .bits = bits, };
1337 	union crste *crstep;
1338 	union pte *ptep;
1339 	gfn_t cur;
1340 	int rc;
1341 
1342 	for (cur = ALIGN_DOWN(gfn, _PAGE_ENTRIES); cur < gfn + count; cur += _PAGE_ENTRIES) {
1343 		rc = dat_entry_walk(mc, cur, asce, DAT_WALK_ALLOC, TABLE_TYPE_PAGE_TABLE,
1344 				    &crstep, &ptep);
1345 		if (rc)
1346 			return rc;
1347 	}
1348 	return _dat_walk_gfn_range(gfn, gfn + count, asce, &ops, DAT_WALK_IGN_HOLES, &state);
1349 }
1350 #endif /* KVM_S390_MANAGES_S390_GUEST */
1351