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