xref: /kvm-unit-tests/x86/amd_sev.c (revision 92a6c9b95ab10eba66bff3ff44476ab0c015b276)
1350bf64aSZixuan Wang /*
2350bf64aSZixuan Wang  * AMD SEV test cases
3350bf64aSZixuan Wang  *
4350bf64aSZixuan Wang  * Copyright (c) 2021, Google Inc
5350bf64aSZixuan Wang  *
6350bf64aSZixuan Wang  * Authors:
7350bf64aSZixuan Wang  *   Hyunwook (Wooky) Baek <baekhw@google.com>
8350bf64aSZixuan Wang  *   Zixuan Wang <zixuanwang@google.com>
9350bf64aSZixuan Wang  *
10350bf64aSZixuan Wang  * SPDX-License-Identifier: LGPL-2.0-or-later
11350bf64aSZixuan Wang  */
12350bf64aSZixuan Wang 
13350bf64aSZixuan Wang #include "libcflat.h"
14350bf64aSZixuan Wang #include "x86/processor.h"
15350bf64aSZixuan Wang #include "x86/amd_sev.h"
168e38cb32SPaolo Bonzini #include "msr.h"
17350bf64aSZixuan Wang 
18350bf64aSZixuan Wang #define EXIT_SUCCESS 0
19350bf64aSZixuan Wang #define EXIT_FAILURE 1
20350bf64aSZixuan Wang 
21*ef9094a5SMarc Orr #define TESTDEV_IO_PORT 0xe0
22*ef9094a5SMarc Orr 
23*ef9094a5SMarc Orr static char st1[] = "abcdefghijklmnop";
24*ef9094a5SMarc Orr 
test_sev_activation(void)25350bf64aSZixuan Wang static int test_sev_activation(void)
26350bf64aSZixuan Wang {
27350bf64aSZixuan Wang 	struct cpuid cpuid_out;
28350bf64aSZixuan Wang 	u64 msr_out;
29350bf64aSZixuan Wang 
30350bf64aSZixuan Wang 	printf("SEV activation test is loaded.\n");
31350bf64aSZixuan Wang 
32350bf64aSZixuan Wang 	/* Tests if CPUID function to check SEV is implemented */
33350bf64aSZixuan Wang 	cpuid_out = cpuid(CPUID_FN_LARGEST_EXT_FUNC_NUM);
34350bf64aSZixuan Wang 	printf("CPUID Fn8000_0000[EAX]: 0x%08x\n", cpuid_out.a);
35350bf64aSZixuan Wang 	if (cpuid_out.a < CPUID_FN_ENCRYPT_MEM_CAPAB) {
36350bf64aSZixuan Wang 		printf("CPUID does not support FN%08x\n",
37350bf64aSZixuan Wang 		       CPUID_FN_ENCRYPT_MEM_CAPAB);
38350bf64aSZixuan Wang 		return EXIT_FAILURE;
39350bf64aSZixuan Wang 	}
40350bf64aSZixuan Wang 
41350bf64aSZixuan Wang 	/* Tests if SEV is supported */
42350bf64aSZixuan Wang 	cpuid_out = cpuid(CPUID_FN_ENCRYPT_MEM_CAPAB);
43350bf64aSZixuan Wang 	printf("CPUID Fn8000_001F[EAX]: 0x%08x\n", cpuid_out.a);
44350bf64aSZixuan Wang 	printf("CPUID Fn8000_001F[EBX]: 0x%08x\n", cpuid_out.b);
45350bf64aSZixuan Wang 	if (!(cpuid_out.a & SEV_SUPPORT_MASK)) {
46350bf64aSZixuan Wang 		printf("SEV is not supported.\n");
47350bf64aSZixuan Wang 		return EXIT_FAILURE;
48350bf64aSZixuan Wang 	}
49350bf64aSZixuan Wang 	printf("SEV is supported\n");
50350bf64aSZixuan Wang 
51350bf64aSZixuan Wang 	/* Tests if SEV is enabled */
52350bf64aSZixuan Wang 	msr_out = rdmsr(MSR_SEV_STATUS);
53350bf64aSZixuan Wang 	printf("MSR C001_0131[EAX]: 0x%08lx\n", msr_out & 0xffffffff);
54350bf64aSZixuan Wang 	if (!(msr_out & SEV_ENABLED_MASK)) {
55350bf64aSZixuan Wang 		printf("SEV is not enabled.\n");
56350bf64aSZixuan Wang 		return EXIT_FAILURE;
57350bf64aSZixuan Wang 	}
58350bf64aSZixuan Wang 	printf("SEV is enabled\n");
59350bf64aSZixuan Wang 
60350bf64aSZixuan Wang 	return EXIT_SUCCESS;
61350bf64aSZixuan Wang }
62350bf64aSZixuan Wang 
test_sev_es_activation(void)638e38cb32SPaolo Bonzini static void test_sev_es_activation(void)
648e38cb32SPaolo Bonzini {
658e38cb32SPaolo Bonzini 	if (rdmsr(MSR_SEV_STATUS) & SEV_ES_ENABLED_MASK) {
668e38cb32SPaolo Bonzini 		printf("SEV-ES is enabled.\n");
678e38cb32SPaolo Bonzini 	} else {
688e38cb32SPaolo Bonzini 		printf("SEV-ES is not enabled.\n");
698e38cb32SPaolo Bonzini 	}
708e38cb32SPaolo Bonzini }
718e38cb32SPaolo Bonzini 
test_stringio(void)72*ef9094a5SMarc Orr static void test_stringio(void)
73*ef9094a5SMarc Orr {
74*ef9094a5SMarc Orr 	int st1_len = sizeof(st1) - 1;
75*ef9094a5SMarc Orr 	u16 got;
76*ef9094a5SMarc Orr 
77*ef9094a5SMarc Orr 	asm volatile("cld \n\t"
78*ef9094a5SMarc Orr 		     "movw %0, %%dx \n\t"
79*ef9094a5SMarc Orr 		     "rep outsw \n\t"
80*ef9094a5SMarc Orr 		     : : "i"((short)TESTDEV_IO_PORT),
81*ef9094a5SMarc Orr 		         "S"(st1), "c"(st1_len / 2));
82*ef9094a5SMarc Orr 
83*ef9094a5SMarc Orr 	asm volatile("inw %1, %0\n\t" : "=a"(got) : "i"((short)TESTDEV_IO_PORT));
84*ef9094a5SMarc Orr 
85*ef9094a5SMarc Orr 	report((got & 0xff) == st1[sizeof(st1) - 3], "outsb nearly up");
86*ef9094a5SMarc Orr 	report((got & 0xff00) >> 8 == st1[sizeof(st1) - 2], "outsb up");
87*ef9094a5SMarc Orr }
88*ef9094a5SMarc Orr 
main(void)89350bf64aSZixuan Wang int main(void)
90350bf64aSZixuan Wang {
91350bf64aSZixuan Wang 	int rtn;
92350bf64aSZixuan Wang 	rtn = test_sev_activation();
93350bf64aSZixuan Wang 	report(rtn == EXIT_SUCCESS, "SEV activation test.");
948e38cb32SPaolo Bonzini 	test_sev_es_activation();
95*ef9094a5SMarc Orr 	test_stringio();
96350bf64aSZixuan Wang 	return report_summary();
97350bf64aSZixuan Wang }
98