xref: /linux/arch/arm64/include/asm/rsi_cmds.h (revision 364eeb79a213fcf9164208b53764223ad522d6b3)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2023 ARM Ltd.
4  */
5 
6 #ifndef __ASM_RSI_CMDS_H
7 #define __ASM_RSI_CMDS_H
8 
9 #include <linux/arm-smccc.h>
10 
11 #include <asm/rsi_smc.h>
12 
13 #define RSI_GRANULE_SHIFT		12
14 #define RSI_GRANULE_SIZE		(_AC(1, UL) << RSI_GRANULE_SHIFT)
15 
16 enum ripas {
17 	RSI_RIPAS_EMPTY = 0,
18 	RSI_RIPAS_RAM = 1,
19 	RSI_RIPAS_DESTROYED = 2,
20 	RSI_RIPAS_DEV = 3,
21 };
22 
23 static inline unsigned long rsi_request_version(unsigned long req,
24 						unsigned long *out_lower,
25 						unsigned long *out_higher)
26 {
27 	struct arm_smccc_res res;
28 
29 	arm_smccc_smc(SMC_RSI_ABI_VERSION, req, 0, 0, 0, 0, 0, 0, &res);
30 
31 	if (out_lower)
32 		*out_lower = res.a1;
33 	if (out_higher)
34 		*out_higher = res.a2;
35 
36 	return res.a0;
37 }
38 
39 static inline unsigned long rsi_get_realm_config(struct realm_config *cfg)
40 {
41 	struct arm_smccc_res res;
42 
43 	arm_smccc_smc(SMC_RSI_REALM_CONFIG, virt_to_phys(cfg),
44 		      0, 0, 0, 0, 0, 0, &res);
45 	return res.a0;
46 }
47 
48 static inline unsigned long rsi_ipa_state_get(phys_addr_t start,
49 					      phys_addr_t end,
50 					      enum ripas *state,
51 					      phys_addr_t *top)
52 {
53 	struct arm_smccc_res res;
54 
55 	arm_smccc_smc(SMC_RSI_IPA_STATE_GET,
56 		      start, end, 0, 0, 0, 0, 0,
57 		      &res);
58 
59 	if (res.a0 == RSI_SUCCESS) {
60 		if (top)
61 			*top = res.a1;
62 		if (state)
63 			*state = res.a2;
64 	}
65 
66 	return res.a0;
67 }
68 
69 static inline long rsi_set_addr_range_state(phys_addr_t start,
70 					    phys_addr_t end,
71 					    enum ripas state,
72 					    unsigned long flags,
73 					    phys_addr_t *top)
74 {
75 	struct arm_smccc_res res;
76 
77 	arm_smccc_smc(SMC_RSI_IPA_STATE_SET, start, end, state,
78 		      flags, 0, 0, 0, &res);
79 
80 	if (top)
81 		*top = res.a1;
82 
83 	if (res.a2 != RSI_ACCEPT)
84 		return -EPERM;
85 
86 	return res.a0;
87 }
88 
89 /**
90  * rsi_attestation_token_init - Initialise the operation to retrieve an
91  * attestation token.
92  *
93  * @challenge:	The challenge data to be used in the attestation token
94  *		generation.
95  * @size:	Size of the challenge data in bytes.
96  *
97  * Initialises the attestation token generation and returns an upper bound
98  * on the attestation token size that can be used to allocate an adequate
99  * buffer. The caller is expected to subsequently call
100  * rsi_attestation_token_continue() to retrieve the attestation token data on
101  * the same CPU.
102  *
103  * Returns:
104  *  On success, returns the upper limit of the attestation report size.
105  *  Otherwise, -EINVAL
106  */
107 static inline long
108 rsi_attestation_token_init(const u8 *challenge, unsigned long size)
109 {
110 	struct arm_smccc_1_2_regs regs = { 0 };
111 
112 	/* The challenge must be at least 32bytes and at most 64bytes */
113 	if (!challenge || size < 32 || size > 64)
114 		return -EINVAL;
115 
116 	regs.a0 = SMC_RSI_ATTESTATION_TOKEN_INIT;
117 	memcpy(&regs.a1, challenge, size);
118 	arm_smccc_1_2_smc(&regs, &regs);
119 
120 	if (regs.a0 == RSI_SUCCESS)
121 		return regs.a1;
122 
123 	return -EINVAL;
124 }
125 
126 /**
127  * rsi_attestation_token_continue - Continue the operation to retrieve an
128  * attestation token.
129  *
130  * @granule: {I}PA of the Granule to which the token will be written.
131  * @offset:  Offset within Granule to start of buffer in bytes.
132  * @size:    The size of the buffer.
133  * @len:     The number of bytes written to the buffer.
134  *
135  * Retrieves up to a RSI_GRANULE_SIZE worth of token data per call. The caller
136  * is expected to call rsi_attestation_token_init() before calling this
137  * function to retrieve the attestation token.
138  *
139  * Return:
140  * * %RSI_SUCCESS     - Attestation token retrieved successfully.
141  * * %RSI_INCOMPLETE  - Token generation is not complete.
142  * * %RSI_ERROR_INPUT - A parameter was not valid.
143  * * %RSI_ERROR_STATE - Attestation not in progress.
144  */
145 static inline unsigned long rsi_attestation_token_continue(phys_addr_t granule,
146 							   unsigned long offset,
147 							   unsigned long size,
148 							   unsigned long *len)
149 {
150 	struct arm_smccc_res res;
151 
152 	arm_smccc_1_1_invoke(SMC_RSI_ATTESTATION_TOKEN_CONTINUE,
153 			     granule, offset, size, 0, &res);
154 
155 	if (len)
156 		*len = res.a1;
157 	return res.a0;
158 }
159 
160 #endif /* __ASM_RSI_CMDS_H */
161