xref: /linux/include/linux/arm-rmi-cmds.h (revision 303bff3637d13f0ecbb280c7cb403470c440a2a6)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2026 ARM Ltd.
4  */
5 
6 #ifndef __LINUX_ARM_RMI_CMDS_H_
7 #define __LINUX_ARM_RMI_CMDS_H_
8 
9 #include <linux/arm-smccc-rmi.h>
10 #include <linux/bug.h>
11 #include <linux/gfp.h>
12 #include <linux/processor.h>
13 #include <linux/string.h>
14 #include <linux/types.h>
15 
16 #define RMI_MAX_ADDR_LIST	256
17 
18 struct rmi_sro_state {
19 	struct arm_smccc_1_2_regs regs;
20 	int addr_count;
21 	unsigned long addr_list[RMI_MAX_ADDR_LIST];
22 };
23 
24 #define RMM_BLOCKED_RETRY_COUNT		2
25 /*
26  * rmi_smccc_invoke: Invoke the RMI call and return the results, retrying the
27  * command when status is RMI_BUSY. If we encounter RMI_BLOCKED, we retry
28  * it one more time before we give up. The caller is supposed to handle the
29  * result and reissue if required.
30  *
31  * We don't expect to see RMI_BLOCKED on a practical system, except when
32  * there are parallel requests that results in long standing operation,
33  * with one blocking the other.
34  *
35  * @regs: Input parameters filled in. Updated with the output results
36  * after the call.
37  */
rmi_smccc_invoke(struct arm_smccc_1_2_regs * regs)38 static inline void rmi_smccc_invoke(struct arm_smccc_1_2_regs *regs)
39 {
40 	struct arm_smccc_1_2_regs args = *regs;
41 	long status;
42 	int i = 0;
43 
44 	while (i < RMM_BLOCKED_RETRY_COUNT) {
45 		arm_smccc_1_2_smc(&args, regs);
46 
47 		status = RMI_RESULT_STATUS(regs->a0);
48 		if (status != RMI_BUSY && status != RMI_BLOCKED)
49 			break;
50 		if (status == RMI_BLOCKED)
51 			i++;
52 		cpu_relax();
53 	}
54 }
55 
56 /*
57  * rmi_smccc_invoke_once: Invoke the RMI call and return the results. Do not
58  * retry the command. Let the caller deal with RMI_BUSY or RMI_BLOCKED.
59  *
60  * @regs: Input parameters filled in. Updated with the output results
61  * after the call.
62  */
rmi_smccc_invoke_once(struct arm_smccc_1_2_regs * regs)63 static __always_inline void rmi_smccc_invoke_once(struct arm_smccc_1_2_regs *regs)
64 {
65 	arm_smccc_1_2_smc(regs, regs);
66 }
67 
68 unsigned long rmi_feat_reg(unsigned int index);
69 
70 int rmi_delegate_range(phys_addr_t phys, unsigned long size,
71 		       phys_addr_t *out_phys);
72 int rmi_undelegate_range(phys_addr_t phys, unsigned long size);
73 int rmi_free_delegated_page(phys_addr_t phys);
74 
rmi_delegate_page(phys_addr_t phys)75 static inline int rmi_delegate_page(phys_addr_t phys)
76 {
77 	return rmi_delegate_range(phys, PAGE_SIZE, NULL);
78 }
79 
rmi_undelegate_page(phys_addr_t phys)80 static inline int rmi_undelegate_page(phys_addr_t phys)
81 {
82 	return rmi_undelegate_range(phys, PAGE_SIZE);
83 }
84 
85 long rmi_sro_memxfer_execute(struct rmi_sro_state *sro, gfp_t gfp);
86 void rmi_sro_free(struct rmi_sro_state *sro);
87 long rmi_sro_execute(struct arm_smccc_1_2_regs *regs);
88 
89 /*
90  * Resetting the addr_count is sufficient to ignore the addr_list contents.
91  */
92 #define rmi_sro_memxfer_cmd(sro, gfp, ...) ({				\
93 	struct rmi_sro_state *__sro = (sro);				\
94 	__sro->addr_count = 0;						\
95 	__sro->regs = (struct arm_smccc_1_2_regs){ __VA_ARGS__ };	\
96 	long __ret = rmi_sro_memxfer_execute(__sro, gfp);		\
97 	rmi_sro_free(__sro);						\
98 	__ret;								\
99 })
100 
101 #ifdef CONFIG_ARM_RMM_RMI
102 
103 bool is_rmm_active(void);
104 bool is_rmi_available(void);
105 
106 #else
107 
is_rmm_active(void)108 static inline bool is_rmm_active(void)
109 {
110 	return false;
111 }
112 
is_rmi_available(void)113 static inline bool is_rmi_available(void)
114 {
115 	return false;
116 }
117 #endif	/* CONFIG_ARM_RMM_RMI */
118 
119 /**
120  * rmi_rtt_data_map_init() - Create a mapping at protected IPA, copying contents
121  *			     from a given non-secure source granule.
122  * @rd: PA of the RD
123  * @data: PA of the target granule mapped in the guest
124  * @ipa: IPA at which the granule @data will be mapped in the guest
125  * @src: PA of the source granule with contents
126  * @flags: RMI_MEASURE_CONTENT if the contents should be measured
127  *
128  * Create a mapping from Protected IPA space to conventional memory, copying
129  * contents from a Non-secure Granule provided by the caller.
130  *
131  * Return: 0 on success, positive RMI result code or negative Linux error code
132  */
rmi_rtt_data_map_init(unsigned long rd,unsigned long data,unsigned long ipa,unsigned long src,unsigned long flags)133 static inline long rmi_rtt_data_map_init(unsigned long rd, unsigned long data,
134 					 unsigned long ipa, unsigned long src,
135 					 unsigned long flags)
136 {
137 	struct arm_smccc_1_2_regs regs = {
138 		SMC_RMI_RTT_DATA_MAP_INIT, rd, data, ipa, src, flags
139 	};
140 
141 	return rmi_sro_execute(&regs);
142 }
143 
144 /**
145  * rmi_rtt_data_map() - Create mappings in protected IPA range with unknown contents
146  * @rd: PA of the RD
147  * @base: Base of the target IPA range
148  * @top: Top of the target IPA range
149  * @flags: Flags
150  * @oaddr: Output address set descriptor
151  * @out_top: Top address of range which was processed.
152  *
153  * Return: 0 on success, positive RMI result code or negative Linux error code.
154  * NOTE: out_top is only valid with ret == RMI_SUCCESS
155  */
rmi_rtt_data_map(unsigned long rd,unsigned long base,unsigned long top,unsigned long flags,unsigned long oaddr,unsigned long * out_top)156 static inline long rmi_rtt_data_map(unsigned long rd,
157 				    unsigned long base,
158 				    unsigned long top,
159 				    unsigned long flags,
160 				    unsigned long oaddr,
161 				    unsigned long *out_top)
162 {
163 	struct arm_smccc_1_2_regs regs = {
164 		SMC_RMI_RTT_DATA_MAP, rd, base, top, flags, oaddr
165 	};
166 	long ret;
167 
168 	ret = rmi_sro_execute(&regs);
169 
170 	if (ret == RMI_SUCCESS && out_top)
171 		*out_top = regs.a1;
172 
173 	return ret;
174 }
175 
176 /**
177  * rmi_rtt_data_unmap() - Remove mappings to conventional memory at a protected
178  *			  IPA range
179  * @rd: PA of the RD
180  * @base: Base of the target IPA range
181  * @top: Top of the target IPA range
182  * @flags: Flags
183  * @oaddr: Output address set descriptor
184  * @out_top: Returns top IPA of range which has been unmapped
185  * @out_range: Output address range
186  * @out_count: Number of entries in output address list
187  *
188  * Removes mappings to convention memory with a target Protected IPA range.
189  *
190  * Return: 0 on success, positive RMI result code or negative Linux error code
191  * NOTE: out_top is only valid with ret == RMI_SUCCESS
192  */
rmi_rtt_data_unmap(unsigned long rd,unsigned long base,unsigned long top,unsigned long flags,unsigned long oaddr,unsigned long * out_top,unsigned long * out_range,unsigned long * out_count)193 static inline long rmi_rtt_data_unmap(unsigned long rd,
194 				      unsigned long base,
195 				      unsigned long top,
196 				      unsigned long flags,
197 				      unsigned long oaddr,
198 				      unsigned long *out_top,
199 				      unsigned long *out_range,
200 				      unsigned long *out_count)
201 {
202 	struct arm_smccc_1_2_regs regs = {
203 		SMC_RMI_RTT_DATA_UNMAP, rd, base, top, flags, oaddr
204 	};
205 	long ret;
206 
207 	ret = rmi_sro_execute(&regs);
208 
209 	if (ret != RMI_SUCCESS)
210 		return ret;
211 
212 	if (out_top)
213 		*out_top = regs.a1;
214 	if (out_range)
215 		*out_range = regs.a2;
216 	if (out_count)
217 		*out_count = regs.a3;
218 
219 	return RMI_SUCCESS;
220 }
221 
222 /**
223  * rmi_psci_complete() - Complete pending PSCI command
224  * @calling_rec: PA of the calling REC
225  * @status: Status of the PSCI request
226  *
227  * Completes a pending PSCI command.
228  *
229  * Return: RMI return code
230  */
rmi_psci_complete(unsigned long calling_rec,unsigned long status)231 static inline long rmi_psci_complete(unsigned long calling_rec,
232 				     unsigned long status)
233 {
234 	struct arm_smccc_1_2_regs regs = {
235 		SMC_RMI_PSCI_COMPLETE, calling_rec, status,
236 	};
237 
238 	rmi_smccc_invoke(&regs);
239 	return regs.a0;
240 }
241 
242 /**
243  * rmi_realm_activate() - Activate a realm
244  * @rd: PA of the RD
245  *
246  * Mark a realm as Active, signalling that creation is completed, allowing
247  * execution of the realm.
248  *
249  * Return: RMI return code
250  */
rmi_realm_activate(unsigned long rd)251 static inline long rmi_realm_activate(unsigned long rd)
252 {
253 	struct arm_smccc_1_2_regs regs = {
254 		SMC_RMI_REALM_ACTIVATE, rd,
255 	};
256 
257 	rmi_smccc_invoke(&regs);
258 	return regs.a0;
259 }
260 
261 /**
262  * rmi_realm_create() - Create a realm
263  * @rd: PA of the RD
264  * @params: PA of realm parameters
265  * @sro: Preallocated SRO context
266  *
267  * Create a new realm using the given parameters.
268  *
269  * Return: 0 on success, positive RMI result code or negative Linux error code
270  */
rmi_realm_create(unsigned long rd,unsigned long params,struct rmi_sro_state * sro)271 static inline long rmi_realm_create(unsigned long rd, unsigned long params,
272 				    struct rmi_sro_state *sro)
273 {
274 	return rmi_sro_memxfer_cmd(sro, GFP_KERNEL,
275 				   SMC_RMI_REALM_CREATE, rd, params);
276 }
277 
278 /**
279  * rmi_realm_terminate() - Terminate a realm
280  * @rd: PA of the RD
281  * @sro: Preallocated SRO context
282  *
283  * Terminates a realm, moving it into a ZOMBIE state
284  *
285  * Return: 0 on success, positive RMI result code or negative Linux error code
286  */
rmi_realm_terminate(unsigned long rd,struct rmi_sro_state * sro)287 static inline long rmi_realm_terminate(unsigned long rd,
288 				       struct rmi_sro_state *sro)
289 {
290 	return rmi_sro_memxfer_cmd(sro, GFP_KERNEL,
291 				   SMC_RMI_REALM_TERMINATE, rd);
292 }
293 
294 /**
295  * rmi_realm_destroy() - Destroy a realm
296  * @rd: PA of the RD
297  * @sro: Preallocated SRO context
298  *
299  * Destroys a realm, all objects belonging to the realm must be destroyed first.
300  *
301  * Return: 0 on success, positive RMI result code or negative Linux error code
302  */
rmi_realm_destroy(unsigned long rd,struct rmi_sro_state * sro)303 static inline long rmi_realm_destroy(unsigned long rd,
304 				     struct rmi_sro_state *sro)
305 {
306 	return rmi_sro_memxfer_cmd(sro, GFP_KERNEL,
307 				   SMC_RMI_REALM_DESTROY, rd);
308 }
309 
310 /**
311  * rmi_rec_create() - Create a REC
312  * @rd: PA of the RD
313  * @rec: PA of the target REC
314  * @params: PA of REC parameters
315  * @sro: Allocated SRO context to be used
316  *
317  * Create a REC using the parameters specified in the struct rec_params pointed
318  * to by @params.
319  *
320  * Return: 0 on success, positive RMI result code or negative Linux error code
321  */
rmi_rec_create(unsigned long rd,unsigned long rec,unsigned long params,struct rmi_sro_state * sro)322 static inline long rmi_rec_create(unsigned long rd,
323 				  unsigned long rec,
324 				  unsigned long params,
325 				  struct rmi_sro_state *sro)
326 {
327 	return rmi_sro_memxfer_cmd(sro, GFP_KERNEL,
328 				   SMC_RMI_REC_CREATE, rd, rec, params);
329 }
330 
331 /**
332  * rmi_rec_destroy() - Destroy a REC
333  * @rec: PA of the target REC
334  * @sro: Allocated SRO context to be used
335  *
336  * Destroys a REC. The REC must not be running.
337  *
338  * Return: 0 on success, positive RMI result code or negative Linux error code
339  */
rmi_rec_destroy(unsigned long rec,struct rmi_sro_state * sro)340 static __always_inline long rmi_rec_destroy(unsigned long rec,
341 					    struct rmi_sro_state *sro)
342 {
343 	return rmi_sro_memxfer_cmd(sro, GFP_KERNEL, SMC_RMI_REC_DESTROY, rec);
344 }
345 
346 /**
347  * rmi_rec_enter() - Enter a REC
348  * @rec: PA of the target REC
349  * @run_ptr: PA of RecRun structure
350  *
351  * Starts (or continues) execution within a REC.
352  *
353  * Return: RMI result
354  */
rmi_rec_enter(unsigned long rec,unsigned long run_ptr)355 static __always_inline long rmi_rec_enter(unsigned long rec, unsigned long run_ptr)
356 {
357 	struct arm_smccc_1_2_regs regs = {
358 		SMC_RMI_REC_ENTER, rec, run_ptr,
359 	};
360 
361 	rmi_smccc_invoke_once(&regs);
362 	return regs.a0;
363 }
364 
365 /**
366  * rmi_rtt_create() - Creates an RTT
367  * @rd: PA of the RD
368  * @rtt: PA of the target RTT
369  * @ipa: Base of the IPA range described by the RTT
370  * @level: Depth of the RTT within the tree
371  *
372  * Creates an RTT (Realm Translation Table) at the specified level for the
373  * translation of the specified address within the realm.
374  *
375  * Return: 0 on success, positive RMI result code or negative Linux error code
376  */
rmi_rtt_create(unsigned long rd,unsigned long rtt,unsigned long ipa,long level)377 static inline long rmi_rtt_create(unsigned long rd, unsigned long rtt,
378 				  unsigned long ipa, long level)
379 {
380 	struct arm_smccc_1_2_regs regs = {
381 		SMC_RMI_RTT_CREATE, rd, rtt, ipa, level
382 	};
383 
384 	return rmi_sro_execute(&regs);
385 }
386 
387 /**
388  * rmi_rtt_destroy() - Destroy an RTT
389  * @rd: PA of the RD
390  * @ipa: Base of the IPA range described by the RTT
391  * @level: RTT level
392  * @out_rtt: Pointer to write the PA of the RTT which was destroyed
393  * @out_top: Pointer to write the top IPA of non-live RTT entries, from entry
394  * at which the RTT walk terminated.
395  *
396  * Destroys an RTT. The RTT must be non-live, i.e. none of the entries in the
397  * table are in ASSIGNED or TABLE state.
398  *
399  * Return: 0 on success, positive RMI result code or negative Linux error code.
400  */
rmi_rtt_destroy(unsigned long rd,unsigned long ipa,long level,unsigned long * out_rtt,unsigned long * out_top)401 static inline long rmi_rtt_destroy(unsigned long rd,
402 				   unsigned long ipa,
403 				   long level,
404 				   unsigned long *out_rtt,
405 				   unsigned long *out_top)
406 {
407 	struct arm_smccc_1_2_regs regs = {
408 		SMC_RMI_RTT_DESTROY, rd, ipa, level
409 	};
410 	long ret = rmi_sro_execute(&regs);
411 
412 	switch (RMI_RESULT_STATUS(ret)) {
413 	case RMI_SUCCESS:
414 		if (out_rtt)
415 			*out_rtt = regs.a1;
416 		fallthrough;
417 	case RMI_ERROR_RTT:
418 		if (out_top)
419 			*out_top = regs.a2;
420 		break;
421 	default:
422 		break;
423 	}
424 
425 	return ret;
426 }
427 
428 /**
429  * rmi_rtt_fold() - Fold an RTT
430  * @rd: PA of the RD
431  * @ipa: Base of the IPA range described by the RTT
432  * @level: Depth of the RTT within the tree
433  * @out_rtt: Pointer to write the PA of the RTT which was destroyed
434  *
435  * Folds an RTT. If all entries with the RTT are 'homogeneous' the RTT can be
436  * folded into the parent and the RTT destroyed.
437  *
438  * Return: 0 on success, positive RMI result code or negative Linux error code
439  */
rmi_rtt_fold(unsigned long rd,unsigned long ipa,long level,unsigned long * out_rtt)440 static inline long rmi_rtt_fold(unsigned long rd, unsigned long ipa,
441 				long level, unsigned long *out_rtt)
442 {
443 	struct arm_smccc_1_2_regs regs = {
444 		SMC_RMI_RTT_FOLD, rd, ipa, level
445 	};
446 	long ret = rmi_sro_execute(&regs);
447 
448 	if (ret == RMI_SUCCESS && out_rtt)
449 		*out_rtt = regs.a1;
450 
451 	return ret;
452 }
453 
454 /**
455  * rmi_rtt_init_ripas() - Set RIPAS for new realm
456  * @rd: PA of the RD
457  * @base: Base of target IPA region
458  * @top: Top of target IPA region
459  * @out_top: Top IPA of range whose RIPAS was modified
460  *
461  * Sets the RIPAS of a target IPA range to RAM, for a realm in the NEW state.
462  *
463  * Return: 0 on success, positive RMI result code or negative Linux error code
464  */
rmi_rtt_init_ripas(unsigned long rd,unsigned long base,unsigned long top,unsigned long * out_top)465 static inline long rmi_rtt_init_ripas(unsigned long rd, unsigned long base,
466 				      unsigned long top, unsigned long *out_top)
467 {
468 	struct arm_smccc_1_2_regs regs = {
469 		SMC_RMI_RTT_INIT_RIPAS, rd, base, top
470 	};
471 	long ret = rmi_sro_execute(&regs);
472 
473 	if (ret == RMI_SUCCESS && out_top)
474 		*out_top = regs.a1;
475 
476 	return ret;
477 }
478 
479 /**
480  * rmi_rtt_unprot_map() - Map unprotected granules into a realm
481  * @rd: PA of the RD
482  * @base: Base IPA of the mapping
483  * @top: Top of the target IPA range
484  * @flags: Flags
485  * @oaddr: Output address set descriptor
486  * @out_top: Top IPA of range which has been mapped
487  *
488  * Create mappings to memory within a target unprotected IPA range.
489  *
490  * Return: 0 on success, positive RMI result code or negative Linux error code
491  */
rmi_rtt_unprot_map(unsigned long rd,unsigned long base,unsigned long top,unsigned long flags,unsigned long oaddr,unsigned long * out_top)492 static inline long rmi_rtt_unprot_map(unsigned long rd,
493 				      unsigned long base,
494 				      unsigned long top,
495 				      unsigned long flags,
496 				      unsigned long oaddr,
497 				      unsigned long *out_top)
498 {
499 	struct arm_smccc_1_2_regs regs = {
500 		SMC_RMI_RTT_UNPROT_MAP, rd, base, top, flags, oaddr
501 	};
502 	long ret = rmi_sro_execute(&regs);
503 
504 	if (ret == RMI_SUCCESS && out_top)
505 		*out_top = regs.a1;
506 
507 	return ret;
508 }
509 
510 /**
511  * rmi_rtt_set_ripas() - Set RIPAS for an running realm
512  * @rd: PA of the RD
513  * @rec: PA of the REC making the request
514  * @base: Base of target IPA region
515  * @top: Top of target IPA region
516  * @out_top: Pointer to write top IPA of range whose RIPAS was modified
517  *
518  * Completes a request made by the realm to change the RIPAS of a target IPA
519  * range.
520  *
521  * Return: 0 on success, positive RMI result code or negative Linux error code
522  */
rmi_rtt_set_ripas(unsigned long rd,unsigned long rec,unsigned long base,unsigned long top,unsigned long * out_top)523 static inline long rmi_rtt_set_ripas(unsigned long rd, unsigned long rec,
524 				     unsigned long base, unsigned long top,
525 				     unsigned long *out_top)
526 {
527 	struct arm_smccc_1_2_regs regs = {
528 		SMC_RMI_RTT_SET_RIPAS, rd, rec, base, top
529 	};
530 	long ret = rmi_sro_execute(&regs);
531 
532 	if (ret == RMI_SUCCESS && out_top)
533 		*out_top = regs.a1;
534 
535 	return ret;
536 }
537 
538 /**
539  * rmi_rtt_unprot_unmap() - Remove mappings within an unprotected IPA range
540  * @rd: PA of the RD
541  * @base: Base IPA of the mapping
542  * @top: Top of the target IPA range
543  * @flags: Flags
544  * @oaddr: Output address set descriptor
545  * @out_top: Top IPA which has been unmapped
546  * @out_range: Output address range
547  * @out_count: Number of entries in output address list
548  *
549  * Removes mappings to memory within a target unprotected IPA range.
550  *
551  * Return: 0 on success, positive RMI result code or negative Linux error code
552  * NOTE: out_top is only valid with ret == RMI_SUCCESS.
553  */
rmi_rtt_unprot_unmap(unsigned long rd,unsigned long base,unsigned long top,unsigned long flags,unsigned long oaddr,unsigned long * out_top,unsigned long * out_range,unsigned long * out_count)554 static inline long rmi_rtt_unprot_unmap(unsigned long rd,
555 					unsigned long base,
556 					unsigned long top,
557 					unsigned long flags,
558 					unsigned long oaddr,
559 					unsigned long *out_top,
560 					unsigned long *out_range,
561 					unsigned long *out_count)
562 {
563 	struct arm_smccc_1_2_regs regs = {
564 		SMC_RMI_RTT_UNPROT_UNMAP, rd, base, top, flags, oaddr
565 	};
566 	long ret = rmi_sro_execute(&regs);
567 
568 	if (ret != RMI_SUCCESS)
569 		return ret;
570 
571 	if (out_top)
572 		*out_top = regs.a1;
573 	if (out_range)
574 		*out_range = regs.a2;
575 	if (out_count)
576 		*out_count = regs.a3;
577 
578 	return RMI_SUCCESS;
579 }
580 
581 #endif	/* __LINUX_ARM_RMI_CMDS_H_ */
582