Skip to content

Commit 20f07a0

Browse files
kirylsuryasaimadhu
authored andcommitted
x86/sev: Move common memory encryption code to mem_encrypt.c
SEV and TDX both protect guest memory from host accesses. They both use guest physical address bits to communicate to the hardware which pages receive protection or not. SEV and TDX both assume that all I/O (real devices and virtio) must be performed to pages *without* protection. To add this support, AMD SEV code forces force_dma_unencrypted() to decrypt DMA pages when DMA pages were allocated for I/O. It also uses swiotlb_update_mem_attributes() to update decryption bits in SWIOTLB DMA buffers. Since TDX also uses a similar memory sharing design, all the above mentioned changes can be reused. So move force_dma_unencrypted(), SWIOTLB update code and virtio changes out of mem_encrypt_amd.c to mem_encrypt.c. Introduce a new config option X86_MEM_ENCRYPT that can be selected by platforms which use x86 memory encryption features (needed in both AMD SEV and Intel TDX guest platforms). Since the code is moved from mem_encrypt_amd.c, inherit the same make flags. This is preparation for enabling TDX memory encryption support and it has no functional changes. Co-developed-by: Kuppuswamy Sathyanarayanan <[email protected]> Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]> Signed-off-by: Kirill A. Shutemov <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Reviewed-by: Andi Kleen <[email protected]> Reviewed-by: Tony Luck <[email protected]> Reviewed-by: Tom Lendacky <[email protected]> Tested-by: Tom Lendacky <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent dbca5e1 commit 20f07a0

File tree

4 files changed

+96
-72
lines changed

4 files changed

+96
-72
lines changed

arch/x86/Kconfig

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,16 +1523,20 @@ config X86_CPA_STATISTICS
15231523
helps to determine the effectiveness of preserving large and huge
15241524
page mappings when mapping protections are changed.
15251525

1526+
config X86_MEM_ENCRYPT
1527+
select ARCH_HAS_FORCE_DMA_UNENCRYPTED
1528+
select DYNAMIC_PHYSICAL_MASK
1529+
select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
1530+
def_bool n
1531+
15261532
config AMD_MEM_ENCRYPT
15271533
bool "AMD Secure Memory Encryption (SME) support"
15281534
depends on X86_64 && CPU_SUP_AMD
15291535
select DMA_COHERENT_POOL
1530-
select DYNAMIC_PHYSICAL_MASK
15311536
select ARCH_USE_MEMREMAP_PROT
1532-
select ARCH_HAS_FORCE_DMA_UNENCRYPTED
15331537
select INSTRUCTION_DECODER
1534-
select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
15351538
select ARCH_HAS_CC_PLATFORM
1539+
select X86_MEM_ENCRYPT
15361540
help
15371541
Say yes to enable support for the encryption of system memory.
15381542
This requires an AMD processor that supports Secure Memory

arch/x86/mm/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# SPDX-License-Identifier: GPL-2.0
22
# Kernel does not boot with instrumentation of tlb.c and mem_encrypt*.c
33
KCOV_INSTRUMENT_tlb.o := n
4+
KCOV_INSTRUMENT_mem_encrypt.o := n
45
KCOV_INSTRUMENT_mem_encrypt_amd.o := n
56
KCOV_INSTRUMENT_mem_encrypt_identity.o := n
67

8+
KASAN_SANITIZE_mem_encrypt.o := n
79
KASAN_SANITIZE_mem_encrypt_amd.o := n
810
KASAN_SANITIZE_mem_encrypt_identity.o := n
911

@@ -12,6 +14,7 @@ KASAN_SANITIZE_mem_encrypt_identity.o := n
1214
KCSAN_SANITIZE := n
1315

1416
ifdef CONFIG_FUNCTION_TRACER
17+
CFLAGS_REMOVE_mem_encrypt.o = -pg
1518
CFLAGS_REMOVE_mem_encrypt_amd.o = -pg
1619
CFLAGS_REMOVE_mem_encrypt_identity.o = -pg
1720
endif
@@ -52,6 +55,8 @@ obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o
5255
obj-$(CONFIG_RANDOMIZE_MEMORY) += kaslr.o
5356
obj-$(CONFIG_PAGE_TABLE_ISOLATION) += pti.o
5457

58+
obj-$(CONFIG_X86_MEM_ENCRYPT) += mem_encrypt.o
5559
obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt_amd.o
60+
5661
obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt_identity.o
5762
obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt_boot.o

