On Tue, Oct 21, 2025 at 04:40:14PM -0700, Jim Mattson wrote:
On Mon, Oct 20, 2025 at 10:26 AM Yosry Ahmed yosry.ahmed@linux.dev wrote:
On Wed, Sep 17, 2025 at 02:48:40PM -0700, Jim Mattson wrote:
Add a selftest that verifies KVM's ability to save and restore nested state when the L1 guest is using 5-level paging and the L2 guest is using 4-level paging. Specifically, canonicality tests of the VMCS12 host-state fields should accept 57-bit virtual addresses.
Signed-off-by: Jim Mattson jmattson@google.com
... +void guest_code(struct vmx_pages *vmx_pages) +{
if (vmx_pages)l1_guest_code(vmx_pages);I think none of the other tests do the NULL check. Seems like the test will actually pass if we pass vmx_pages == NULL. I think it's better if we let L1 crash if we mess up the setup.
I'll drop the check in the next version.
GUEST_DONE();+}
+int main(int argc, char *argv[]) +{
vm_vaddr_t vmx_pages_gva = 0;struct kvm_vm *vm;struct kvm_vcpu *vcpu;struct kvm_x86_state *state;struct ucall uc;int stage;TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX));TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_LA57));TEST_REQUIRE(kvm_has_cap(KVM_CAP_NESTED_STATE));vm = vm_create_shape_with_one_vcpu(VM_SHAPE(VM_MODE_PXXV57_4K), &vcpu,guest_code);/** L1 needs to read its own PML5 table to set up L2. Identity map* the PML5 table to facilitate this.*/virt_map(vm, vm->pgd, vm->pgd, 1);vcpu_alloc_vmx(vm, &vmx_pages_gva);vcpu_args_set(vcpu, 1, vmx_pages_gva);for (stage = 1;; stage++) {vcpu_run(vcpu);TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);switch (get_ucall(vcpu, &uc)) {case UCALL_ABORT:REPORT_GUEST_ASSERT(uc);/* NOT REACHED */case UCALL_SYNC:break;case UCALL_DONE:goto done;default:TEST_FAIL("Unknown ucall %lu", uc.cmd);}TEST_ASSERT(uc.args[1] == stage,"Expected stage %d, got stage %lu", stage, (ulong)uc.args[1]);if (stage == 1) {pr_info("L2 is active; performing save/restore.\n");state = vcpu_save_state(vcpu);kvm_vm_release(vm);/* Restore state in a new VM. */vcpu = vm_recreate_with_one_vcpu(vm);vcpu_load_state(vcpu, state);kvm_x86_state_cleanup(state);It seems like we only load the vCPU state but we don't actually run it after restoring the nested state. Should we have another stage and run L2 again after the restore? What is the current failure mode without 9245fd6b8531?
When everything works, we do actually run the vCPU again after restoring the nested state. L1 has to execute GUEST_DONE() to exit this loop.
Oh I missed the fact that the loop will keep going until GUEST_DONE(), now it makes sense. I thought we're just checking that restoring the state will fail.
Without commit 9245fd6b8531 ("KVM: x86: model canonical checks more precisely"), the test fails with:
KVM_SET_NESTED_STATE failed, rc: -1 errno: 22 (Invalid argument)
Right, this failure would happen even if we do not try to run the vCPU again tho, which what I initially thought was the case. Sorry for the noise.
(And, in that case, we do not re-enter the guest.)
}}+done:
kvm_vm_free(vm);return 0;+}
2.51.0.470.ga7dc726c21-goog