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 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 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 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 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