Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: realm: ioremap: Allow mapping memory as encrypted

For ioremap(), so far we only checked if it was a device (RIPAS_DEV) to choose
an encrypted vs decrypted mapping. However, we may have firmware reserved memory
regions exposed to the OS (e.g., EFI Coco Secret Securityfs, ACPI CCEL).
We need to make sure that anything that is RIPAS_RAM (i.e., Guest
protected memory with RMM guarantees) are also mapped as encrypted.

Rephrasing the above, anything that is not RIPAS_EMPTY is guaranteed to be
protected by the RMM. Thus we choose encrypted mapping for anything that is not
RIPAS_EMPTY. While at it, rename the helper function

__arm64_is_protected_mmio => arm64_rsi_is_protected

to clearly indicate that this not an arm64 generic helper, but something to do
with Realms.

Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
Cc: Steven Price <steven.price@arm.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Tested-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Suzuki K Poulose and committed by
Will Deacon
fa84e534 8f5ae30d

+24 -6
+1 -1
arch/arm64/include/asm/io.h
··· 311 311 static inline bool arm64_is_protected_mmio(phys_addr_t phys_addr, size_t size) 312 312 { 313 313 if (unlikely(is_realm_world())) 314 - return __arm64_is_protected_mmio(phys_addr, size); 314 + return arm64_rsi_is_protected(phys_addr, size); 315 315 return false; 316 316 } 317 317
+1 -1
arch/arm64/include/asm/rsi.h
··· 16 16 17 17 void __init arm64_rsi_init(void); 18 18 19 - bool __arm64_is_protected_mmio(phys_addr_t base, size_t size); 19 + bool arm64_rsi_is_protected(phys_addr_t base, size_t size); 20 20 21 21 static inline bool is_realm_world(void) 22 22 {
+22 -4
arch/arm64/kernel/rsi.c
··· 84 84 } 85 85 } 86 86 87 - bool __arm64_is_protected_mmio(phys_addr_t base, size_t size) 87 + /* 88 + * Check if a given PA range is Trusted (e.g., Protected memory, a Trusted Device 89 + * mapping, or an MMIO emulated in the Realm world). 90 + * 91 + * We can rely on the RIPAS value of the region to detect if a given region is 92 + * protected. 93 + * 94 + * RIPAS_DEV - A trusted device memory or a trusted emulated MMIO (in the Realm 95 + * world 96 + * RIPAS_RAM - Memory (RAM), protected by the RMM guarantees. (e.g., Firmware 97 + * reserved regions for data sharing). 98 + * 99 + * RIPAS_DESTROYED is a special case of one of the above, where the host did 100 + * something without our permission and as such we can't do anything about it. 101 + * 102 + * The only case where something is emulated by the untrusted hypervisor or is 103 + * backed by shared memory is indicated by RSI_RIPAS_EMPTY. 104 + */ 105 + bool arm64_rsi_is_protected(phys_addr_t base, size_t size) 88 106 { 89 107 enum ripas ripas; 90 108 phys_addr_t end, top; ··· 119 101 break; 120 102 if (WARN_ON(top <= base)) 121 103 break; 122 - if (ripas != RSI_RIPAS_DEV) 104 + if (ripas == RSI_RIPAS_EMPTY) 123 105 break; 124 106 base = top; 125 107 } 126 108 127 109 return base >= end; 128 110 } 129 - EXPORT_SYMBOL(__arm64_is_protected_mmio); 111 + EXPORT_SYMBOL(arm64_rsi_is_protected); 130 112 131 113 static int realm_ioremap_hook(phys_addr_t phys, size_t size, pgprot_t *prot) 132 114 { 133 - if (__arm64_is_protected_mmio(phys, size)) 115 + if (arm64_rsi_is_protected(phys, size)) 134 116 *prot = pgprot_encrypted(*prot); 135 117 else 136 118 *prot = pgprot_decrypted(*prot);