xref: /linux/arch/arm64/kernel/rsi.c (revision f4cdf7ca9a1fdcca413157df19753f388a5a224e)
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/platform_device.h>
11 
12 #include <asm/io.h>
13 #include <asm/mem_encrypt.h>
14 #include <asm/pgtable.h>
15 #include <asm/rsi.h>
16 
17 static struct realm_config config;
18 
19 unsigned long prot_ns_shared;
20 EXPORT_SYMBOL(prot_ns_shared);
21 
22 DEFINE_STATIC_KEY_FALSE_RO(rsi_present);
23 EXPORT_SYMBOL(rsi_present);
24 
25 static bool rsi_version_matches(void)
26 {
27 	unsigned long ver_lower, ver_higher;
28 	unsigned long ret = rsi_request_version(RSI_ABI_VERSION,
29 						&ver_lower,
30 						&ver_higher);
31 
32 	if (ret == SMCCC_RET_NOT_SUPPORTED)
33 		return false;
34 
35 	if (ret != RSI_SUCCESS) {
36 		pr_err("RME: RMM doesn't support RSI version %lu.%lu. Supported range: %lu.%lu-%lu.%lu\n",
37 		       RSI_ABI_VERSION_MAJOR, RSI_ABI_VERSION_MINOR,
38 		       RSI_ABI_VERSION_GET_MAJOR(ver_lower),
39 		       RSI_ABI_VERSION_GET_MINOR(ver_lower),
40 		       RSI_ABI_VERSION_GET_MAJOR(ver_higher),
41 		       RSI_ABI_VERSION_GET_MINOR(ver_higher));
42 		return false;
43 	}
44 
45 	pr_info("RME: Using RSI version %lu.%lu\n",
46 		RSI_ABI_VERSION_GET_MAJOR(ver_lower),
47 		RSI_ABI_VERSION_GET_MINOR(ver_lower));
48 
49 	return true;
50 }
51 
52 static void __init arm64_rsi_setup_memory(void)
53 {
54 	u64 i;
55 	phys_addr_t start, end;
56 
57 	/*
58 	 * Iterate over the available memory ranges and convert the state to
59 	 * protected memory. We should take extra care to ensure that we DO NOT
60 	 * permit any "DESTROYED" pages to be converted to "RAM".
61 	 *
62 	 * panic() is used because if the attempt to switch the memory to
63 	 * protected has failed here, then future accesses to the memory are
64 	 * simply going to be reflected as a SEA (Synchronous External Abort)
65 	 * which we can't handle.  Bailing out early prevents the guest limping
66 	 * on and dying later.
67 	 */
68 	for_each_mem_range(i, &start, &end) {
69 		if (rsi_set_memory_range_protected_safe(start, end)) {
70 			panic("Failed to set memory range to protected: %pa-%pa",
71 			      &start, &end);
72 		}
73 	}
74 }
75 
76 /*
77  * Check if a given PA range is Trusted (e.g., Protected memory, a Trusted Device
78  * mapping, or an MMIO emulated in the Realm world).
79  *
80  * We can rely on the RIPAS value of the region to detect if a given region is
81  * protected.
82  *
83  *  RIPAS_DEV - A trusted device memory or a trusted emulated MMIO (in the Realm
84  *		world
85  *  RIPAS_RAM - Memory (RAM), protected by the RMM guarantees. (e.g., Firmware
86  *		reserved regions for data sharing).
87  *
88  *  RIPAS_DESTROYED is a special case of one of the above, where the host did
89  *  something without our permission and as such we can't do anything about it.
90  *
91  * The only case where something is emulated by the untrusted hypervisor or is
92  * backed by shared memory is indicated by RSI_RIPAS_EMPTY.
93  */
94 bool arm64_rsi_is_protected(phys_addr_t base, size_t size)
95 {
96 	enum ripas ripas;
97 	phys_addr_t end, top;
98 
99 	/* Overflow ? */
100 	if (WARN_ON(base + size <= base))
101 		return false;
102 
103 	end = ALIGN(base + size, RSI_GRANULE_SIZE);
104 	base = ALIGN_DOWN(base, RSI_GRANULE_SIZE);
105 
106 	while (base < end) {
107 		if (WARN_ON(rsi_ipa_state_get(base, end, &ripas, &top)))
108 			break;
109 		if (WARN_ON(top <= base))
110 			break;
111 		if (ripas == RSI_RIPAS_EMPTY)
112 			break;
113 		base = top;
114 	}
115 
116 	return base >= end;
117 }
118 EXPORT_SYMBOL(arm64_rsi_is_protected);
119 
120 static int realm_ioremap_hook(phys_addr_t phys, size_t size, pgprot_t *prot)
121 {
122 	if (arm64_rsi_is_protected(phys, size))
123 		*prot = pgprot_encrypted(*prot);
124 	else
125 		*prot = pgprot_decrypted(*prot);
126 
127 	return 0;
128 }
129 
130 void __init arm64_rsi_init(void)
131 {
132 	if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)
133 		return;
134 	if (!rsi_version_matches())
135 		return;
136 	if (WARN_ON(rsi_get_realm_config(lm_alias(&config))))
137 		return;
138 	prot_ns_shared = __phys_to_pte_val(BIT(config.ipa_bits - 1));
139 
140 	if (arm64_ioremap_prot_hook_register(realm_ioremap_hook))
141 		return;
142 
143 	if (realm_register_memory_enc_ops())
144 		return;
145 
146 	arm64_rsi_setup_memory();
147 
148 	static_branch_enable(&rsi_present);
149 }
150 
151 static struct platform_device rsi_dev = {
152 	.name = RSI_PDEV_NAME,
153 	.id = PLATFORM_DEVID_NONE
154 };
155 
156 static int __init arm64_create_dummy_rsi_dev(void)
157 {
158 	if (is_realm_world() &&
159 	    platform_device_register(&rsi_dev))
160 		pr_err("failed to register rsi platform device\n");
161 	return 0;
162 }
163 
164 arch_initcall(arm64_create_dummy_rsi_dev)
165