The top bit of the configured IPA size is used as an attribute to
control whether the address is protected or shared. Query the
configuration from the RMM to assertain which bit this is.
Co-developed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm64/include/asm/pgtable-prot.h | 2 ++
arch/arm64/include/asm/rsi_cmds.h | 8 ++++++++
arch/arm64/kernel/rsi.c | 8 ++++++++
3 files changed, 18 insertions(+)
@@ -33,7 +33,9 @@
#include <asm/pgtable-types.h>
extern bool arm64_use_ng_mappings;
+extern unsigned long prot_ns_shared;
+#define PROT_NS_SHARED ((prot_ns_shared))
#define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
#define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
@@ -46,6 +46,14 @@ static inline void invoke_rsi_fn_smc_with_res(unsigned long function_id,
arm_smccc_smc(function_id, arg0, arg1, arg2, arg3, 0, 0, 0, res);
}
+static inline unsigned long rsi_get_realm_config(struct realm_config *cfg)
+{
+ struct arm_smccc_res res;
+
+ invoke_rsi_fn_smc_with_res(SMC_RSI_REALM_CONFIG, virt_to_phys(cfg), 0, 0, 0, &res);
+ return res.a0;
+}
+
static inline unsigned long rsi_set_addr_range_state(phys_addr_t start,
phys_addr_t end,
enum ripas state,
@@ -7,6 +7,11 @@
#include <linux/memblock.h>
#include <asm/rsi.h>
+struct realm_config __attribute((aligned(PAGE_SIZE))) config;
+
+unsigned long prot_ns_shared;
+EXPORT_SYMBOL(prot_ns_shared);
+
DEFINE_STATIC_KEY_FALSE_RO(rsi_present);
static bool rsi_version_matches(void)
@@ -45,6 +50,9 @@ void __init arm64_rsi_init(void)
{
if (!rsi_version_matches())
return;
+ if (rsi_get_realm_config(&config))
+ return;
+ prot_ns_shared = BIT(config.ipa_bits - 1);
static_branch_enable(&rsi_present);
}