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

arm64: mm: Add top-level dispatcher for internal mem_encrypt API

Implementing the internal mem_encrypt API for arm64 depends entirely on
the Confidential Computing environment in which the kernel is running.

Introduce a simple dispatcher so that backend hooks can be registered
depending upon the environment in which the kernel finds itself.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Acked-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240830130150.8568-4-will@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>

+68 -1
+1
arch/arm64/Kconfig
··· 34 34 select ARCH_HAS_KERNEL_FPU_SUPPORT if KERNEL_MODE_NEON 35 35 select ARCH_HAS_KEEPINITRD 36 36 select ARCH_HAS_MEMBARRIER_SYNC_CORE 37 + select ARCH_HAS_MEM_ENCRYPT 37 38 select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS 38 39 select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE 39 40 select ARCH_HAS_PTE_DEVMAP
+15
arch/arm64/include/asm/mem_encrypt.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + #ifndef __ASM_MEM_ENCRYPT_H 3 + #define __ASM_MEM_ENCRYPT_H 4 + 5 + struct arm64_mem_crypt_ops { 6 + int (*encrypt)(unsigned long addr, int numpages); 7 + int (*decrypt)(unsigned long addr, int numpages); 8 + }; 9 + 10 + int arm64_mem_crypt_ops_register(const struct arm64_mem_crypt_ops *ops); 11 + 12 + int set_memory_encrypted(unsigned long addr, int numpages); 13 + int set_memory_decrypted(unsigned long addr, int numpages); 14 + 15 + #endif /* __ASM_MEM_ENCRYPT_H */
+1
arch/arm64/include/asm/set_memory.h
··· 3 3 #ifndef _ASM_ARM64_SET_MEMORY_H 4 4 #define _ASM_ARM64_SET_MEMORY_H 5 5 6 + #include <asm/mem_encrypt.h> 6 7 #include <asm-generic/set_memory.h> 7 8 8 9 bool can_set_direct_map(void);
+1 -1
arch/arm64/mm/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-y := dma-mapping.o extable.o fault.o init.o \ 3 3 cache.o copypage.o flush.o \ 4 - ioremap.o mmap.o pgd.o mmu.o \ 4 + ioremap.o mmap.o pgd.o mem_encrypt.o mmu.o \ 5 5 context.o proc.o pageattr.o fixmap.o 6 6 obj-$(CONFIG_ARM64_CONTPTE) += contpte.o 7 7 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+50
arch/arm64/mm/mem_encrypt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Implementation of the memory encryption/decryption API. 4 + * 5 + * Since the low-level details of the operation depend on the 6 + * Confidential Computing environment (e.g. pKVM, CCA, ...), this just 7 + * acts as a top-level dispatcher to whatever hooks may have been 8 + * registered. 9 + * 10 + * Author: Will Deacon <will@kernel.org> 11 + * Copyright (C) 2024 Google LLC 12 + * 13 + * "Hello, boils and ghouls!" 14 + */ 15 + 16 + #include <linux/bug.h> 17 + #include <linux/compiler.h> 18 + #include <linux/err.h> 19 + #include <linux/mm.h> 20 + 21 + #include <asm/mem_encrypt.h> 22 + 23 + static const struct arm64_mem_crypt_ops *crypt_ops; 24 + 25 + int arm64_mem_crypt_ops_register(const struct arm64_mem_crypt_ops *ops) 26 + { 27 + if (WARN_ON(crypt_ops)) 28 + return -EBUSY; 29 + 30 + crypt_ops = ops; 31 + return 0; 32 + } 33 + 34 + int set_memory_encrypted(unsigned long addr, int numpages) 35 + { 36 + if (likely(!crypt_ops) || WARN_ON(!PAGE_ALIGNED(addr))) 37 + return 0; 38 + 39 + return crypt_ops->encrypt(addr, numpages); 40 + } 41 + EXPORT_SYMBOL_GPL(set_memory_encrypted); 42 + 43 + int set_memory_decrypted(unsigned long addr, int numpages) 44 + { 45 + if (likely(!crypt_ops) || WARN_ON(!PAGE_ALIGNED(addr))) 46 + return 0; 47 + 48 + return crypt_ops->decrypt(addr, numpages); 49 + } 50 + EXPORT_SYMBOL_GPL(set_memory_decrypted);