Change smaller_maxphyaddr_emulation_test to expect a #PF(RSVD), rather than an emulation failure, when TDP is disabled. KVM only needs to emulate instructions to emulate a smaller guest.MAXPHYADDR when TDP is enabled. Fixes: 39bbcc3a4e39 ("selftests: kvm: Allows userspace to handle emulation errors.") Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx> --- .../smaller_maxphyaddr_emulation_test.c | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c b/tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c index 91a85a00b692..afa9e0b3dd8a 100644 --- a/tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c +++ b/tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c @@ -21,6 +21,12 @@ #define MEM_REGION_SLOT 10 #define MEM_REGION_SIZE PAGE_SIZE +static void guest_page_fault_handler(struct ex_regs *regs) +{ + GUEST_ASSERT(regs->error_code & PFERR_RSVD_MASK); + GUEST_SYNC(PF_VECTOR); +} + static void guest_code(void) { flds(MEM_REGION_GVA); @@ -36,6 +42,23 @@ static void assert_ucall_done(struct kvm_vcpu *vcpu) uc.cmd, UCALL_DONE); } +static void assert_reserved_page_fault(struct kvm_vcpu *vcpu) +{ + struct ucall uc; + + switch (get_ucall(vcpu, &uc)) { + case UCALL_ABORT: + REPORT_GUEST_ASSERT(uc); + break; + case UCALL_SYNC: + TEST_ASSERT(uc.args[1] == PF_VECTOR, + "Unexpected UCALL_SYNC: %lu", uc.args[1]); + break; + default: + TEST_FAIL("Unrecognized ucall: %lu\n", uc.cmd); + } +} + int main(int argc, char *argv[]) { struct kvm_vcpu *vcpu; @@ -50,6 +73,9 @@ int main(int argc, char *argv[]) TEST_REQUIRE(kvm_has_cap(KVM_CAP_SMALLER_MAXPHYADDR)); vm = vm_create_with_one_vcpu(&vcpu, guest_code); + vm_init_descriptor_tables(vm); + vcpu_init_descriptor_tables(vcpu); + vm_install_exception_handler(vm, PF_VECTOR, guest_page_fault_handler); vcpu_set_cpuid_maxphyaddr(vcpu, MAXPHYADDR); @@ -70,10 +96,21 @@ int main(int argc, char *argv[]) vm_set_page_table_entry(vm, vcpu, MEM_REGION_GVA, pte | (1ull << 36)); vcpu_run(vcpu); - assert_exit_for_flds_emulation_failure(vcpu); - skip_flds_instruction(vcpu); - vcpu_run(vcpu); - assert_ucall_done(vcpu); + + /* + * When TDP is enabled, KVM must emulate the flds instruction, which + * results in an emulation failure out to userspace. Otherwise, no + * instruction emulation is required so check that the instruction + * generates #PF(RSVD). + */ + if (kvm_is_tdp_enabled()) { + assert_exit_for_flds_emulation_failure(vcpu); + skip_flds_instruction(vcpu); + vcpu_run(vcpu); + assert_ucall_done(vcpu); + } else { + assert_reserved_page_fault(vcpu); + } kvm_vm_free(vm); -- 2.38.0.413.g74048e4d9e-goog