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(®s);
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(®s);
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(®s);
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(®s);
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(®s);
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(®s);
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(®s);
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(®s);
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(®s);
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(®s);
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(®s);
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(®s);
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(®s);
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