compare_sregs() and compare_vcpu_events() have been empty since the test was written, so the checks that req_and_verify_all_valid() and set_and_verify_various() run after every KVM_RUN only ever compared the general purpose registers. KVM could return anything at all in the sregs and events halves of the kvm_run sync region and the test would still pass.
Fill both in, in the style of compare_regs(): every field of struct kvm_sregs, including the segment and descriptor table members and the interrupt bitmap, and every field of struct kvm_vcpu_events. Both sides of each comparison come from the same vCPU without it having run in between, so they are expected to match exactly. Assisted-by: Cursor:claude-opus-5 Signed-off-by: Hemanth Selam <[email protected]> --- .../selftests/kvm/x86/sync_regs_test.c | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/sync_regs_test.c b/tools/testing/selftests/kvm/x86/sync_regs_test.c index ed0c21b427c9..c7d1f3cca16e 100644 --- a/tools/testing/selftests/kvm/x86/sync_regs_test.c +++ b/tools/testing/selftests/kvm/x86/sync_regs_test.c @@ -70,13 +70,102 @@ static void compare_regs(struct kvm_regs *left, struct kvm_regs *right) #undef REG_COMPARE } +static void compare_segment(struct kvm_segment *left, struct kvm_segment *right, + const char *name) +{ +#define SEG_COMPARE(field) \ + TEST_ASSERT(left->field == right->field, \ + "Segment %s." #field \ + " values did not match: 0x%llx, 0x%llx", \ + name, (unsigned long long)left->field, \ + (unsigned long long)right->field) + SEG_COMPARE(base); + SEG_COMPARE(limit); + SEG_COMPARE(selector); + SEG_COMPARE(type); + SEG_COMPARE(present); + SEG_COMPARE(dpl); + SEG_COMPARE(db); + SEG_COMPARE(s); + SEG_COMPARE(l); + SEG_COMPARE(g); + SEG_COMPARE(avl); + SEG_COMPARE(unusable); +#undef SEG_COMPARE +} + +static void compare_dtable(struct kvm_dtable *left, struct kvm_dtable *right, + const char *name) +{ + TEST_ASSERT(left->base == right->base, + "Descriptor table %s.base values did not match: 0x%llx, 0x%llx", + name, left->base, right->base); + TEST_ASSERT(left->limit == right->limit, + "Descriptor table %s.limit values did not match: 0x%x, 0x%x", + name, left->limit, right->limit); +} + static void compare_sregs(struct kvm_sregs *left, struct kvm_sregs *right) { +#define SREG_COMPARE(reg) \ + TEST_ASSERT(left->reg == right->reg, \ + "Register " #reg \ + " values did not match: 0x%llx, 0x%llx", \ + left->reg, right->reg) + compare_segment(&left->cs, &right->cs, "cs"); + compare_segment(&left->ds, &right->ds, "ds"); + compare_segment(&left->es, &right->es, "es"); + compare_segment(&left->fs, &right->fs, "fs"); + compare_segment(&left->gs, &right->gs, "gs"); + compare_segment(&left->ss, &right->ss, "ss"); + compare_segment(&left->tr, &right->tr, "tr"); + compare_segment(&left->ldt, &right->ldt, "ldt"); + compare_dtable(&left->gdt, &right->gdt, "gdt"); + compare_dtable(&left->idt, &right->idt, "idt"); + SREG_COMPARE(cr0); + SREG_COMPARE(cr2); + SREG_COMPARE(cr3); + SREG_COMPARE(cr4); + SREG_COMPARE(cr8); + SREG_COMPARE(efer); + SREG_COMPARE(apic_base); +#undef SREG_COMPARE + TEST_ASSERT(!memcmp(left->interrupt_bitmap, right->interrupt_bitmap, + sizeof(left->interrupt_bitmap)), + "interrupt_bitmap values did not match"); } static void compare_vcpu_events(struct kvm_vcpu_events *left, struct kvm_vcpu_events *right) { +#define EVENT_COMPARE(field) \ + TEST_ASSERT(left->field == right->field, \ + "Event " #field \ + " values did not match: 0x%llx, 0x%llx", \ + (unsigned long long)left->field, \ + (unsigned long long)right->field) + EVENT_COMPARE(exception.injected); + EVENT_COMPARE(exception.nr); + EVENT_COMPARE(exception.has_error_code); + EVENT_COMPARE(exception.pending); + EVENT_COMPARE(exception.error_code); + EVENT_COMPARE(interrupt.injected); + EVENT_COMPARE(interrupt.nr); + EVENT_COMPARE(interrupt.soft); + EVENT_COMPARE(interrupt.shadow); + EVENT_COMPARE(nmi.injected); + EVENT_COMPARE(nmi.pending); + EVENT_COMPARE(nmi.masked); + EVENT_COMPARE(sipi_vector); + EVENT_COMPARE(flags); + EVENT_COMPARE(smi.smm); + EVENT_COMPARE(smi.pending); + EVENT_COMPARE(smi.smm_inside_nmi); + EVENT_COMPARE(smi.latched_init); + EVENT_COMPARE(triple_fault.pending); + EVENT_COMPARE(exception_has_payload); + EVENT_COMPARE(exception_payload); +#undef EVENT_COMPARE } #define TEST_SYNC_FIELDS (KVM_SYNC_X86_REGS|KVM_SYNC_X86_SREGS|KVM_SYNC_X86_EVENTS) -- 2.43.7

