@@ -163,6 +163,11 @@ config ARCH_MMAP_RND_BITS_MAX
config ARCH_MMAP_RND_COMPAT_BITS_MAX
default 17
+config RISCV_MEM_ENCRYPT
+ select ARCH_HAS_MEM_ENCRYPT
+ select ARCH_HAS_FORCE_DMA_UNENCRYPTED
+ def_bool n
+
# set if we run in machine mode, cleared if we run in supervisor mode
config RISCV_M_MODE
bool
@@ -515,6 +520,8 @@ config RISCV_COVE_HOST
config RISCV_COVE_GUEST
bool "Guest Support for Confidential VM Extension(CoVE)"
default n
+ select SWIOTLB
+ select RISCV_MEM_ENCRYPT
help
Enables support for running TVMs on platforms supporting CoVE.
new file mode 100644
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * RISCV Memory Encryption Support.
+ *
+ * Copyright (c) 2023 Rivos Inc.
+ *
+ * Authors:
+ * Rajnesh Kanwal <rkanwal@rivosinc.com>
+ */
+
+#ifndef __RISCV_MEM_ENCRYPT_H__
+#define __RISCV_MEM_ENCRYPT_H__
+
+#include <linux/init.h>
+
+struct device;
+
+bool force_dma_unencrypted(struct device *dev);
+
+/* Architecture __weak replacement functions */
+void __init mem_encrypt_init(void);
+
+int set_memory_encrypted(unsigned long addr, int numpages);
+int set_memory_decrypted(unsigned long addr, int numpages);
+
+#endif /* __RISCV_MEM_ENCRYPT_H__ */
@@ -33,3 +33,5 @@ endif
obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
obj-$(CONFIG_RISCV_DMA_NONCOHERENT) += dma-noncoherent.o
+
+obj-$(CONFIG_RISCV_MEM_ENCRYPT) += mem_encrypt.o
@@ -21,6 +21,7 @@
#include <linux/crash_dump.h>
#include <linux/hugetlb.h>
+#include <asm/cove.h>
#include <asm/fixmap.h>
#include <asm/tlbflush.h>
#include <asm/sections.h>
@@ -156,11 +157,25 @@ static void print_vm_layout(void) { }
void __init mem_init(void)
{
+ unsigned int flags = SWIOTLB_VERBOSE;
+ bool swiotlb_en;
+
+ if (is_cove_guest()) {
+ /* Since the guest memory is inaccessible to the host, devices
+ * always need to use the SWIOTLB buffer for DMA even if
+ * dma_capable() says otherwise.
+ */
+ flags |= SWIOTLB_FORCE;
+ swiotlb_en = true;
+ } else {
+ swiotlb_en = !!(max_pfn > PFN_DOWN(dma32_phys_limit));
+ }
+
#ifdef CONFIG_FLATMEM
BUG_ON(!mem_map);
#endif /* CONFIG_FLATMEM */
- swiotlb_init(max_pfn > PFN_DOWN(dma32_phys_limit), SWIOTLB_VERBOSE);
+ swiotlb_init(swiotlb_en, flags);
memblock_free_all();
print_vm_layout();
new file mode 100644
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Rivos Inc.
+ *
+ * Authors:
+ * Rajnesh Kanwal <rkanwal@rivosinc.com>
+ */
+
+#include <linux/dma-direct.h>
+#include <linux/swiotlb.h>
+#include <linux/cc_platform.h>
+#include <linux/mem_encrypt.h>
+#include <asm/covg_sbi.h>
+
+/* Override for DMA direct allocation check - ARCH_HAS_FORCE_DMA_UNENCRYPTED */
+bool force_dma_unencrypted(struct device *dev)
+{
+ /*
+ * For authorized devices in trusted guest, all DMA must be to/from
+ * unencrypted addresses.
+ */
+ return cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT);
+}
+
+int set_memory_encrypted(unsigned long addr, int numpages)
+{
+ if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
+ return 0;
+
+ if (!PAGE_ALIGNED(addr))
+ return -EINVAL;
+
+ return sbi_covg_unshare_memory(__pa(addr), numpages * PAGE_SIZE);
+}
+EXPORT_SYMBOL_GPL(set_memory_encrypted);
+
+int set_memory_decrypted(unsigned long addr, int numpages)
+{
+ if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
+ return 0;
+
+ if (!PAGE_ALIGNED(addr))
+ return -EINVAL;
+
+ return sbi_covg_share_memory(__pa(addr), numpages * PAGE_SIZE);
+}
+EXPORT_SYMBOL_GPL(set_memory_decrypted);
+
+/* Architecture __weak replacement functions */
+void __init mem_encrypt_init(void)
+{
+ if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
+ return;
+
+ /* Call into SWIOTLB to update the SWIOTLB DMA buffers */
+ swiotlb_update_mem_attributes();
+}