1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4  */
5 
6 #include <arch_helpers.h>
7 #include <attestation_token.h>
8 #include <bitmap.h>
9 #include <buffer.h>
10 #include <gic.h>
11 #include <granule.h>
12 #include <memory_alloc.h>
13 #include <realm.h>
14 #include <ripas.h>
15 #include <smc.h>
16 #include <status.h>
17 #include <stddef.h>
18 #include <string.h>
19 #include <table.h>
20 
21 /*
22  * For prototyping we assume 4K pages
23  */
24 #define BLOCK_L2_SIZE		(GRANULE_SIZE * S2TTES_PER_S2TT)
25 
26 /*
27  * The maximum number of bits supported by the RMM for a stage 2 translation
28  * output address (including stage 2 table entries).
29  */
30 #define S2TTE_OA_BITS			48
31 
32 #define DESC_TYPE_MASK			0x3UL
33 #define S2TTE_L012_TABLE		0x3UL
34 #define S2TTE_L012_BLOCK		0x1UL
35 #define S2TTE_L3_PAGE			0x3UL
36 #define S2TTE_Lx_INVALID		0x0UL
37 
38 /*
39  * The following constants for the mapping attributes (S2_TTE_MEMATTR_*)
40  * assume that HCR_EL2.FWB is set.
41  */
42 #define S2TTE_MEMATTR_SHIFT		2
43 #define S2TTE_MEMATTR_MASK		(0x7UL << S2TTE_MEMATTR_SHIFT)
44 #define S2TTE_MEMATTR_FWB_NORMAL_WB	((1UL << 4) | (2UL << 2))
45 #define S2TTE_MEMATTR_FWB_RESERVED	((1UL << 4) | (0UL << 2))
46 
47 #define S2TTE_AP_SHIFT			6
48 #define S2TTE_AP_MASK			(3UL << S2TTE_AP_SHIFT)
49 #define S2TTE_AP_RW			(3UL << S2TTE_AP_SHIFT)
50 
51 #define S2TTE_SH_SHIFT			8
52 #define S2TTE_SH_MASK			(3UL << S2TTE_SH_SHIFT)
53 #define S2TTE_SH_NS			(0UL << S2TTE_SH_SHIFT)
54 #define S2TTE_SH_RESERVED		(1UL << S2TTE_SH_SHIFT)
55 #define S2TTE_SH_OS			(2UL << S2TTE_SH_SHIFT)
56 #define S2TTE_SH_IS			(3UL << S2TTE_SH_SHIFT)	/* Inner Shareable */
57 
58 /*
59  * We set HCR_EL2.FWB So we set bit[4] to 1 and bits[3:2] to 2 and force
60  * everyting to be Normal Write-Back
61  */
62 #define S2TTE_MEMATTR_FWB_NORMAL_WB	((1UL << 4) | (2UL << 2))
63 #define S2TTE_AF			(1UL << 10)
64 #define S2TTE_XN			(2UL << 53)
65 #define S2TTE_NS			(1UL << 55)
66 
67 #define S2TTE_ATTRS	(S2TTE_MEMATTR_FWB_NORMAL_WB | S2TTE_AP_RW | \
68 			S2TTE_SH_IS | S2TTE_AF)
69 
70 #define S2TTE_TABLE	S2TTE_L012_TABLE
71 #define S2TTE_BLOCK	(S2TTE_ATTRS | S2TTE_L012_BLOCK)
72 #define S2TTE_PAGE	(S2TTE_ATTRS | S2TTE_L3_PAGE)
73 #define S2TTE_BLOCK_NS	(S2TTE_NS | S2TTE_XN | S2TTE_AF | S2TTE_L012_BLOCK)
74 #define S2TTE_PAGE_NS	(S2TTE_NS | S2TTE_XN | S2TTE_AF | S2TTE_L3_PAGE)
75 #define S2TTE_INVALID	0
76 
77 /*
78  * The type of an S2TTE is one of the following:
79  *
80  * - Invalid
81  * - Valid page
82  * - Valid block
83  * - Table
84  *
85  * Within an invalid S2TTE for a Protected IPA, architecturally RES0 bits are
86  * used to encode the HIPAS and RIPAS.
87  *
88  * A valid S2TTE for a Protected IPA implies HIPAS=ASSIGNED and RIPAS=RAM.
89  *
90  * An invalid S2TTE for an Unprotected IPA implies HIPAS=INVALID_NS.
91  * A valid S2TTE for an Unprotected IPA implies HIPAS=VALID_NS.
92  *
93  * The following table defines the mapping from a (HIPAS, RIPAS) tuple to the
94  * value of the S2TTE.
95  *
96  * ------------------------------------------------------------------------------
97  * IPA		HIPAS		RIPAS		S2TTE value
98  * ==============================================================================
99  * Protected	UNASSIGNED	EMPTY		(S2TTE_INVALID_HIPAS_UNASSIGNED	|
100  *						 S2TTE_INVALID_RIPAS_EMPTY)
101  * Protected	UNASSIGNED	RAM		(S2TTE_INVALID_HIPAS_UNASSIGNED	|
102  *						 S2TTE_INVALID_RIPAS_RAM)
103  * Protected	ASSIGNED	EMPTY		(S2TTE_INVALID_HIPAS_ASSIGNED	|
104  *						 S2TTE_INVALID_RIPAS_EMPTY)
105  * Protected	ASSIGNED	RAM		Valid page / block with NS=0
106  * Protected	DESTROYED	*		S2TTE_INVALID_DESTROYED
107  * Unprotected	INVALID_NS	N/A		S2TTE_INVALID_UNPROTECTED
108  * Unprotected	VALID_NS	N/A		Valid page / block with NS=1
109  * ------------------------------------------------------------------------------
110  */
111 
112 #define S2TTE_INVALID_HIPAS_SHIFT	2
113 #define S2TTE_INVALID_HIPAS_WIDTH	4
114 #define S2TTE_INVALID_HIPAS_MASK	MASK(S2TTE_INVALID_HIPAS)
115 
116 #define S2TTE_INVALID_HIPAS_UNASSIGNED	(INPLACE(S2TTE_INVALID_HIPAS, 0))
117 #define S2TTE_INVALID_HIPAS_ASSIGNED	(INPLACE(S2TTE_INVALID_HIPAS, 1))
118 #define S2TTE_INVALID_HIPAS_DESTROYED	(INPLACE(S2TTE_INVALID_HIPAS, 2))
119 
120 #define S2TTE_INVALID_RIPAS_SHIFT	6
121 #define S2TTE_INVALID_RIPAS_WIDTH	1
122 #define S2TTE_INVALID_RIPAS_MASK	MASK(S2TTE_INVALID_RIPAS)
123 
124 #define S2TTE_INVALID_RIPAS_EMPTY	(INPLACE(S2TTE_INVALID_RIPAS, 0))
125 #define S2TTE_INVALID_RIPAS_RAM		(INPLACE(S2TTE_INVALID_RIPAS, 1))
126 
127 #define S2TTE_INVALID_DESTROYED		S2TTE_INVALID_HIPAS_DESTROYED
128 #define S2TTE_INVALID_UNPROTECTED	0x0UL
129 
130 #define NR_RTT_LEVELS	4
131 
132 /*
133  * Invalidates S2 TLB entries from [ipa, ipa + size] region tagged with `vmid`.
134  */
stage2_tlbi_ipa(const struct realm_s2_context * s2_ctx,unsigned long ipa,unsigned long size)135 static void stage2_tlbi_ipa(const struct realm_s2_context *s2_ctx,
136 			    unsigned long ipa,
137 			    unsigned long size)
138 {
139 	/*
140 	 * Notes:
141 	 *
142 	 * - This follows the description provided in the Arm ARM on
143 	 *   "Invalidation of TLB entries from stage 2 translations".
144 	 *
145 	 * - @TODO: Provide additional information to this primitive so that
146 	 *   we can utilize:
147 	 *   - The TTL level hint, see FEAT_TTL,
148 	 *   - Final level lookup only invalidation,
149 	 *   - Address range invalidation.
150 	 */
151 
152 	/*
153 	 * Save the current content of vttb_el2.
154 	 */
155 	unsigned long old_vttbr_el2 = read_vttbr_el2();
156 
157 	/*
158 	 * Make 'vmid' the `current vmid`. Note that the tlbi instructions
159 	 * bellow target the TLB entries that match the `current vmid`.
160 	 */
161 	write_vttbr_el2(INPLACE(VTTBR_EL2_VMID, s2_ctx->vmid));
162 	isb();
163 
164 	/*
165 	 * Invalidate entries in S2 TLB caches that
166 	 * match both `ipa` & the `current vmid`.
167 	 */
168 	while (size != 0UL) {
169 		tlbiipas2e1is(ipa >> 12);
170 		size -= GRANULE_SIZE;
171 		ipa += GRANULE_SIZE;
172 	}
173 	dsb(ish);
174 
175 	/*
176 	 * The architecture does not require TLB invalidation by IPA to affect
177 	 * combined Stage-1 + Stage-2 TLBs. Therefore we must invalidate all of
178 	 * Stage-1 (tagged with the `current vmid`) after invalidating Stage-2.
179 	 */
180 	tlbivmalle1is();
181 	dsb(ish);
182 	isb();
183 
184 	/*
185 	 * Restore the old content of vttb_el2.
186 	 */
187 	write_vttbr_el2(old_vttbr_el2);
188 	isb();
189 }
190 
191 /*
192  * Invalidate S2 TLB entries with "addr" IPA.
193  * Call this function after:
194  * 1.  A L3 page desc has been removed.
195  */
invalidate_page(const struct realm_s2_context * s2_ctx,unsigned long addr)196 void invalidate_page(const struct realm_s2_context *s2_ctx, unsigned long addr)
197 {
198 	stage2_tlbi_ipa(s2_ctx, addr, GRANULE_SIZE);
199 }
200 
201 /*
202  * Invalidate S2 TLB entries with "addr" IPA.
203  * Call this function after:
204  * 1.  A L2 block desc has been removed, or
205  * 2a. A L2 table desc has been removed, where
206  * 2b. All S2TTEs in L3 table that the L2 table desc was pointed to were invalid.
207  */
invalidate_block(const struct realm_s2_context * s2_ctx,unsigned long addr)208 void invalidate_block(const struct realm_s2_context *s2_ctx, unsigned long addr)
209 {
210 	stage2_tlbi_ipa(s2_ctx, addr, GRANULE_SIZE);
211 }
212 
213 /*
214  * Invalidate S2 TLB entries with "addr" IPA.
215  * Call this function after:
216  * 1a. A L2 table desc has been removed, where
217  * 1b. Some S2TTEs in the table that the L2 table desc was pointed to were valid.
218  */
invalidate_pages_in_block(const struct realm_s2_context * s2_ctx,unsigned long addr)219 void invalidate_pages_in_block(const struct realm_s2_context *s2_ctx, unsigned long addr)
220 {
221 	stage2_tlbi_ipa(s2_ctx, addr, BLOCK_L2_SIZE);
222 }
223 
224 /*
225  * Return the index of the entry describing @addr in the translation table at
226  * level @level.  This only works for non-concatenated page tables, so should
227  * not be called to get the index for the starting level.
228  *
229  * See the library pseudocode
230  * aarch64/translation/vmsa_addrcalc/AArch64.TTEntryAddress on which this is
231  * modeled.
232  */
s2_addr_to_idx(unsigned long addr,long level)233 static unsigned long s2_addr_to_idx(unsigned long addr, long level)
234 {
235 	int levels = RTT_PAGE_LEVEL - level;
236 	int lsb = levels * S2TTE_STRIDE + GRANULE_SHIFT;
237 
238 	addr >>= lsb;
239 	addr &= (1UL << S2TTE_STRIDE) - 1;
240 	return addr;
241 }
242 
243 /*
244  * Return the index of the entry describing @addr in the translation table
245  * starting level.  This may return an index >= S2TTES_PER_S2TT when the
246  * combination of @start_level and @ipa_bits implies concatenated
247  * stage 2 tables.
248  *
249  * See the library pseudocode
250  * aarch64/translation/vmsa_addrcalc/AArch64.S2SLTTEntryAddress on which
251  * this is modeled.
252  */
s2_sl_addr_to_idx(unsigned long addr,int start_level,unsigned long ipa_bits)253 static unsigned long s2_sl_addr_to_idx(unsigned long addr, int start_level,
254 				       unsigned long ipa_bits)
255 {
256 	int levels = RTT_PAGE_LEVEL - start_level;
257 	int lsb = levels * S2TTE_STRIDE + GRANULE_SHIFT;
258 
259 	addr &= (1UL << ipa_bits) - 1UL;
260 	addr >>= lsb;
261 	return addr;
262 }
263 
addr_level_mask(unsigned long addr,long level)264 static unsigned long addr_level_mask(unsigned long addr, long level)
265 {
266 	int levels = RTT_PAGE_LEVEL - level;
267 	unsigned int lsb = levels * S2TTE_STRIDE + GRANULE_SHIFT;
268 	unsigned int msb = S2TTE_OA_BITS - 1;
269 
270 	return addr & BIT_MASK_ULL(msb, lsb);
271 }
272 
table_entry_to_phys(unsigned long entry)273 static inline unsigned long table_entry_to_phys(unsigned long entry)
274 {
275 	return addr_level_mask(entry, RTT_PAGE_LEVEL);
276 }
277 
entry_is_table(unsigned long entry)278 static inline bool entry_is_table(unsigned long entry)
279 {
280 	return (entry & DESC_TYPE_MASK) == S2TTE_L012_TABLE;
281 }
282 
__table_get_entry(struct granule * g_tbl,unsigned long idx)283 static unsigned long __table_get_entry(struct granule *g_tbl,
284 				       unsigned long idx)
285 {
286 	unsigned long *table, entry;
287 
288 	table = granule_map(g_tbl, SLOT_RTT);
289 	entry = s2tte_read(&table[idx]);
290 	buffer_unmap(table);
291 
292 	return entry;
293 }
294 
__find_next_level_idx(struct granule * g_tbl,unsigned long idx)295 static struct granule *__find_next_level_idx(struct granule *g_tbl,
296 					     unsigned long idx)
297 {
298 	const unsigned long entry = __table_get_entry(g_tbl, idx);
299 
300 	if (!entry_is_table(entry)) {
301 		return NULL;
302 	}
303 
304 	return addr_to_granule(table_entry_to_phys(entry));
305 }
306 
__find_lock_next_level(struct granule * g_tbl,unsigned long map_addr,long level)307 static struct granule *__find_lock_next_level(struct granule *g_tbl,
308 					      unsigned long map_addr,
309 					      long level)
310 {
311 	const unsigned long idx = s2_addr_to_idx(map_addr, level);
312 	struct granule *g = __find_next_level_idx(g_tbl, idx);
313 
314 	if (g != NULL) {
315 		granule_lock(g, GRANULE_STATE_RTT);
316 	}
317 
318 	return g;
319 }
320 
321 /*
322  * Walk an RTT until level @level using @map_addr.
323  * @g_root is the root (level 0) table and must be locked before the call.
324  * @start_level is the initial lookup level used for the stage 2 translation
325  * tables which may depend on the configuration of the realm, factoring in the
326  * IPA size of the realm and the desired starting level (within the limits
327  * defined by the Armv8 VMSA including options for stage 2 table concatenation).
328  * The function uses hand-over-hand locking to avoid race conditions and allow
329  * concurrent access to RTT tree which is not part of the current walk; when a
330  * next level table is reached it is locked before releasing previously locked
331  * table.
332  * The walk stops when either:
333  * - The entry found is a leaf entry (not an RTT Table entry), or
334  * - Level @level is reached.
335  *
336  * On return:
337  * - rtt_walk::last_level is the last level that has been reached by the walk.
338  * - rtt_walk.g_llt points to the TABLE granule at level @rtt_walk::level.
339  *   The granule is locked.
340  * - rtt_walk::index is the entry index at rtt_walk.g_llt for @map_addr.
341  */
rtt_walk_lock_unlock(struct granule * g_root,int start_level,unsigned long ipa_bits,unsigned long map_addr,long level,struct rtt_walk * wi)342 void rtt_walk_lock_unlock(struct granule *g_root,
343 			  int start_level,
344 			  unsigned long ipa_bits,
345 			  unsigned long map_addr,
346 			  long level,
347 			  struct rtt_walk *wi)
348 {
349 	struct granule *g_tbls[NR_RTT_LEVELS] = { NULL };
350 	unsigned long sl_idx;
351 	int i, last_level;
352 
353 	assert(start_level >= MIN_STARTING_LEVEL);
354 	assert(level >= start_level);
355 	assert(map_addr < (1UL << ipa_bits));
356 	assert(wi != NULL);
357 
358 	/* Handle concatenated starting level (SL) tables */
359 	sl_idx = s2_sl_addr_to_idx(map_addr, start_level, ipa_bits);
360 	if (sl_idx >= S2TTES_PER_S2TT) {
361 		unsigned int tt_num = (sl_idx >> S2TTE_STRIDE);
362 		struct granule *g_concat_root = g_root + tt_num;
363 
364 		granule_lock(g_concat_root, GRANULE_STATE_RTT);
365 		granule_unlock(g_root);
366 		g_root = g_concat_root;
367 	}
368 
369 	g_tbls[start_level] = g_root;
370 	for (i = start_level; i < level; i++) {
371 		/*
372 		 * Lock next RTT level. Correct locking order is guaranteed
373 		 * because reference is obtained from a locked granule
374 		 * (previous level). Also, hand-over-hand locking/unlocking is
375 		 * used to avoid race conditions.
376 		 */
377 		g_tbls[i + 1] = __find_lock_next_level(g_tbls[i], map_addr, i);
378 		if (g_tbls[i + 1] == NULL) {
379 			last_level = i;
380 			goto out;
381 		}
382 		granule_unlock(g_tbls[i]);
383 	}
384 
385 	last_level = level;
386 out:
387 	wi->last_level = last_level;
388 	wi->g_llt = g_tbls[last_level];
389 	wi->index = s2_addr_to_idx(map_addr, last_level);
390 }
391 
392 /*
393  * Creates a value which can be OR'd with an s2tte to set RIPAS=@ripas.
394  */
s2tte_create_ripas(enum ripas ripas)395 unsigned long s2tte_create_ripas(enum ripas ripas)
396 {
397 	if (ripas == RMI_EMPTY) {
398 		return S2TTE_INVALID_RIPAS_EMPTY;
399 	}
400 	return S2TTE_INVALID_RIPAS_RAM;
401 }
402 
403 /*
404  * Creates an invalid s2tte with HIPAS=UNASSIGNED and RIPAS=@ripas.
405  */
s2tte_create_unassigned(enum ripas ripas)406 unsigned long s2tte_create_unassigned(enum ripas ripas)
407 {
408 	return S2TTE_INVALID_HIPAS_UNASSIGNED | s2tte_create_ripas(ripas);
409 }
410 
411 /*
412  * Creates an invalid s2tte with HIPAS=DESTROYED.
413  */
s2tte_create_destroyed(void)414 unsigned long s2tte_create_destroyed(void)
415 {
416 	return S2TTE_INVALID_DESTROYED;
417 }
418 
419 /*
420  * Creates an invalid s2tte with output address @pa, HIPAS=ASSIGNED and
421  * RIPAS=EMPTY, at level @level.
422  */
s2tte_create_assigned_empty(unsigned long pa,long level)423 unsigned long s2tte_create_assigned_empty(unsigned long pa, long level)
424 {
425 	assert(level >= RTT_MIN_BLOCK_LEVEL);
426 	assert(addr_is_level_aligned(pa, level));
427 	return (pa | S2TTE_INVALID_HIPAS_ASSIGNED | S2TTE_INVALID_RIPAS_EMPTY);
428 }
429 
430 /*
431  * Creates a page or block s2tte for a Protected IPA, with output address @pa.
432  */
s2tte_create_valid(unsigned long pa,long level)433 unsigned long s2tte_create_valid(unsigned long pa, long level)
434 {
435 	assert(level >= RTT_MIN_BLOCK_LEVEL);
436 	assert(addr_is_level_aligned(pa, level));
437 	if (level == RTT_PAGE_LEVEL) {
438 		return (pa | S2TTE_PAGE);
439 	}
440 	return (pa | S2TTE_BLOCK);
441 }
442 
443 /*
444  * Creates an invalid s2tte with HIPAS=INVALID_NS.
445  */
s2tte_create_invalid_ns(void)446 unsigned long s2tte_create_invalid_ns(void)
447 {
448 	return S2TTE_INVALID_UNPROTECTED;
449 }
450 
451 /*
452  * Creates a page or block s2tte for an Unprotected IPA at level @level.
453  *
454  * The following S2 TTE fields are provided through @s2tte argument:
455  * - The physical address
456  * - MemAttr
457  * - S2AP
458  * - Shareability
459  */
s2tte_create_valid_ns(unsigned long s2tte,long level)460 unsigned long s2tte_create_valid_ns(unsigned long s2tte, long level)
461 {
462 	assert(level >= RTT_MIN_BLOCK_LEVEL);
463 	if (level == RTT_PAGE_LEVEL) {
464 		return (s2tte | S2TTE_PAGE_NS);
465 	}
466 	return (s2tte | S2TTE_BLOCK_NS);
467 }
468 
469 /*
470  * Validate the portion of NS S2TTE that is provided by the host.
471  */
host_ns_s2tte_is_valid(unsigned long s2tte,long level)472 bool host_ns_s2tte_is_valid(unsigned long s2tte, long level)
473 {
474 	unsigned long mask = addr_level_mask(~0UL, level) |
475 			     S2TTE_MEMATTR_MASK |
476 			     S2TTE_AP_MASK |
477 			     S2TTE_SH_MASK;
478 
479 	/*
480 	 * Test that all fields that are not controlled by the host are zero
481 	 * and that the output address is correctly aligned. Note that
482 	 * the host is permitted to map any physical address outside PAR.
483 	 */
484 	if ((s2tte & ~mask) != 0UL) {
485 		return false;
486 	}
487 
488 	/*
489 	 * Only one value masked by S2TTE_MEMATTR_MASK is invalid/reserved.
490 	 */
491 	if ((s2tte & S2TTE_MEMATTR_MASK) == S2TTE_MEMATTR_FWB_RESERVED) {
492 		return false;
493 	}
494 
495 	/*
496 	 * Only one value masked by S2TTE_SH_MASK is invalid/reserved.
497 	 */
498 	if ((s2tte & S2TTE_SH_MASK) == S2TTE_SH_RESERVED) {
499 		return false;
500 	}
501 
502 	/*
503 	 * Note that all the values that are masked by S2TTE_AP_MASK are valid.
504 	 */
505 	return true;
506 }
507 
508 /*
509  * Returns the portion of NS S2TTE that is set by the host.
510  */
host_ns_s2tte(unsigned long s2tte,long level)511 unsigned long host_ns_s2tte(unsigned long s2tte, long level)
512 {
513 	unsigned long mask = addr_level_mask(~0UL, level) |
514 			     S2TTE_MEMATTR_MASK |
515 			     S2TTE_AP_MASK |
516 			     S2TTE_SH_MASK;
517 	return (s2tte & mask);
518 }
519 
520 /*
521  * Creates a table s2tte at level @level with output address @pa.
522  */
s2tte_create_table(unsigned long pa,long level)523 unsigned long s2tte_create_table(unsigned long pa, long level)
524 {
525 	assert(level < RTT_PAGE_LEVEL);
526 	assert(GRANULE_ALIGNED(pa));
527 
528 	return (pa | S2TTE_TABLE);
529 }
530 
531 /*
532  * Returns true if @s2tte has HIPAS=@hipas.
533  */
s2tte_has_hipas(unsigned long s2tte,unsigned long hipas)534 static bool s2tte_has_hipas(unsigned long s2tte, unsigned long hipas)
535 {
536 	unsigned long desc_type = s2tte & DESC_TYPE_MASK;
537 	unsigned long invalid_desc_hipas = s2tte & S2TTE_INVALID_HIPAS_MASK;
538 
539 	if ((desc_type != S2TTE_Lx_INVALID) || (invalid_desc_hipas != hipas)) {
540 		return false;
541 	}
542 	return true;
543 }
544 
545 /*
546  * Returns true if @s2tte has HIPAS=UNASSIGNED or HIPAS=INVALID_NS.
547  */
s2tte_is_unassigned(unsigned long s2tte)548 bool s2tte_is_unassigned(unsigned long s2tte)
549 {
550 	return s2tte_has_hipas(s2tte, S2TTE_INVALID_HIPAS_UNASSIGNED);
551 }
552 
553 /*
554  * Returns true if @s2tte has HIPAS=DESTROYED.
555  */
s2tte_is_destroyed(unsigned long s2tte)556 bool s2tte_is_destroyed(unsigned long s2tte)
557 {
558 	return s2tte_has_hipas(s2tte, S2TTE_INVALID_HIPAS_DESTROYED);
559 }
560 
561 /*
562  * Returns true if @s2tte has HIPAS=ASSIGNED.
563  */
s2tte_is_assigned(unsigned long s2tte,long level)564 bool s2tte_is_assigned(unsigned long s2tte, long level)
565 {
566 	(void)level;
567 
568 	return s2tte_has_hipas(s2tte, S2TTE_INVALID_HIPAS_ASSIGNED);
569 }
570 
s2tte_check(unsigned long s2tte,long level,unsigned long ns)571 static bool s2tte_check(unsigned long s2tte, long level, unsigned long ns)
572 {
573 	unsigned long desc_type;
574 
575 	if ((s2tte & S2TTE_NS) != ns) {
576 		return false;
577 	}
578 
579 	desc_type = s2tte & DESC_TYPE_MASK;
580 
581 	/* Only pages at L3 and valid blocks at L2 allowed */
582 	if (((level == RTT_PAGE_LEVEL) && (desc_type == S2TTE_L3_PAGE)) ||
583 	    ((level == RTT_MIN_BLOCK_LEVEL) && (desc_type == S2TTE_BLOCK))) {
584 		return true;
585 	}
586 
587 	return false;
588 }
589 
590 /*
591  * Returns true if @s2tte is a page or block s2tte, and NS=0.
592  */
s2tte_is_valid(unsigned long s2tte,long level)593 bool s2tte_is_valid(unsigned long s2tte, long level)
594 {
595 	return s2tte_check(s2tte, level, 0UL);
596 }
597 
598 /*
599  * Returns true if @s2tte is a page or block s2tte, and NS=1.
600  */
s2tte_is_valid_ns(unsigned long s2tte,long level)601 bool s2tte_is_valid_ns(unsigned long s2tte, long level)
602 {
603 	return s2tte_check(s2tte, level, S2TTE_NS);
604 }
605 
606 /*
607  * Returns true if @s2tte is a table at level @level.
608  */
s2tte_is_table(unsigned long s2tte,long level)609 bool s2tte_is_table(unsigned long s2tte, long level)
610 {
611 	unsigned long desc_type = s2tte & DESC_TYPE_MASK;
612 
613 	if ((level < RTT_PAGE_LEVEL) && (desc_type == S2TTE_TABLE)) {
614 		return true;
615 	}
616 
617 	return false;
618 }
619 
620 /*
621  * Returns RIPAS of @s2tte.
622  *
623  * Caller should ensure that HIPAS=UNASSIGNED or HIPAS=ASSIGNED.
624  * The s2tte must be not valid/invalid descriptor.
625  */
s2tte_get_ripas(unsigned long s2tte)626 enum ripas s2tte_get_ripas(unsigned long s2tte)
627 {
628 	unsigned long desc_ripas = s2tte & S2TTE_INVALID_RIPAS_MASK;
629 
630 	/*
631 	 * If valid s2tte descriptor is passed, then ensure S2AP[0]
632 	 * bit is 1 (S2AP is set to RW for lower EL), which corresponds
633 	 * to RIPAS_RAM (bit[6]) on a valid descriptor.
634 	 */
635 	if (((s2tte & DESC_TYPE_MASK) != S2TTE_Lx_INVALID) &&
636 	     (desc_ripas != S2TTE_INVALID_RIPAS_RAM)) {
637 		assert(false);
638 	}
639 
640 	if (desc_ripas == S2TTE_INVALID_RIPAS_EMPTY) {
641 		return RMI_EMPTY;
642 	}
643 
644 	return RMI_RAM;
645 }
646 
647 /*
648  * Populates @s2tt with s2ttes which have HIPAS=UNASSIGNED and RIPAS=@ripas.
649  *
650  * The granule is populated before it is made a table,
651  * hence, don't use s2tte_write for access.
652  */
s2tt_init_unassigned(unsigned long * s2tt,enum ripas ripas)653 void s2tt_init_unassigned(unsigned long *s2tt, enum ripas ripas)
654 {
655 	for (unsigned int i = 0U; i < S2TTES_PER_S2TT; i++) {
656 		s2tt[i] = s2tte_create_unassigned(ripas);
657 	}
658 
659 	dsb(ish);
660 }
661 
662 /*
663  * Populates @s2tt with s2ttes which have HIPAS=DESTROYED.
664  *
665  * The granule is populated before it is made a table,
666  * hence, don't use s2tte_write for access.
667  */
s2tt_init_destroyed(unsigned long * s2tt)668 void s2tt_init_destroyed(unsigned long *s2tt)
669 {
670 	for (unsigned int i = 0U; i < S2TTES_PER_S2TT; i++) {
671 		s2tt[i] = s2tte_create_destroyed();
672 	}
673 
674 	dsb(ish);
675 }
676 
s2tte_map_size(int level)677 unsigned long s2tte_map_size(int level)
678 {
679 	int levels, lsb;
680 
681 	assert(level <= RTT_PAGE_LEVEL);
682 
683 	levels = RTT_PAGE_LEVEL - level;
684 	lsb = levels * S2TTE_STRIDE + GRANULE_SHIFT;
685 	return 1UL << lsb;
686 }
687 
688 /*
689  * Populates @s2tt with HIPAS=ASSIGNED, RIPAS=EMPTY s2ttes that refer to a
690  * contiguous memory block starting at @pa, and mapped at level @level.
691  *
692  * The granule is populated before it is made a table,
693  * hence, don't use s2tte_write for access.
694  */
s2tt_init_assigned_empty(unsigned long * s2tt,unsigned long pa,long level)695 void s2tt_init_assigned_empty(unsigned long *s2tt, unsigned long pa, long level)
696 {
697 	const unsigned long map_size = s2tte_map_size(level);
698 	unsigned int i;
699 
700 	for (i = 0U; i < S2TTES_PER_S2TT; i++) {
701 		s2tt[i] = s2tte_create_assigned_empty(pa, level);
702 		pa += map_size;
703 	}
704 	dsb(ish);
705 }
706 
707 /*
708  * Populates @s2tt with HIPAS=VALID, RIPAS=@ripas s2ttes that refer to a
709  * contiguous memory block starting at @pa, and mapped at level @level.
710  *
711  * The granule is populated before it is made a table,
712  * hence, don't use s2tte_write for access.
713  */
s2tt_init_valid(unsigned long * s2tt,unsigned long pa,long level)714 void s2tt_init_valid(unsigned long *s2tt, unsigned long pa, long level)
715 {
716 	const unsigned long map_size = s2tte_map_size(level);
717 	unsigned int i;
718 
719 	for (i = 0U; i < S2TTES_PER_S2TT; i++) {
720 		s2tt[i] = s2tte_create_valid(pa, level);
721 		pa += map_size;
722 	}
723 	dsb(ish);
724 }
725 
726 /*
727  * Populates @s2tt with HIPAS=VALID_NS, RIPAS=@ripas s2ttes that refer to a
728  * contiguous memory block starting at @pa, and mapped at level @level.
729  *
730  * The granule is populated before it is made a table,
731  * hence, don't use s2tte_write for access.
732  */
s2tt_init_valid_ns(unsigned long * s2tt,unsigned long pa,long level)733 void s2tt_init_valid_ns(unsigned long *s2tt, unsigned long pa, long level)
734 {
735 	const unsigned long map_size = s2tte_map_size(level);
736 	unsigned int i;
737 
738 	for (i = 0U; i < S2TTES_PER_S2TT; i++) {
739 		s2tt[i] = s2tte_create_valid_ns(pa, level);
740 		pa += map_size;
741 	}
742 	dsb(ish);
743 }
744 
745 /* Returns physical address of a page entry or block */
s2tte_pa(unsigned long s2tte,long level)746 unsigned long s2tte_pa(unsigned long s2tte, long level)
747 {
748 	if (s2tte_is_unassigned(s2tte) || s2tte_is_destroyed(s2tte) ||
749 	    s2tte_is_table(s2tte, level)) {
750 		assert(false);
751 	}
752 	return addr_level_mask(s2tte, level);
753 }
754 
755 /* Returns physical address of a table entry */
s2tte_pa_table(unsigned long s2tte,long level)756 unsigned long s2tte_pa_table(unsigned long s2tte, long level)
757 {
758 	assert(s2tte_is_table(s2tte, level));
759 	return addr_level_mask(s2tte, RTT_PAGE_LEVEL);
760 }
761 
addr_is_level_aligned(unsigned long addr,long level)762 bool addr_is_level_aligned(unsigned long addr, long level)
763 {
764 	return (addr == addr_level_mask(addr, level));
765 }
766 
767 typedef bool (*s2tte_type_checker)(unsigned long s2tte);
768 
__table_is_uniform_block(unsigned long * table,s2tte_type_checker s2tte_is_x,enum ripas * ripas_ptr)769 static bool __table_is_uniform_block(unsigned long *table,
770 			      s2tte_type_checker s2tte_is_x,
771 			      enum ripas *ripas_ptr)
772 {
773 	unsigned long s2tte = s2tte_read(&table[0]);
774 	enum ripas ripas;
775 	unsigned int i;
776 
777 	if (!s2tte_is_x(s2tte)) {
778 		return false;
779 	}
780 
781 	if (ripas_ptr != NULL) {
782 		ripas = s2tte_get_ripas(s2tte);
783 	}
784 
785 	for (i = 1U; i < S2TTES_PER_S2TT; i++) {
786 		s2tte = s2tte_read(&table[i]);
787 
788 		if (!s2tte_is_x(s2tte)) {
789 			return false;
790 		}
791 
792 		if ((ripas_ptr != NULL) &&
793 		    (s2tte_get_ripas(s2tte) != ripas)) {
794 			return false;
795 		}
796 	}
797 
798 	if (ripas_ptr != NULL) {
799 		*ripas_ptr = ripas;
800 	}
801 
802 	return true;
803 }
804 
805 /*
806  * Returns true if all s2ttes in @table have HIPAS=UNASSIGNED and
807  * have the same RIPAS.
808  *
809  * If return value is true, the RIPAS value is returned in @ripas.
810  */
table_is_unassigned_block(unsigned long * table,enum ripas * ripas)811 bool table_is_unassigned_block(unsigned long *table, enum ripas *ripas)
812 {
813 	return __table_is_uniform_block(table, s2tte_is_unassigned, ripas);
814 }
815 
816 /*
817  * Returns true if all s2ttes in @table have HIPAS=DESTROYED.
818  */
table_is_destroyed_block(unsigned long * table)819 bool table_is_destroyed_block(unsigned long *table)
820 {
821 	return __table_is_uniform_block(table, s2tte_is_destroyed, NULL);
822 }
823 
824 typedef bool (*s2tte_type_level_checker)(unsigned long s2tte, long level);
825 
__table_maps_block(unsigned long * table,long level,s2tte_type_level_checker s2tte_is_x)826 static bool __table_maps_block(unsigned long *table,
827 			       long level,
828 			       s2tte_type_level_checker s2tte_is_x)
829 {
830 	unsigned long base_pa;
831 	unsigned long map_size = s2tte_map_size(level);
832 	unsigned long s2tte = s2tte_read(&table[0]);
833 	unsigned int i;
834 
835 	if (!s2tte_is_x(s2tte, level)) {
836 		return false;
837 	}
838 
839 	base_pa = s2tte_pa(s2tte, level);
840 	if (!addr_is_level_aligned(base_pa, level - 1L)) {
841 		return false;
842 	}
843 
844 	for (i = 1U; i < S2TTES_PER_S2TT; i++) {
845 		unsigned long expected_pa = base_pa + (i * map_size);
846 
847 		s2tte = s2tte_read(&table[i]);
848 
849 		if (!s2tte_is_x(s2tte, level)) {
850 			return false;
851 		}
852 
853 		if (s2tte_pa(s2tte, level) != expected_pa) {
854 			return false;
855 		}
856 	}
857 
858 	return true;
859 }
860 
861 /*
862  * Returns true if all s2ttes in @table have HIPAS=ASSIGNED
863  * and refer to a contiguous block of granules aligned to @level - 1.
864  */
table_maps_assigned_block(unsigned long * table,long level)865 bool table_maps_assigned_block(unsigned long *table, long level)
866 {
867 	return __table_maps_block(table, level, s2tte_is_assigned);
868 }
869 
870 /*
871  * Returns true if all s2ttes in @table have HIPAS=VALID and
872  * refer to a contiguous block of granules aligned to @level - 1.
873  */
table_maps_valid_block(unsigned long * table,long level)874 bool table_maps_valid_block(unsigned long *table, long level)
875 {
876 	return __table_maps_block(table, level, s2tte_is_valid);
877 }
878 
879 /*
880  * Returns true if all s2ttes in @table have HIPAS=VALID_NS and
881  * refer to a contiguous block of granules aligned to @level - 1.
882  */
table_maps_valid_ns_block(unsigned long * table,long level)883 bool table_maps_valid_ns_block(unsigned long *table, long level)
884 {
885 	return __table_maps_block(table, level, s2tte_is_valid_ns);
886 }
887