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 <thomas.lendacky@amd.com>
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 
16 /* Override for DMA direct allocation check - ARCH_HAS_FORCE_DMA_UNENCRYPTED */
force_dma_unencrypted(struct device * dev)17 bool force_dma_unencrypted(struct device *dev)
18 {
19 	/*
20 	 * For SEV, all DMA must be to unencrypted addresses.
21 	 */
22 	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
23 		return true;
24 
25 	/*
26 	 * For SME, all DMA must be to unencrypted addresses if the
27 	 * device does not support DMA to addresses that include the
28 	 * encryption mask.
29 	 */
30 	if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
31 		u64 dma_enc_mask = DMA_BIT_MASK(__ffs64(sme_me_mask));
32 		u64 dma_dev_mask = min_not_zero(dev->coherent_dma_mask,
33 						dev->bus_dma_limit);
34 
35 		if (dma_dev_mask <= dma_enc_mask)
36 			return true;
37 	}
38 
39 	return false;
40 }
41 
print_mem_encrypt_feature_info(void)42 static void print_mem_encrypt_feature_info(void)
43 {
44 	pr_info("Memory Encryption Features active:");
45 
46 	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) {
47 		pr_cont(" Intel TDX\n");
48 		return;
49 	}
50 
51 	pr_cont(" AMD");
52 
53 	/* Secure Memory Encryption */
54 	if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
55 		/*
56 		 * SME is mutually exclusive with any of the SEV
57 		 * features below.
58 		 */
59 		pr_cont(" SME\n");
60 		return;
61 	}
62 
63 	/* Secure Encrypted Virtualization */
64 	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
65 		pr_cont(" SEV");
66 
67 	/* Encrypted Register State */
68 	if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
69 		pr_cont(" SEV-ES");
70 
71 	/* Secure Nested Paging */
72 	if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
73 		pr_cont(" SEV-SNP");
74 
75 	pr_cont("\n");
76 }
77 
78 /* Architecture __weak replacement functions */
mem_encrypt_init(void)79 void __init mem_encrypt_init(void)
80 {
81 	if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
82 		return;
83 
84 	/* Call into SWIOTLB to update the SWIOTLB DMA buffers */
85 	swiotlb_update_mem_attributes();
86 
87 	print_mem_encrypt_feature_info();
88 }
89