Re: [PATCH v3 03/10] KVM: selftests: Add a test to verify APICv updates (while L2 is active)

From: Chao Gao

Date: Thu Dec 11 2025 - 22:25:16 EST


On Fri, Dec 05, 2025 at 03:19:06PM -0800, Sean Christopherson wrote:
>Add a test to verify KVM correctly handles a variety of edge cases related
>to APICv updates, and in particular updates that are triggered while L2 is
>actively running.
>
>Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>

Reviewed-by: Chao Gao <chao.gao@xxxxxxxxx>

A few nits below:

>--- /dev/null
>+++ b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
>@@ -0,0 +1,181 @@
>+// SPDX-License-Identifier: GPL-2.0-only
>+#include "test_util.h"
>+#include "kvm_util.h"
>+#include "processor.h"
>+#include "vmx.h"
>+
>+#define GOOD_IPI_VECTOR 0xe0
>+#define BAD_IPI_VECTOR 0xf0
>+
>+static volatile int good_ipis_received;
>+
>+static void good_ipi_handler(struct ex_regs *regs)
>+{
>+ good_ipis_received++;
>+}
>+
>+static void bad_ipi_handler(struct ex_regs *regs)
>+{
>+ TEST_FAIL("Received \"bad\" IPI; ICR MMIO write should have been ignored");

is it ok to use TEST_FAIL() in guest code?

>+}
>+
>+static void l2_vmcall(void)
>+{
>+ /*
>+ * Exit to L1. Assume all registers may be clobbered as selftests's
>+ * VM-Enter code doesn't preserve L2 GPRs.
>+ */
>+ asm volatile("push %%rbp\n\t"
>+ "push %%r15\n\t"
>+ "push %%r14\n\t"
>+ "push %%r13\n\t"
>+ "push %%r12\n\t"
>+ "push %%rbx\n\t"
>+ "push %%rdx\n\t"
>+ "push %%rdi\n\t"
>+ "vmcall\n\t"
>+ "pop %%rdi\n\t"
>+ "pop %%rdx\n\t"
>+ "pop %%rbx\n\t"
>+ "pop %%r12\n\t"
>+ "pop %%r13\n\t"
>+ "pop %%r14\n\t"
>+ "pop %%r15\n\t"
>+ "pop %%rbp\n\t"
>+ ::: "rax", "rcx", "rdx", "rsi", "rdx", "r8", "r9", "r10", "r11", "memory");
>+}

There's already a vmcall() helper in vmx.h. Why add a new one?

>+int main(int argc, char *argv[])
>+{
>+ vm_vaddr_t vmx_pages_gva;
>+ struct vmx_pages *vmx;
>+ struct kvm_vcpu *vcpu;
>+ struct kvm_vm *vm;
>+ struct ucall uc;
>+
>+ TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX));
>+
>+ vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
>+
>+ vmx = vcpu_alloc_vmx(vm, &vmx_pages_gva);
>+ prepare_virtualize_apic_accesses(vmx, vm);
>+ vcpu_args_set(vcpu, 2, vmx_pages_gva);

s/2/1

only one argument here.