blob: 7757d4f85b7a33a2f4c42d8d82cc25a1d47d33aa [file] [log] [blame]
/*
* AMD SEV test cases
*
* Copyright (c) 2021, Google Inc
*
* Authors:
* Hyunwook (Wooky) Baek <baekhw@google.com>
* Zixuan Wang <zixuanwang@google.com>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "libcflat.h"
#include "x86/processor.h"
#include "x86/amd_sev.h"
#include "msr.h"
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
#define TESTDEV_IO_PORT 0xe0
static char st1[] = "abcdefghijklmnop";
static int test_sev_activation(void)
{
struct cpuid cpuid_out;
u64 msr_out;
printf("SEV activation test is loaded.\n");
/* Tests if CPUID function to check SEV is implemented */
cpuid_out = cpuid(CPUID_FN_LARGEST_EXT_FUNC_NUM);
printf("CPUID Fn8000_0000[EAX]: 0x%08x\n", cpuid_out.a);
if (cpuid_out.a < CPUID_FN_ENCRYPT_MEM_CAPAB) {
printf("CPUID does not support FN%08x\n",
CPUID_FN_ENCRYPT_MEM_CAPAB);
return EXIT_FAILURE;
}
/* Tests if SEV is supported */
cpuid_out = cpuid(CPUID_FN_ENCRYPT_MEM_CAPAB);
printf("CPUID Fn8000_001F[EAX]: 0x%08x\n", cpuid_out.a);
printf("CPUID Fn8000_001F[EBX]: 0x%08x\n", cpuid_out.b);
if (!(cpuid_out.a & SEV_SUPPORT_MASK)) {
printf("SEV is not supported.\n");
return EXIT_FAILURE;
}
printf("SEV is supported\n");
/* Tests if SEV is enabled */
msr_out = rdmsr(MSR_SEV_STATUS);
printf("MSR C001_0131[EAX]: 0x%08lx\n", msr_out & 0xffffffff);
if (!(msr_out & SEV_ENABLED_MASK)) {
printf("SEV is not enabled.\n");
return EXIT_FAILURE;
}
printf("SEV is enabled\n");
return EXIT_SUCCESS;
}
static void test_sev_es_activation(void)
{
if (rdmsr(MSR_SEV_STATUS) & SEV_ES_ENABLED_MASK) {
printf("SEV-ES is enabled.\n");
} else {
printf("SEV-ES is not enabled.\n");
}
}
static void test_stringio(void)
{
int st1_len = sizeof(st1) - 1;
u16 got;
asm volatile("cld \n\t"
"movw %0, %%dx \n\t"
"rep outsw \n\t"
: : "i"((short)TESTDEV_IO_PORT),
"S"(st1), "c"(st1_len / 2));
asm volatile("inw %1, %0\n\t" : "=a"(got) : "i"((short)TESTDEV_IO_PORT));
report((got & 0xff) == st1[sizeof(st1) - 3], "outsb nearly up");
report((got & 0xff00) >> 8 == st1[sizeof(st1) - 2], "outsb up");
}
int main(void)
{
int rtn;
rtn = test_sev_activation();
report(rtn == EXIT_SUCCESS, "SEV activation test.");
test_sev_es_activation();
test_stringio();
return report_summary();
}