Commit 42be24a4 authored by Suzuki K Poulose's avatar Suzuki K Poulose Committed by Catalin Marinas
Browse files

arm64: Enable memory encrypt for Realms



Use the memory encryption APIs to trigger a RSI call to request a
transition between protected memory and shared memory (or vice versa)
and updating the kernel's linear map of modified pages to flip the top
bit of the IPA. This requires that block mappings are not used in the
direct map for realm guests.

Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Reviewed-by: default avatarGavin Shan <gshan@redhat.com>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Co-developed-by: default avatarSteven Price <steven.price@arm.com>
Signed-off-by: default avatarSteven Price <steven.price@arm.com>
Link: https://lore.kernel.org/r/20241017131434.40935-10-steven.price@arm.com


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 0e9cb599
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ config ARM64
	select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
	select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
	select ARCH_HAS_CACHE_LINE_SIZE
	select ARCH_HAS_CC_PLATFORM
	select ARCH_HAS_CURRENT_STACK_POINTER
	select ARCH_HAS_DEBUG_VIRTUAL
	select ARCH_HAS_DEBUG_VM_PGTABLE
@@ -44,6 +45,8 @@ config ARM64
	select ARCH_HAS_SETUP_DMA_OPS
	select ARCH_HAS_SET_DIRECT_MAP
	select ARCH_HAS_SET_MEMORY
	select ARCH_HAS_MEM_ENCRYPT
	select ARCH_HAS_FORCE_DMA_UNENCRYPTED
	select ARCH_STACKWALK
	select ARCH_HAS_STRICT_KERNEL_RWX
	select ARCH_HAS_STRICT_MODULE_RWX
+9 −0
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
#ifndef __ASM_MEM_ENCRYPT_H
#define __ASM_MEM_ENCRYPT_H

#include <asm/rsi.h>

struct arm64_mem_crypt_ops {
	int (*encrypt)(unsigned long addr, int numpages);
	int (*decrypt)(unsigned long addr, int numpages);
@@ -12,4 +14,11 @@ int arm64_mem_crypt_ops_register(const struct arm64_mem_crypt_ops *ops);
int set_memory_encrypted(unsigned long addr, int numpages);
int set_memory_decrypted(unsigned long addr, int numpages);

int realm_register_memory_enc_ops(void);

static inline bool force_dma_unencrypted(struct device *dev)
{
	return is_realm_world();
}

#endif	/* __ASM_MEM_ENCRYPT_H */
+5 −0
Original line number Diff line number Diff line
@@ -684,6 +684,11 @@ static inline void set_pud_at(struct mm_struct *mm, unsigned long addr,
#define pgprot_nx(prot) \
	__pgprot_modify(prot, PTE_MAYBE_GP, PTE_PXN)

#define pgprot_decrypted(prot) \
	__pgprot_modify(prot, PROT_NS_SHARED, PROT_NS_SHARED)
#define pgprot_encrypted(prot) \
	__pgprot_modify(prot, PROT_NS_SHARED, 0)

/*
 * Mark the prot value as uncacheable and unbufferable.
 */
+3 −0
Original line number Diff line number Diff line
@@ -15,4 +15,7 @@ int set_direct_map_invalid_noflush(struct page *page);
int set_direct_map_default_noflush(struct page *page);
bool kernel_page_present(struct page *page);

int set_memory_encrypted(unsigned long addr, int numpages);
int set_memory_decrypted(unsigned long addr, int numpages);

#endif /* _ASM_ARM64_SET_MEMORY_H */
+16 −0
Original line number Diff line number Diff line
@@ -7,8 +7,10 @@
#include <linux/memblock.h>
#include <linux/psci.h>
#include <linux/swiotlb.h>
#include <linux/cc_platform.h>

#include <asm/io.h>
#include <asm/mem_encrypt.h>
#include <asm/rsi.h>

static struct realm_config config;
@@ -19,6 +21,17 @@ EXPORT_SYMBOL(prot_ns_shared);
DEFINE_STATIC_KEY_FALSE_RO(rsi_present);
EXPORT_SYMBOL(rsi_present);

bool cc_platform_has(enum cc_attr attr)
{
	switch (attr) {
	case CC_ATTR_MEM_ENCRYPT:
		return is_realm_world();
	default:
		return false;
	}
}
EXPORT_SYMBOL_GPL(cc_platform_has);

static bool rsi_version_matches(void)
{
	unsigned long ver_lower, ver_higher;
@@ -119,6 +132,9 @@ void __init arm64_rsi_init(void)
	if (arm64_ioremap_prot_hook_register(realm_ioremap_hook))
		return;

	if (realm_register_memory_enc_ops())
		return;

	arm64_rsi_setup_memory();

	static_branch_enable(&rsi_present);
Loading