Skip to content

Commit b880a80

Browse files
Suzuki K Poulosectmarinas
authored andcommitted
arm64: rsi: Add RSI definitions
The RMM (Realm Management Monitor) provides functionality that can be accessed by a realm guest through SMC (Realm Services Interface) calls. The SMC definitions are based on DEN0137[1] version 1.0-rel0. [1] https://developer.arm.com/documentation/den0137/1-0rel0/ Acked-by: Catalin Marinas <[email protected]> Reviewed-by: Gavin Shan <[email protected]> Signed-off-by: Suzuki K Poulose <[email protected]> Signed-off-by: Steven Price <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 9852d85 commit b880a80

File tree

2 files changed

+332
-0
lines changed

2 files changed

+332
-0
lines changed

arch/arm64/include/asm/rsi_cmds.h

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
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 long rsi_set_addr_range_state(phys_addr_t start,
49+
phys_addr_t end,
50+
enum ripas state,
51+
unsigned long flags,
52+
phys_addr_t *top)
53+
{
54+
struct arm_smccc_res res;
55+
56+
arm_smccc_smc(SMC_RSI_IPA_STATE_SET, start, end, state,
57+
flags, 0, 0, 0, &res);
58+
59+
if (top)
60+
*top = res.a1;
61+
62+
if (res.a2 != RSI_ACCEPT)
63+
return -EPERM;
64+
65+
return res.a0;
66+
}
67+
68+
/**
69+
* rsi_attestation_token_init - Initialise the operation to retrieve an
70+
* attestation token.
71+
*
72+
* @challenge: The challenge data to be used in the attestation token
73+
* generation.
74+
* @size: Size of the challenge data in bytes.
75+
*
76+
* Initialises the attestation token generation and returns an upper bound
77+
* on the attestation token size that can be used to allocate an adequate
78+
* buffer. The caller is expected to subsequently call
79+
* rsi_attestation_token_continue() to retrieve the attestation token data on
80+
* the same CPU.
81+
*
82+
* Returns:
83+
* On success, returns the upper limit of the attestation report size.
84+
* Otherwise, -EINVAL
85+
*/
86+
static inline long
87+
rsi_attestation_token_init(const u8 *challenge, unsigned long size)
88+
{
89+
struct arm_smccc_1_2_regs regs = { 0 };
90+
91+
/* The challenge must be at least 32bytes and at most 64bytes */
92+
if (!challenge || size < 32 || size > 64)
93+
return -EINVAL;
94+
95+
regs.a0 = SMC_RSI_ATTESTATION_TOKEN_INIT;
96+
memcpy(&regs.a1, challenge, size);
97+
arm_smccc_1_2_smc(&regs, &regs);
98+
99+
if (regs.a0 == RSI_SUCCESS)
100+
return regs.a1;
101+
102+
return -EINVAL;
103+
}
104+
105+
/**
106+
* rsi_attestation_token_continue - Continue the operation to retrieve an
107+
* attestation token.
108+
*
109+
* @granule: {I}PA of the Granule to which the token will be written.
110+
* @offset: Offset within Granule to start of buffer in bytes.
111+
* @size: The size of the buffer.
112+
* @len: The number of bytes written to the buffer.
113+
*
114+
* Retrieves up to a RSI_GRANULE_SIZE worth of token data per call. The caller
115+
* is expected to call rsi_attestation_token_init() before calling this
116+
* function to retrieve the attestation token.
117+
*
118+
* Return:
119+
* * %RSI_SUCCESS - Attestation token retrieved successfully.
120+
* * %RSI_INCOMPLETE - Token generation is not complete.
121+
* * %RSI_ERROR_INPUT - A parameter was not valid.
122+
* * %RSI_ERROR_STATE - Attestation not in progress.
123+
*/
124+
static inline unsigned long rsi_attestation_token_continue(phys_addr_t granule,
125+
unsigned long offset,
126+
unsigned long size,
127+
unsigned long *len)
128+
{
129+
struct arm_smccc_res res;
130+
131+
arm_smccc_1_1_invoke(SMC_RSI_ATTESTATION_TOKEN_CONTINUE,
132+
granule, offset, size, 0, &res);
133+
134+
if (len)
135+
*len = res.a1;
136+
return res.a0;
137+
}
138+
139+
#endif /* __ASM_RSI_CMDS_H */

