Messages in this thread | | | Date | Tue, 03 Jan 2023 10:17:16 -0800 | Subject | Re: [PATCH v10 016/108] KVM: TDX: create/destroy VM structure | From | Ackerley Tng <> |
| |
Happy to help!
Nope it wasn't any special technique, I was working on the selftests and made a mistake configuring the TD while initializing it.
While setting up struct kvm_tdx_init_vm, I did not copy the entire struct kvm_cpuid2.
This reliably reproduces the crash:
--------
// SPDX-License-Identifier: GPL-2.0-only
#include "kvm_util_base.h" #include <processor.h>
static int tdx_ioctl(int fd, int ioctl_no, uint32_t flags, void *data) { struct kvm_tdx_cmd tdx_cmd;
memset(&tdx_cmd, 0x0, sizeof(tdx_cmd)); tdx_cmd.id = ioctl_no; tdx_cmd.flags = flags; tdx_cmd.data = (uint64_t)data; return ioctl(fd, KVM_MEMORY_ENCRYPT_OP, &tdx_cmd); }
#define XFEATURE_LBR 15 #define XFEATURE_XTILECFG 17 #define XFEATURE_XTILEDATA 18 #define XFEATURE_CET_U 11 #define XFEATURE_CET_S 12
#define XFEATURE_MASK_LBR (1 << XFEATURE_LBR) #define XFEATURE_MASK_CET_U (1 << XFEATURE_CET_U) #define XFEATURE_MASK_CET_S (1 << XFEATURE_CET_S) #define XFEATURE_MASK_CET (XFEATURE_MASK_CET_U | XFEATURE_MASK_CET_S) #define XFEATURE_MASK_XTILECFG (1 << XFEATURE_XTILECFG) #define XFEATURE_MASK_XTILEDATA (1 << XFEATURE_XTILEDATA) #define XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILECFG | XFEATURE_MASK_XTILEDATA)
static void apply_tdx_restrictions(struct kvm_cpuid2 *cpuid_data) { for (int i = 0; i < 100; i++) { struct kvm_cpuid_entry2 *e = &cpuid_data->entries[i];
if (e->function == 0xd && e->index == 0) { /* * TDX module requires both XTILE_{CFG, DATA} to be set. * Both bits are required for AMX to be functional. */ if ((e->eax & XFEATURE_MASK_XTILE) != XFEATURE_MASK_XTILE) { e->eax &= ~XFEATURE_MASK_XTILE; } }
if (e->function == 0xd && e->index == 1) { /* * TDX doesn't support LBR yet. * Disable bits from the XCR0 register. */ e->ecx &= ~XFEATURE_MASK_LBR;
/* * TDX modules requires both CET_{U, S} to be set even * if only one is supported. */ if (e->ecx & XFEATURE_MASK_CET) e->ecx |= XFEATURE_MASK_CET; } } }
void initialize_td_bad(struct kvm_vm *vm) { const struct kvm_cpuid2 *cpuid; int rc;
/* No guest VMM controlled cpuid information yet. */ struct kvm_tdx_init_vm init_vm;
rc = kvm_check_cap(KVM_CAP_X2APIC_API); TEST_ASSERT(rc, "TDX: KVM_CAP_X2APIC_API is not supported!"); rc = kvm_check_cap(KVM_CAP_SPLIT_IRQCHIP); TEST_ASSERT(rc, "TDX: KVM_CAP_SPLIT_IRQCHIP is not supported!");
vm_enable_cap(vm, KVM_CAP_X2APIC_API, KVM_X2APIC_API_USE_32BIT_IDS | KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK); vm_enable_cap(vm, KVM_CAP_SPLIT_IRQCHIP, 24);
/* Allocate and setup memory for the td guest. */ vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, 0, 0, 1, 0);
cpuid = kvm_get_supported_cpuid(); apply_tdx_restrictions((struct kvm_cpuid2 *) cpuid);
memset(&init_vm, 0, sizeof(init_vm)); init_vm.attributes = 0;
/* * Should have been kvm_cpuid2_size(cpuid->nent) instead of * sizeof(*cpuid) */ memcpy(&init_vm.cpuid, cpuid, sizeof(*cpuid));
rc = tdx_ioctl(vm->fd, KVM_TDX_INIT_VM, 0, &init_vm); TEST_ASSERT(rc == 0, "KVM_TDX_INIT_VM failed: %d %d", rc, errno); }
static int crash(void) { struct kvm_vm *vm;
/* Create a TD VM with no memory.*/ vm = ____vm_create(VM_MODE_DEFAULT, 0, KVM_X86_TDX_VM);
/* Allocate TD guest memory and initialize the TD.*/ initialize_td_bad(vm);
return 0; }
int main(int argc, char **argv) { /* Disable stdout buffering */ setbuf(stdout, NULL);
return crash(); }
| |