x86: Fix a #GP from occurring in usermode library's exception handlers
When handling an exception in usermode.c the exception handler #GPs when executing IRET to return from the exception handler. This happens because the stack segment selector does not have the same privilege level as the return code segment selector. Set the stack segment selector to match the code segment selector's privilege level to fix the issue. This problem has been disguised in kvm-unit-tests because a #GP exception handler has been registered with run_in_user() for the tests that are currently using this feature. With a #GP exception handler registered, the first exception will be processed then #GP on the IRET. The IRET from the second #GP will then succeed, and the subsequent lngjmp() will restore RSP to a sane value. But if no #GP handler is installed, e.g. if a test wants to handle only #ACs, the #GP on the initial IRET will be fatal. This is only a problem in 64-bit mode because 64-bit mode unconditionally pops SS:RSP (SDM vol 3, 6.14.3 "IRET in IA-32e Mode"). In 32-bit mode SS:RSP is not popped because there is no privilege level change when executing IRET at the end of the #GP handler. Signed-off-by:Aaron Lewis <aaronlewis@google.com> Reviewed-by:
Sean Christopherson <seanjc@google.com> Message-Id: <20211214011823.3277011-2-aaronlewis@google.com> Signed-off-by:
Paolo Bonzini <pbonzini@redhat.com>
Loading