1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2023 ARM Ltd.
6 #include <linux/jump_label.h>
7 #include <linux/memblock.h>
8 #include <linux/psci.h>
9 #include <linux/swiotlb.h>
10 #include <linux/cc_platform.h>
13 #include <asm/mem_encrypt.h>
16 static struct realm_config config
;
18 unsigned long prot_ns_shared
;
19 EXPORT_SYMBOL(prot_ns_shared
);
21 DEFINE_STATIC_KEY_FALSE_RO(rsi_present
);
22 EXPORT_SYMBOL(rsi_present
);
24 bool cc_platform_has(enum cc_attr attr
)
27 case CC_ATTR_MEM_ENCRYPT
:
28 return is_realm_world();
33 EXPORT_SYMBOL_GPL(cc_platform_has
);
35 static bool rsi_version_matches(void)
37 unsigned long ver_lower
, ver_higher
;
38 unsigned long ret
= rsi_request_version(RSI_ABI_VERSION
,
42 if (ret
== SMCCC_RET_NOT_SUPPORTED
)
45 if (ret
!= RSI_SUCCESS
) {
46 pr_err("RME: RMM doesn't support RSI version %lu.%lu. Supported range: %lu.%lu-%lu.%lu\n",
47 RSI_ABI_VERSION_MAJOR
, RSI_ABI_VERSION_MINOR
,
48 RSI_ABI_VERSION_GET_MAJOR(ver_lower
),
49 RSI_ABI_VERSION_GET_MINOR(ver_lower
),
50 RSI_ABI_VERSION_GET_MAJOR(ver_higher
),
51 RSI_ABI_VERSION_GET_MINOR(ver_higher
));
55 pr_info("RME: Using RSI version %lu.%lu\n",
56 RSI_ABI_VERSION_GET_MAJOR(ver_lower
),
57 RSI_ABI_VERSION_GET_MINOR(ver_lower
));
62 static void __init
arm64_rsi_setup_memory(void)
65 phys_addr_t start
, end
;
68 * Iterate over the available memory ranges and convert the state to
69 * protected memory. We should take extra care to ensure that we DO NOT
70 * permit any "DESTROYED" pages to be converted to "RAM".
72 * panic() is used because if the attempt to switch the memory to
73 * protected has failed here, then future accesses to the memory are
74 * simply going to be reflected as a SEA (Synchronous External Abort)
75 * which we can't handle. Bailing out early prevents the guest limping
78 for_each_mem_range(i
, &start
, &end
) {
79 if (rsi_set_memory_range_protected_safe(start
, end
)) {
80 panic("Failed to set memory range to protected: %pa-%pa",
86 bool __arm64_is_protected_mmio(phys_addr_t base
, size_t size
)
92 if (WARN_ON(base
+ size
<= base
))
95 end
= ALIGN(base
+ size
, RSI_GRANULE_SIZE
);
96 base
= ALIGN_DOWN(base
, RSI_GRANULE_SIZE
);
99 if (WARN_ON(rsi_ipa_state_get(base
, end
, &ripas
, &top
)))
101 if (WARN_ON(top
<= base
))
103 if (ripas
!= RSI_RIPAS_DEV
)
110 EXPORT_SYMBOL(__arm64_is_protected_mmio
);
112 static int realm_ioremap_hook(phys_addr_t phys
, size_t size
, pgprot_t
*prot
)
114 if (__arm64_is_protected_mmio(phys
, size
))
115 *prot
= pgprot_encrypted(*prot
);
117 *prot
= pgprot_decrypted(*prot
);
122 void __init
arm64_rsi_init(void)
124 if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC
)
126 if (!rsi_version_matches())
128 if (WARN_ON(rsi_get_realm_config(&config
)))
130 prot_ns_shared
= BIT(config
.ipa_bits
- 1);
132 if (arm64_ioremap_prot_hook_register(realm_ioremap_hook
))
135 if (realm_register_memory_enc_ops())
138 arm64_rsi_setup_memory();
140 static_branch_enable(&rsi_present
);