Re: [RFC PATCH v5 15/29] KVM: selftests: TDX: Add TDX MSR read/write tests

From: Yan Zhao
Date: Mon Mar 04 2024 - 19:53:28 EST


> +void verify_guest_msr_writes(void)
> +{
> + struct kvm_vcpu *vcpu;
> + struct kvm_vm *vm;
> +
> + uint64_t data;
> + int ret;
> +
> + vm = td_create();
> + td_initialize(vm, VM_MEM_SRC_ANONYMOUS, 0);
> +
> + /*
> + * Set explicit MSR filter map to control access to the MSR registers
> + * used in the test.
> + */
> + printf("\t ... Setting test MSR filter\n");
> + ret = kvm_check_cap(KVM_CAP_X86_USER_SPACE_MSR);
> + TEST_ASSERT(ret, "KVM_CAP_X86_USER_SPACE_MSR is unavailable");
> + vm_enable_cap(vm, KVM_CAP_X86_USER_SPACE_MSR, KVM_MSR_EXIT_REASON_FILTER);
> +
> + ret = kvm_check_cap(KVM_CAP_X86_MSR_FILTER);
> + TEST_ASSERT(ret, "KVM_CAP_X86_MSR_FILTER is unavailable");
> +
> + ret = ioctl(vm->fd, KVM_X86_SET_MSR_FILTER, &tdx_msr_test_filter);
> + TEST_ASSERT(ret == 0,
> + "KVM_X86_SET_MSR_FILTER failed, ret: %i errno: %i (%s)",
> + ret, errno, strerror(errno));
> +
> + vcpu = td_vcpu_add(vm, 0, guest_msr_write);
> + td_finalize(vm);
> +
> + printf("Verifying guest msr writes:\n");
> +
> + printf("\t ... Running guest\n");
> + /* Only the write to MSR_IA32_MISC_ENABLE should trigger an exit */
> + td_vcpu_run(vcpu);
> + TDX_TEST_CHECK_GUEST_FAILURE(vcpu);
> + data = tdx_test_read_64bit_report_from_guest(vcpu);
> + TEST_ASSERT_EQ(data, TDG_VP_VMCALL_INVALID_OPERAND);
> +
> + td_vcpu_run(vcpu);
> + TDX_TEST_ASSERT_SUCCESS(vcpu);
> +
> + printf("\t ... Verifying MSR values writen by guest\n");
> +
> + TEST_ASSERT_EQ(vcpu_get_msr(vcpu, MSR_X2APIC_APIC_ICR), 4);
> + TEST_ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_MISC_ENABLE), 0x1800);
It's not staightforward to assert MSR_IA32_MISC_ENABLE is 0x1800.
Rather than assume MSR_IA32_MISC_ENABLE is reset to
(MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL | MSR_IA32_MISC_ENABLE_BTS_UNAVAIL)
which is 0x1800, why not call vcpu_get_msr() before guest write and compare
the saved value here?

> + TEST_ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_POWER_CTL), 6);
> +
> + kvm_vm_free(vm);
> + printf("\t ... PASSED\n");
> +}
> +
> +
> int main(int argc, char **argv)
> {
> setbuf(stdout, NULL);
> @@ -531,6 +738,8 @@ int main(int argc, char **argv)
> run_in_new_process(&verify_get_td_vmcall_info);
> run_in_new_process(&verify_guest_writes);
> run_in_new_process(&verify_guest_reads);
> + run_in_new_process(&verify_guest_msr_writes);
> + run_in_new_process(&verify_guest_msr_reads);
>
> return 0;
> }
> --
> 2.43.0.472.g3155946c3a-goog
>
>