The guest in sync_regs_test does raw ucalls by directly accessing the
ucall IO port. It makes these ucalls without setting %rdi to a `struct
ucall`, which is what a ucall uses to pass messages. The issue is that
if the host did a get_ucall (the receiver side), it would try to access
the `struct ucall` at %rdi=0 which would lead to an error ("No mapping
for vm virtual address, gva: 0x0").
This issue is currently benign as there is no get_ucall in
sync_regs_test; however, that will change in the next commit as it
changes the unhandled exception reporting mechanism to use ucalls. In
that case, every vcpu_run is followed by a get_ucall to check if the
guest is trying to report an unhandled exception.
Fix this in advance by setting %rdi to a UCALL_NONE struct ucall for the
sync_regs_test guest.
Tested with gcc-[8,9,10], and clang-[9,11].
Signed-off-by: Ricardo Koller <ricarkol@google.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20210611011020.3420067-3-ricarkol@google.com
Commit 204c91eff7 ("KVM: selftests: do not blindly clobber registers in
guest asm") was intended to make test more gcc-proof, however, the result
is exactly the opposite: on newer gccs (e.g. 8.2.1) the test breaks with
==== Test Assertion Failure ====
x86_64/sync_regs_test.c:168: run->s.regs.regs.rbx == 0xBAD1DEA + 1
pid=14170 tid=14170 - Invalid argument
1 0x00000000004015b3: main at sync_regs_test.c:166 (discriminator 6)
2 0x00007f413fb66412: ?? ??:0
3 0x000000000040191d: _start at ??:?
rbx sync regs value incorrect 0x1.
Apparently, compile is still free to play games with registers even
when they have variables attached.
Re-write guest code with 'asm volatile' by embedding ucall there and
making sure rbx is preserved.
Fixes: 204c91eff7 ("KVM: selftests: do not blindly clobber registers in guest asm")
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
The guest_code of sync_regs_test is assuming that the compiler will not
touch %r11 outside the asm that increments it, which is a bit brittle.
Instead, we can increment a variable and use a dummy asm to ensure the
increment is not optimized away. However, we also need to use a
callee-save register or the compiler will insert a save/restore around
the vmexit, breaking the whole idea behind the test.
(Yes, "if it ain't broken...", but I would like the test to be clean
before it is copied into the upcoming s390 selftests).
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>