xref: /linux/drivers/firmware/arm_rmm/rsi.c (revision 303bff3637d13f0ecbb280c7cb403470c440a2a6)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2023 ARM Ltd.
4  */
5 
6 #include <linux/jump_label.h>
7 #include <linux/memblock.h>
8 #include <linux/psci.h>
9 #include <linux/swiotlb.h>
10 #include <linux/arm-rsi-cmds.h>
11 #include <linux/kobject.h>
12 #include <linux/sysfs.h>
13 
14 #include <asm/io.h>
15 #include <asm/mem_encrypt.h>
16 #include <asm/pgtable.h>
17 
18 static struct realm_config config;
19 
20 unsigned long prot_ns_shared;
21 EXPORT_SYMBOL(prot_ns_shared);
22 
23 DEFINE_STATIC_KEY_FALSE_RO(rsi_present);
24 EXPORT_SYMBOL(rsi_present);
25 
rsi_version_matches(void)26 static bool rsi_version_matches(void)
27 {
28 	unsigned long ver_lower, ver_higher;
29 	unsigned long ret = rsi_request_version(RSI_ABI_VERSION,
30 						&ver_lower,
31 						&ver_higher);
32 
33 	if (ret == SMCCC_RET_NOT_SUPPORTED)
34 		return false;
35 
36 	if (ret != RSI_SUCCESS) {
37 		pr_err("RME: RMM doesn't support RSI version %lu.%lu. Supported range: %lu.%lu-%lu.%lu\n",
38 		       RSI_ABI_VERSION_MAJOR, RSI_ABI_VERSION_MINOR,
39 		       RSI_ABI_VERSION_GET_MAJOR(ver_lower),
40 		       RSI_ABI_VERSION_GET_MINOR(ver_lower),
41 		       RSI_ABI_VERSION_GET_MAJOR(ver_higher),
42 		       RSI_ABI_VERSION_GET_MINOR(ver_higher));
43 		return false;
44 	}
45 
46 	pr_info("RME: Using RSI version %lu.%lu\n",
47 		RSI_ABI_VERSION_GET_MAJOR(ver_lower),
48 		RSI_ABI_VERSION_GET_MINOR(ver_lower));
49 
50 	return true;
51 }
52 
arm64_rsi_setup_memory(void)53 static void __init arm64_rsi_setup_memory(void)
54 {
55 	u64 i;
56 	phys_addr_t start, end;
57 
58 	/*
59 	 * Iterate over the available memory ranges and convert the state to
60 	 * protected memory. We should take extra care to ensure that we DO NOT
61 	 * permit any "DESTROYED" pages to be converted to "RAM".
62 	 *
63 	 * panic() is used because if the attempt to switch the memory to
64 	 * protected has failed here, then future accesses to the memory are
65 	 * simply going to be reflected as a SEA (Synchronous External Abort)
66 	 * which we can't handle.  Bailing out early prevents the guest limping
67 	 * on and dying later.
68 	 */
69 	for_each_mem_range(i, &start, &end) {
70 		if (rsi_set_memory_range_protected_safe(start, end)) {
71 			panic("Failed to set memory range to protected: %pa-%pa",
72 			      &start, &end);
73 		}
74 	}
75 }
76 
77 /*
78  * Check if a given PA range is Trusted (e.g., Protected memory, a Trusted Device
79  * mapping, or an MMIO emulated in the Realm world).
80  *
81  * We can rely on the RIPAS value of the region to detect if a given region is
82  * protected.
83  *
84  *  RIPAS_DEV - A trusted device memory or a trusted emulated MMIO (in the Realm
85  *		world
86  *  RIPAS_RAM - Memory (RAM), protected by the RMM guarantees. (e.g., Firmware
87  *		reserved regions for data sharing).
88  *
89  *  RIPAS_DESTROYED is a special case of one of the above, where the host did
90  *  something without our permission and as such we can't do anything about it.
91  *
92  * The only case where something is emulated by the untrusted hypervisor or is
93  * backed by shared memory is indicated by RSI_RIPAS_EMPTY.
94  */
arm64_rsi_is_protected(phys_addr_t base,size_t size)95 bool arm64_rsi_is_protected(phys_addr_t base, size_t size)
96 {
97 	enum ripas ripas;
98 	phys_addr_t end, top;
99 
100 	/* Overflow ? */
101 	if (WARN_ON(base + size <= base))
102 		return false;
103 
104 	end = ALIGN(base + size, RSI_GRANULE_SIZE);
105 	base = ALIGN_DOWN(base, RSI_GRANULE_SIZE);
106 
107 	while (base < end) {
108 		if (WARN_ON(rsi_ipa_state_get(base, end, &ripas, &top)))
109 			break;
110 		if (WARN_ON(top <= base))
111 			break;
112 		if (ripas == RSI_RIPAS_EMPTY)
113 			break;
114 		base = top;
115 	}
116 
117 	return base >= end;
118 }
119 EXPORT_SYMBOL(arm64_rsi_is_protected);
120 
realm_ioremap_hook(phys_addr_t phys,size_t size,pgprot_t * prot)121 static int realm_ioremap_hook(phys_addr_t phys, size_t size, pgprot_t *prot)
122 {
123 	if (arm64_rsi_is_protected(phys, size))
124 		*prot = pgprot_encrypted(*prot);
125 	else
126 		*prot = pgprot_decrypted(*prot);
127 
128 	return 0;
129 }
130 
realm_set_memory_encrypted(unsigned long addr,int numpages)131 static int realm_set_memory_encrypted(unsigned long addr, int numpages)
132 {
133 	int ret = __set_memory_enc_dec(addr, numpages, true);
134 
135 	/*
136 	 * If the request to change state fails, then the only sensible cause
137 	 * of action for the caller is to leak the memory
138 	 */
139 	WARN(ret, "Failed to encrypt memory, %d pages will be leaked",
140 	     numpages);
141 
142 	return ret;
143 }
144 
realm_set_memory_decrypted(unsigned long addr,int numpages)145 static int realm_set_memory_decrypted(unsigned long addr, int numpages)
146 {
147 	int ret = __set_memory_enc_dec(addr, numpages, false);
148 
149 	WARN(ret, "Failed to decrypt memory, %d pages will be leaked",
150 	     numpages);
151 
152 	return ret;
153 }
154 
155 static const struct arm64_mem_crypt_ops realm_crypt_ops = {
156 	.encrypt = realm_set_memory_encrypted,
157 	.decrypt = realm_set_memory_decrypted,
158 };
159 
realm_register_memory_enc_ops(void)160 static int realm_register_memory_enc_ops(void)
161 {
162 	return arm64_mem_crypt_ops_register(&realm_crypt_ops);
163 }
164 
arm64_rsi_init(void)165 void __init arm64_rsi_init(void)
166 {
167 	if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)
168 		return;
169 	if (!rsi_version_matches())
170 		return;
171 	if (WARN_ON(rsi_get_realm_config(lm_alias(&config))))
172 		return;
173 	prot_ns_shared = __phys_to_pte_val(BIT(config.ipa_bits - 1));
174 
175 	if (arm64_ioremap_prot_hook_register(realm_ioremap_hook))
176 		return;
177 
178 	if (realm_register_memory_enc_ops())
179 		return;
180 
181 	arm64_rsi_setup_memory();
182 
183 	static_branch_enable(&rsi_present);
184 }
185 
realm_guest_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)186 static ssize_t realm_guest_show(struct kobject *kobj,
187 		struct kobj_attribute *attr, char *buf)
188 {
189 	return sysfs_emit(buf, "1\n");
190 }
191 
192 static struct kobj_attribute cca_realm_guest = __ATTR_RO(realm_guest);
193 static const struct attribute *cca_realm_attrs[] = {
194 	&cca_realm_guest.attr,
195 	NULL
196 };
197 
realm_sysfs_init(void)198 static int __init realm_sysfs_init(void)
199 {
200 	int ret;
201 	struct kobject *cca_kobj;
202 
203 	if (!is_realm_world())
204 		return 0;
205 
206 	cca_kobj = kobject_create_and_add("cca", firmware_kobj);
207 	if (!cca_kobj)
208 		return -ENOMEM;
209 
210 	ret = sysfs_create_files(cca_kobj, cca_realm_attrs);
211 	if (!ret)
212 		return 0;
213 
214 	kobject_put(cca_kobj);
215 	return ret;
216 }
217 device_initcall(realm_sysfs_init);
218