arch/x86/mm/mem_encrypt.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Memory Encryption Support Common Code
4+
*
5+
* Copyright (C) 2016 Advanced Micro Devices, Inc.
6+
*
7+
* Author: Tom Lendacky <[email protected]>
8+
*/
9+
10+
#include <linux/dma-direct.h>
11+
#include <linux/dma-mapping.h>
12+
#include <linux/swiotlb.h>
13+
#include <linux/cc_platform.h>
14+
#include <linux/mem_encrypt.h>
15+
#include <linux/virtio_config.h>
16+
17+
/* Override for DMA direct allocation check - ARCH_HAS_FORCE_DMA_UNENCRYPTED */
18+
bool force_dma_unencrypted(struct device *dev)
19+
{
20+
/*
21+
* For SEV, all DMA must be to unencrypted addresses.
22+
*/
23+
if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
24+
return true;
25+
26+
/*
27+
* For SME, all DMA must be to unencrypted addresses if the
28+
* device does not support DMA to addresses that include the
29+
* encryption mask.
30+
*/
31+
if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
32+
u64 dma_enc_mask = DMA_BIT_MASK(__ffs64(sme_me_mask));
33+
u64 dma_dev_mask = min_not_zero(dev->coherent_dma_mask,
34+
dev->bus_dma_limit);
35+
36+
if (dma_dev_mask <= dma_enc_mask)
37+
return true;
38+
}
39+
40+
return false;
41+
}
42+
43+
static void print_mem_encrypt_feature_info(void)
44+
{
45+
pr_info("AMD Memory Encryption Features active:");
46+
47+
/* Secure Memory Encryption */
48+
if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
49+
/*
50+
* SME is mutually exclusive with any of the SEV
51+
* features below.
52+
*/
53+
pr_cont(" SME\n");
54+
return;
55+
}
56+
57+
/* Secure Encrypted Virtualization */
58+
if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
59+
pr_cont(" SEV");
60+
61+
/* Encrypted Register State */
62+
if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
63+
pr_cont(" SEV-ES");
64+
65+
pr_cont("\n");
66+
}
67+
68+
/* Architecture __weak replacement functions */
69+
void __init mem_encrypt_init(void)
70+
{
71+
if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
72+
return;
73+
74+
/* Call into SWIOTLB to update the SWIOTLB DMA buffers */
75+
swiotlb_update_mem_attributes();
76+
77+
print_mem_encrypt_feature_info();
78+
}
79+
80+
int arch_has_restricted_virtio_memory_access(void)
81+
{
82+
return cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT);
83+
}
84+
EXPORT_SYMBOL_GPL(arch_has_restricted_virtio_memory_access);

arch/x86/mm/mem_encrypt_amd.c

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -413,32 +413,6 @@ void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, boo
413413
notify_range_enc_status_changed(vaddr, npages, enc);
414414
}
415415

416-
/* Override for DMA direct allocation check - ARCH_HAS_FORCE_DMA_UNENCRYPTED */
417-
bool force_dma_unencrypted(struct device *dev)
418-
{
419-
/*
420-
* For SEV, all DMA must be to unencrypted addresses.
421-
*/
422-
if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
423-
return true;
424-
425-
/*
426-
* For SME, all DMA must be to unencrypted addresses if the
427-
* device does not support DMA to addresses that include the
428-
* encryption mask.
429-
*/
430-
if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
431-
u64 dma_enc_mask = DMA_BIT_MASK(__ffs64(sme_me_mask));
432-
u64 dma_dev_mask = min_not_zero(dev->coherent_dma_mask,
433-
dev->bus_dma_limit);
434-
435-
if (dma_dev_mask <= dma_enc_mask)
436-
return true;
437-
}
438-
439-
return false;
440-
}
441-
442416
void __init mem_encrypt_free_decrypted_mem(void)
443417
{
444418
unsigned long vaddr, vaddr_end, npages;
@@ -462,46 +436,3 @@ void __init mem_encrypt_free_decrypted_mem(void)
462436

463437
free_init_pages("unused decrypted", vaddr, vaddr_end);
464438
}
465-
466-
static void print_mem_encrypt_feature_info(void)
467-
{
468-
pr_info("AMD Memory Encryption Features active:");
469-
470-
/* Secure Memory Encryption */
471-
if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
472-
/*
473-
* SME is mutually exclusive with any of the SEV
474-
* features below.
475-
*/
476-
pr_cont(" SME\n");
477-
return;
478-
}
479-
480-
/* Secure Encrypted Virtualization */
481-
if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
482-
pr_cont(" SEV");
483-
484-
/* Encrypted Register State */
485-
if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
486-
pr_cont(" SEV-ES");
487-
488-
pr_cont("\n");
489-
}
490-
491-
/* Architecture __weak replacement functions */
492-
void __init mem_encrypt_init(void)
493-
{
494-
if (!sme_me_mask)
495-
return;
496-
497-
/* Call into SWIOTLB to update the SWIOTLB DMA buffers */
498-
swiotlb_update_mem_attributes();
499-
500-
print_mem_encrypt_feature_info();
501-
}
502-
503-
int arch_has_restricted_virtio_memory_access(void)
504-
{
505-
return cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT);
506-
}
507-
EXPORT_SYMBOL_GPL(arch_has_restricted_virtio_memory_access);

0 commit comments

Comments
 (0)