Message ID | 20190313201926.7868-1-sean.j.christopherson@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: selftests: assert on exit reason in CR4/cpuid sync test | expand |
On 3/13/19 3:19 PM, Sean Christopherson wrote: > ...so that the test doesn't end up in an infinite loop if it fails for > whatever reason, e.g. SHUTDOWN due to gcc inserting stack canary code > into ucall() and attempting to derefence a null segment. You fix passed on my box. Before I ack it, could you share the failure case (i.e. the steps to reproduce infinite loop) mentioned above? > > Fixes: ca359066889f7 ("kvm: selftests: add cr4_cpuid_sync_test") > Cc: Wei Huang <wei@redhat.com> > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> > --- > .../kvm/x86_64/cr4_cpuid_sync_test.c | 35 ++++++++++--------- > 1 file changed, 19 insertions(+), 16 deletions(-) > > diff --git a/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c b/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c > index d503a51fad30..7c2c4d4055a8 100644 > --- a/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c > +++ b/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c > @@ -87,22 +87,25 @@ int main(int argc, char *argv[]) > while (1) { > rc = _vcpu_run(vm, VCPU_ID); > > - if (run->exit_reason == KVM_EXIT_IO) { > - switch (get_ucall(vm, VCPU_ID, &uc)) { > - case UCALL_SYNC: > - /* emulate hypervisor clearing CR4.OSXSAVE */ > - vcpu_sregs_get(vm, VCPU_ID, &sregs); > - sregs.cr4 &= ~X86_CR4_OSXSAVE; > - vcpu_sregs_set(vm, VCPU_ID, &sregs); > - break; > - case UCALL_ABORT: > - TEST_ASSERT(false, "Guest CR4 bit (OSXSAVE) unsynchronized with CPUID bit."); > - break; > - case UCALL_DONE: > - goto done; > - default: > - TEST_ASSERT(false, "Unknown ucall 0x%x.", uc.cmd); > - } > + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, > + "Unexpected exit reason: %u (%s),\n", > + run->exit_reason, > + exit_reason_str(run->exit_reason)); > + > + switch (get_ucall(vm, VCPU_ID, &uc)) { > + case UCALL_SYNC: > + /* emulate hypervisor clearing CR4.OSXSAVE */ > + vcpu_sregs_get(vm, VCPU_ID, &sregs); > + sregs.cr4 &= ~X86_CR4_OSXSAVE; > + vcpu_sregs_set(vm, VCPU_ID, &sregs); > + break; > + case UCALL_ABORT: > + TEST_ASSERT(false, "Guest CR4 bit (OSXSAVE) unsynchronized with CPUID bit."); > + break; > + case UCALL_DONE: > + goto done; > + default: > + TEST_ASSERT(false, "Unknown ucall 0x%x.", uc.cmd); > } > } > >
On Wed, Mar 20, 2019 at 11:50:26PM -0500, Wei Huang wrote: > > > On 3/13/19 3:19 PM, Sean Christopherson wrote: > > ...so that the test doesn't end up in an infinite loop if it fails for > > whatever reason, e.g. SHUTDOWN due to gcc inserting stack canary code > > into ucall() and attempting to derefence a null segment. > > You fix passed on my box. Before I ack it, could you share the failure > case (i.e. the steps to reproduce infinite loop) mentioned above? Hit a triple fault shutdown due to derefencing an invalid fs: selector[1] or because the addresses for the guest are borked[2]. [1] https://patchwork.kernel.org/patch/10851713/ [2] https://patchwork.kernel.org/patch/10851913/
On 3/13/19 3:19 PM, Sean Christopherson wrote: > ...so that the test doesn't end up in an infinite loop if it fails for > whatever reason, e.g. SHUTDOWN due to gcc inserting stack canary code > into ucall() and attempting to derefence a null segment. > > Fixes: ca359066889f7 ("kvm: selftests: add cr4_cpuid_sync_test") > Cc: Wei Huang <wei@redhat.com> > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> > --- > .../kvm/x86_64/cr4_cpuid_sync_test.c | 35 ++++++++++--------- > 1 file changed, 19 insertions(+), 16 deletions(-) > > diff --git a/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c b/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c > index d503a51fad30..7c2c4d4055a8 100644 > --- a/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c > +++ b/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c > @@ -87,22 +87,25 @@ int main(int argc, char *argv[]) > while (1) { > rc = _vcpu_run(vm, VCPU_ID); > > - if (run->exit_reason == KVM_EXIT_IO) { > - switch (get_ucall(vm, VCPU_ID, &uc)) { > - case UCALL_SYNC: > - /* emulate hypervisor clearing CR4.OSXSAVE */ > - vcpu_sregs_get(vm, VCPU_ID, &sregs); > - sregs.cr4 &= ~X86_CR4_OSXSAVE; > - vcpu_sregs_set(vm, VCPU_ID, &sregs); > - break; > - case UCALL_ABORT: > - TEST_ASSERT(false, "Guest CR4 bit (OSXSAVE) unsynchronized with CPUID bit."); > - break; > - case UCALL_DONE: > - goto done; > - default: > - TEST_ASSERT(false, "Unknown ucall 0x%x.", uc.cmd); > - } > + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, > + "Unexpected exit reason: %u (%s),\n", > + run->exit_reason, > + exit_reason_str(run->exit_reason)); > + > + switch (get_ucall(vm, VCPU_ID, &uc)) { > + case UCALL_SYNC: > + /* emulate hypervisor clearing CR4.OSXSAVE */ > + vcpu_sregs_get(vm, VCPU_ID, &sregs); > + sregs.cr4 &= ~X86_CR4_OSXSAVE; > + vcpu_sregs_set(vm, VCPU_ID, &sregs); > + break; > + case UCALL_ABORT: > + TEST_ASSERT(false, "Guest CR4 bit (OSXSAVE) unsynchronized with CPUID bit."); > + break; > + case UCALL_DONE: > + goto done; > + default: > + TEST_ASSERT(false, "Unknown ucall 0x%x.", uc.cmd); > } > } > > Acked-by: Wei Huang <wei@redhat.com>
diff --git a/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c b/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c index d503a51fad30..7c2c4d4055a8 100644 --- a/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c +++ b/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c @@ -87,22 +87,25 @@ int main(int argc, char *argv[]) while (1) { rc = _vcpu_run(vm, VCPU_ID); - if (run->exit_reason == KVM_EXIT_IO) { - switch (get_ucall(vm, VCPU_ID, &uc)) { - case UCALL_SYNC: - /* emulate hypervisor clearing CR4.OSXSAVE */ - vcpu_sregs_get(vm, VCPU_ID, &sregs); - sregs.cr4 &= ~X86_CR4_OSXSAVE; - vcpu_sregs_set(vm, VCPU_ID, &sregs); - break; - case UCALL_ABORT: - TEST_ASSERT(false, "Guest CR4 bit (OSXSAVE) unsynchronized with CPUID bit."); - break; - case UCALL_DONE: - goto done; - default: - TEST_ASSERT(false, "Unknown ucall 0x%x.", uc.cmd); - } + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, + "Unexpected exit reason: %u (%s),\n", + run->exit_reason, + exit_reason_str(run->exit_reason)); + + switch (get_ucall(vm, VCPU_ID, &uc)) { + case UCALL_SYNC: + /* emulate hypervisor clearing CR4.OSXSAVE */ + vcpu_sregs_get(vm, VCPU_ID, &sregs); + sregs.cr4 &= ~X86_CR4_OSXSAVE; + vcpu_sregs_set(vm, VCPU_ID, &sregs); + break; + case UCALL_ABORT: + TEST_ASSERT(false, "Guest CR4 bit (OSXSAVE) unsynchronized with CPUID bit."); + break; + case UCALL_DONE: + goto done; + default: + TEST_ASSERT(false, "Unknown ucall 0x%x.", uc.cmd); } }
...so that the test doesn't end up in an infinite loop if it fails for whatever reason, e.g. SHUTDOWN due to gcc inserting stack canary code into ucall() and attempting to derefence a null segment. Fixes: ca359066889f7 ("kvm: selftests: add cr4_cpuid_sync_test") Cc: Wei Huang <wei@redhat.com> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> --- .../kvm/x86_64/cr4_cpuid_sync_test.c | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-)