arch/arm64/include/asm/rsi_smc.h

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2023 ARM Ltd.
4+
*/
5+
6+
#ifndef __ASM_RSI_SMC_H_
7+
#define __ASM_RSI_SMC_H_
8+
9+
#include <linux/arm-smccc.h>
10+
11+
/*
12+
* This file describes the Realm Services Interface (RSI) Application Binary
13+
* Interface (ABI) for SMC calls made from within the Realm to the RMM and
14+
* serviced by the RMM.
15+
*/
16+
17+
/*
18+
* The major version number of the RSI implementation. This is increased when
19+
* the binary format or semantics of the SMC calls change.
20+
*/
21+
#define RSI_ABI_VERSION_MAJOR UL(1)
22+
23+
/*
24+
* The minor version number of the RSI implementation. This is increased when
25+
* a bug is fixed, or a feature is added without breaking binary compatibility.
26+
*/
27+
#define RSI_ABI_VERSION_MINOR UL(0)
28+
29+
#define RSI_ABI_VERSION ((RSI_ABI_VERSION_MAJOR << 16) | \
30+
RSI_ABI_VERSION_MINOR)
31+
32+
#define RSI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16)
33+
#define RSI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF)
34+
35+
#define RSI_SUCCESS UL(0)
36+
#define RSI_ERROR_INPUT UL(1)
37+
#define RSI_ERROR_STATE UL(2)
38+
#define RSI_INCOMPLETE UL(3)
39+
#define RSI_ERROR_UNKNOWN UL(4)
40+
41+
#define SMC_RSI_FID(n) ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
42+
ARM_SMCCC_SMC_64, \
43+
ARM_SMCCC_OWNER_STANDARD, \
44+
n)
45+
46+
/*
47+
* Returns RSI version.
48+
*
49+
* arg1 == Requested interface revision
50+
* ret0 == Status / error
51+
* ret1 == Lower implemented interface revision
52+
* ret2 == Higher implemented interface revision
53+
*/
54+
#define SMC_RSI_ABI_VERSION SMC_RSI_FID(0x190)
55+
56+
/*
57+
* Read feature register.
58+
*
59+
* arg1 == Feature register index
60+
* ret0 == Status / error
61+
* ret1 == Feature register value
62+
*/
63+
#define SMC_RSI_FEATURES SMC_RSI_FID(0x191)
64+
65+
/*
66+
* Read measurement for the current Realm.
67+
*
68+
* arg1 == Index, which measurements slot to read
69+
* ret0 == Status / error
70+
* ret1 == Measurement value, bytes: 0 - 7
71+
* ret2 == Measurement value, bytes: 8 - 15
72+
* ret3 == Measurement value, bytes: 16 - 23
73+
* ret4 == Measurement value, bytes: 24 - 31
74+
* ret5 == Measurement value, bytes: 32 - 39
75+
* ret6 == Measurement value, bytes: 40 - 47
76+
* ret7 == Measurement value, bytes: 48 - 55
77+
* ret8 == Measurement value, bytes: 56 - 63
78+
*/
79+
#define SMC_RSI_MEASUREMENT_READ SMC_RSI_FID(0x192)
80+
81+
/*
82+
* Extend Realm Extensible Measurement (REM) value.
83+
*
84+
* arg1 == Index, which measurements slot to extend
85+
* arg2 == Size of realm measurement in bytes, max 64 bytes
86+
* arg3 == Measurement value, bytes: 0 - 7
87+
* arg4 == Measurement value, bytes: 8 - 15
88+
* arg5 == Measurement value, bytes: 16 - 23
89+
* arg6 == Measurement value, bytes: 24 - 31
90+
* arg7 == Measurement value, bytes: 32 - 39
91+
* arg8 == Measurement value, bytes: 40 - 47
92+
* arg9 == Measurement value, bytes: 48 - 55
93+
* arg10 == Measurement value, bytes: 56 - 63
94+
* ret0 == Status / error
95+
*/
96+
#define SMC_RSI_MEASUREMENT_EXTEND SMC_RSI_FID(0x193)
97+
98+
/*
99+
* Initialize the operation to retrieve an attestation token.
100+
*
101+
* arg1 == Challenge value, bytes: 0 - 7
102+
* arg2 == Challenge value, bytes: 8 - 15
103+
* arg3 == Challenge value, bytes: 16 - 23
104+
* arg4 == Challenge value, bytes: 24 - 31
105+
* arg5 == Challenge value, bytes: 32 - 39
106+
* arg6 == Challenge value, bytes: 40 - 47
107+
* arg7 == Challenge value, bytes: 48 - 55
108+
* arg8 == Challenge value, bytes: 56 - 63
109+
* ret0 == Status / error
110+
* ret1 == Upper bound of token size in bytes
111+
*/
112+
#define SMC_RSI_ATTESTATION_TOKEN_INIT SMC_RSI_FID(0x194)
113+
114+
/*
115+
* Continue the operation to retrieve an attestation token.
116+
*
117+
* arg1 == The IPA of token buffer
118+
* arg2 == Offset within the granule of the token buffer
119+
* arg3 == Size of the granule buffer
120+
* ret0 == Status / error
121+
* ret1 == Length of token bytes copied to the granule buffer
122+
*/
123+
#define SMC_RSI_ATTESTATION_TOKEN_CONTINUE SMC_RSI_FID(0x195)
124+
125+
#ifndef __ASSEMBLY__
126+
127+
struct realm_config {
128+
union {
129+
struct {
130+
unsigned long ipa_bits; /* Width of IPA in bits */
131+
unsigned long hash_algo; /* Hash algorithm */
132+
};
133+
u8 pad[0x200];
134+
};
135+
union {
136+
u8 rpv[64]; /* Realm Personalization Value */
137+
u8 pad2[0xe00];
138+
};
139+
/*
140+
* The RMM requires the configuration structure to be aligned to a 4k
141+
* boundary, ensure this happens by aligning this structure.
142+
*/
143+
} __aligned(0x1000);
144+
145+
#endif /* __ASSEMBLY__ */
146+
147+
/*
148+
* Read configuration for the current Realm.
149+
*
150+
* arg1 == struct realm_config addr
151+
* ret0 == Status / error
152+
*/
153+
#define SMC_RSI_REALM_CONFIG SMC_RSI_FID(0x196)
154+
155+
/*
156+
* Request RIPAS of a target IPA range to be changed to a specified value.
157+
*
158+
* arg1 == Base IPA address of target region
159+
* arg2 == Top of the region
160+
* arg3 == RIPAS value
161+
* arg4 == flags
162+
* ret0 == Status / error
163+
* ret1 == Top of modified IPA range
164+
* ret2 == Whether the Host accepted or rejected the request
165+
*/
166+
#define SMC_RSI_IPA_STATE_SET SMC_RSI_FID(0x197)
167+
168+
#define RSI_NO_CHANGE_DESTROYED UL(0)
169+
#define RSI_CHANGE_DESTROYED UL(1)
170+
171+
#define RSI_ACCEPT UL(0)
172+
#define RSI_REJECT UL(1)
173+
174+
/*
175+
* Get RIPAS of a target IPA range.
176+
*
177+
* arg1 == Base IPA of target region
178+
* arg2 == End of target IPA region
179+
* ret0 == Status / error
180+
* ret1 == Top of IPA region which has the reported RIPAS value
181+
* ret2 == RIPAS value
182+
*/
183+
#define SMC_RSI_IPA_STATE_GET SMC_RSI_FID(0x198)
184+
185+
/*
186+
* Make a Host call.
187+
*
188+
* arg1 == IPA of host call structure
189+
* ret0 == Status / error
190+
*/
191+
#define SMC_RSI_HOST_CALL SMC_RSI_FID(0x199)
192+
193+
#endif /* __ASM_RSI_SMC_H_ */

0 commit comments

Comments
 (0)