xref: /kvm-unit-tests/x86/amd_sev.c (revision 92a6c9b95ab10eba66bff3ff44476ab0c015b276)
1 /*
2  * AMD SEV test cases
3  *
4  * Copyright (c) 2021, Google Inc
5  *
6  * Authors:
7  *   Hyunwook (Wooky) Baek <baekhw@google.com>
8  *   Zixuan Wang <zixuanwang@google.com>
9  *
10  * SPDX-License-Identifier: LGPL-2.0-or-later
11  */
12 
13 #include "libcflat.h"
14 #include "x86/processor.h"
15 #include "x86/amd_sev.h"
16 #include "msr.h"
17 
18 #define EXIT_SUCCESS 0
19 #define EXIT_FAILURE 1
20 
21 #define TESTDEV_IO_PORT 0xe0
22 
23 static char st1[] = "abcdefghijklmnop";
24 
test_sev_activation(void)25 static int test_sev_activation(void)
26 {
27 	struct cpuid cpuid_out;
28 	u64 msr_out;
29 
30 	printf("SEV activation test is loaded.\n");
31 
32 	/* Tests if CPUID function to check SEV is implemented */
33 	cpuid_out = cpuid(CPUID_FN_LARGEST_EXT_FUNC_NUM);
34 	printf("CPUID Fn8000_0000[EAX]: 0x%08x\n", cpuid_out.a);
35 	if (cpuid_out.a < CPUID_FN_ENCRYPT_MEM_CAPAB) {
36 		printf("CPUID does not support FN%08x\n",
37 		       CPUID_FN_ENCRYPT_MEM_CAPAB);
38 		return EXIT_FAILURE;
39 	}
40 
41 	/* Tests if SEV is supported */
42 	cpuid_out = cpuid(CPUID_FN_ENCRYPT_MEM_CAPAB);
43 	printf("CPUID Fn8000_001F[EAX]: 0x%08x\n", cpuid_out.a);
44 	printf("CPUID Fn8000_001F[EBX]: 0x%08x\n", cpuid_out.b);
45 	if (!(cpuid_out.a & SEV_SUPPORT_MASK)) {
46 		printf("SEV is not supported.\n");
47 		return EXIT_FAILURE;
48 	}
49 	printf("SEV is supported\n");
50 
51 	/* Tests if SEV is enabled */
52 	msr_out = rdmsr(MSR_SEV_STATUS);
53 	printf("MSR C001_0131[EAX]: 0x%08lx\n", msr_out & 0xffffffff);
54 	if (!(msr_out & SEV_ENABLED_MASK)) {
55 		printf("SEV is not enabled.\n");
56 		return EXIT_FAILURE;
57 	}
58 	printf("SEV is enabled\n");
59 
60 	return EXIT_SUCCESS;
61 }
62 
test_sev_es_activation(void)63 static void test_sev_es_activation(void)
64 {
65 	if (rdmsr(MSR_SEV_STATUS) & SEV_ES_ENABLED_MASK) {
66 		printf("SEV-ES is enabled.\n");
67 	} else {
68 		printf("SEV-ES is not enabled.\n");
69 	}
70 }
71 
test_stringio(void)72 static void test_stringio(void)
73 {
74 	int st1_len = sizeof(st1) - 1;
75 	u16 got;
76 
77 	asm volatile("cld \n\t"
78 		     "movw %0, %%dx \n\t"
79 		     "rep outsw \n\t"
80 		     : : "i"((short)TESTDEV_IO_PORT),
81 		         "S"(st1), "c"(st1_len / 2));
82 
83 	asm volatile("inw %1, %0\n\t" : "=a"(got) : "i"((short)TESTDEV_IO_PORT));
84 
85 	report((got & 0xff) == st1[sizeof(st1) - 3], "outsb nearly up");
86 	report((got & 0xff00) >> 8 == st1[sizeof(st1) - 2], "outsb up");
87 }
88 
main(void)89 int main(void)
90 {
91 	int rtn;
92 	rtn = test_sev_activation();
93 	report(rtn == EXIT_SUCCESS, "SEV activation test.");
94 	test_sev_es_activation();
95 	test_stringio();
96 	return report_summary();
97 }
98