Skip to content

Commit 3715894

Browse files
Suzuki K Poulosectmarinas
authored andcommitted
arm64: rsi: Add support for checking whether an MMIO is protected
On Arm CCA, with RMM-v1.0, all MMIO regions are shared. However, in the future, an Arm CCA-v1.0 compliant guest may be run in a lesser privileged partition in the Realm World (with Arm CCA-v1.1 Planes feature). In this case, some of the MMIO regions may be emulated by a higher privileged component in the Realm world, i.e, protected. Thus the guest must decide today, whether a given MMIO region is shared vs Protected and create the stage1 mapping accordingly. On Arm CCA, this detection is based on the "IPA State" (RIPAS == RIPAS_IO). Provide a helper to run this check on a given range of MMIO. Also, provide a arm64 helper which may be hooked in by other solutions. Reviewed-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 3993069 commit 3715894

File tree

4 files changed

+57
-0
lines changed

4 files changed

+57
-0
lines changed

arch/arm64/include/asm/io.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <asm/early_ioremap.h>
1818
#include <asm/alternative.h>
1919
#include <asm/cpufeature.h>
20+
#include <asm/rsi.h>
2021

2122
/*
2223
* Generic IO read/write. These perform native-endian accesses.
@@ -318,4 +319,11 @@ extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
318319
unsigned long flags);
319320
#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap
320321

322+
static inline bool arm64_is_protected_mmio(phys_addr_t phys_addr, size_t size)
323+
{
324+
if (unlikely(is_realm_world()))
325+
return __arm64_is_protected_mmio(phys_addr, size);
326+
return false;
327+
}
328+
321329
#endif /* __ASM_IO_H */

arch/arm64/include/asm/rsi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ DECLARE_STATIC_KEY_FALSE(rsi_present);
1414

1515
void __init arm64_rsi_init(void);
1616

17+
bool __arm64_is_protected_mmio(phys_addr_t base, size_t size);
18+
1719
static inline bool is_realm_world(void)
1820
{
1921
return static_branch_unlikely(&rsi_present);

arch/arm64/include/asm/rsi_cmds.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ static inline unsigned long rsi_get_realm_config(struct realm_config *cfg)
4545
return res.a0;
4646
}
4747

48+
static inline unsigned long rsi_ipa_state_get(phys_addr_t start,
49+
phys_addr_t end,
50+
enum ripas *state,
51+
phys_addr_t *top)
52+
{
53+
struct arm_smccc_res res;
54+
55+
arm_smccc_smc(SMC_RSI_IPA_STATE_GET,
56+
start, end, 0, 0, 0, 0, 0,
57+
&res);
58+
59+
if (res.a0 == RSI_SUCCESS) {
60+
if (top)
61+
*top = res.a1;
62+
if (state)
63+
*state = res.a2;
64+
}
65+
66+
return res.a0;
67+
}
68+
4869
static inline long rsi_set_addr_range_state(phys_addr_t start,
4970
phys_addr_t end,
5071
enum ripas state,

arch/arm64/kernel/rsi.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,32 @@ static void __init arm64_rsi_setup_memory(void)
6767
}
6868
}
6969

70+
bool __arm64_is_protected_mmio(phys_addr_t base, size_t size)
71+
{
72+
enum ripas ripas;
73+
phys_addr_t end, top;
74+
75+
/* Overflow ? */
76+
if (WARN_ON(base + size <= base))
77+
return false;
78+
79+
end = ALIGN(base + size, RSI_GRANULE_SIZE);
80+
base = ALIGN_DOWN(base, RSI_GRANULE_SIZE);
81+
82+
while (base < end) {
83+
if (WARN_ON(rsi_ipa_state_get(base, end, &ripas, &top)))
84+
break;
85+
if (WARN_ON(top <= base))
86+
break;
87+
if (ripas != RSI_RIPAS_DEV)
88+
break;
89+
base = top;
90+
}
91+
92+
return base >= end;
93+
}
94+
EXPORT_SYMBOL(__arm64_is_protected_mmio);
95+
7096
void __init arm64_rsi_init(void)
7197
{
7298
if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)

0 commit comments

Comments
 (0)