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