Download raw body.
SEV-ES guest: Implement CPUID #VC, IOIO #VC, MSR #VC 3/3
Hi,
this is change 3/3. With this change, SEV-ES enabled guest can be run
on vmm(4)/vmd(8).
Fill in the handling of cpuid, in/out and rdmsr/wrmsr. For the
in/out and rdmsr/wrmsr we have to decode the actual instructions.
Use the GHCB to request emulation of these instructions from vmm(4).
Take care,
Hans-Joerg
--
commit dbe7557824d97848daf41c65ea0cef92a153ad50
Author: Hans-Joerg Hoexer <hshoexer@genua.de>
Date: Thu Nov 21 15:57:33 2024 +0100
SEV-ES guest: Implement CPUID #VC, IOIO #VC, MSR #VC
Fill in the handling of cpuid, in/out and rdmsr/wrmsr. For the
in/out and rdmsr/wrmsr we have to decode the actual instructions.
Use the GHCB to request emulation of these instructions from vmm(4).
With this change, SEV-ES enabled guest are able to run on vmm(4)/vmd(8).
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index bb445a60894..37b0dfbe8ba 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -305,6 +305,8 @@ int
vctrap(struct trapframe *frame)
{
uint64_t sw_exitcode, sw_exitinfo1, sw_exitinfo2;
+ uint8_t *rip = (uint8_t *)(frame->tf_rip);
+ uint16_t port;
struct ghcb_sync syncout, syncin;
struct ghcb_sa *ghcb;
@@ -318,6 +320,99 @@ vctrap(struct trapframe *frame)
sw_exitinfo2 = 0;
switch (sw_exitcode) {
+ case SVM_VMEXIT_CPUID:
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ32, &syncout);
+ ghcb_sync_val(GHCB_RCX, GHCB_SZ32, &syncout);
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ32, &syncin);
+ ghcb_sync_val(GHCB_RBX, GHCB_SZ32, &syncin);
+ ghcb_sync_val(GHCB_RCX, GHCB_SZ32, &syncin);
+ ghcb_sync_val(GHCB_RDX, GHCB_SZ32, &syncin);
+ frame->tf_rip += 2;
+ break;
+ case SVM_VMEXIT_MSR: {
+ if (*rip == 0x0f && *(rip + 1) == 0x30) {
+ /* WRMSR */
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ32, &syncout);
+ ghcb_sync_val(GHCB_RCX, GHCB_SZ32, &syncout);
+ ghcb_sync_val(GHCB_RDX, GHCB_SZ32, &syncout);
+ sw_exitinfo1 = 1;
+ } else if (*rip == 0x0f && *(rip + 1) == 0x32) {
+ /* RDMSR */
+ ghcb_sync_val(GHCB_RCX, GHCB_SZ32, &syncout);
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ32, &syncin);
+ ghcb_sync_val(GHCB_RDX, GHCB_SZ32, &syncin);
+ } else
+ panic("failed to decode MSR");
+ frame->tf_rip += 2;
+ break;
+ }
+ case SVM_VMEXIT_IOIO: {
+ switch (*rip) {
+ case 0x66: {
+ switch (*(rip + 1)) {
+ case 0xef: /* out %ax,(%dx) */
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ16, &syncout);
+ port = (uint16_t)frame->tf_rdx;
+ sw_exitinfo1 = (port << 16) |
+ (1ULL << 5);
+ frame->tf_rip += 2;
+ break;
+ case 0xed: /* in (%dx),%ax */
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ16, &syncin);
+ port = (uint16_t)frame->tf_rdx;
+ sw_exitinfo1 = (port << 16) |
+ (1ULL << 5) | (1ULL << 0);
+ frame->tf_rip += 2;
+ break;
+ default:
+ panic("failed to decode prefixed IOIO");
+ }
+ break;
+ }
+ case 0xe4: /* in $port,%al */
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ8, &syncin);
+ port = *(rip + 1);
+ sw_exitinfo1 = (port << 16) | (1ULL << 4) |
+ (1ULL << 0);
+ frame->tf_rip += 2;
+ break;
+ case 0xe6: /* outb %al,$port */
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ8, &syncout);
+ port = *(rip + 1);
+ sw_exitinfo1 = (port << 16) | (1ULL << 4);
+ frame->tf_rip += 2;
+ break;
+ case 0xec: /* in (%dx),%al */
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ8, &syncin);
+ port = (uint16_t)frame->tf_rdx;
+ sw_exitinfo1 = (port << 16) | (1ULL << 4) |
+ (1ULL << 0);
+ frame->tf_rip += 1;
+ break;
+ case 0xed: /* in (%dx),%eax */
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ32, &syncin);
+ port = (uint16_t)frame->tf_rdx;
+ sw_exitinfo1 = (port << 16) | (1ULL << 6) |
+ (1ULL << 0);
+ frame->tf_rip += 1;
+ break;
+ case 0xee: /* out %al,(%dx) */
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ8, &syncout);
+ port = (uint16_t)frame->tf_rdx;
+ sw_exitinfo1 = (port << 16) | (1ULL << 4);
+ frame->tf_rip += 1;
+ break;
+ case 0xef: /* out %eax,(%dx) */
+ ghcb_sync_val(GHCB_RAX, GHCB_SZ32, &syncout);
+ port = (uint16_t)frame->tf_rdx;
+ sw_exitinfo1 = (port << 16) | (1ULL << 6);
+ frame->tf_rip += 1;
+ break;
+ default:
+ panic("failed to decode IOIO");
+ }
+ break;
+ }
default:
panic("invalid exit code 0x%llx", sw_exitcode);
}
SEV-ES guest: Implement CPUID #VC, IOIO #VC, MSR #VC 3/3