Skip to content

Commit

Permalink
KVM: rseq: Update rseq when processing NOTIFY_RESUME on xfer to KVM g…
Browse files Browse the repository at this point in the history
…uest

commit 8646e53 upstream.

Invoke rseq's NOTIFY_RESUME handler when processing the flag prior to
transferring to a KVM guest, which is roughly equivalent to an exit to
userspace and processes many of the same pending actions.  While the task
cannot be in an rseq critical section as the KVM path is reachable only
by via ioctl(KVM_RUN), the side effects that apply to rseq outside of a
critical section still apply, e.g. the current CPU needs to be updated if
the task is migrated.

Clearing TIF_NOTIFY_RESUME without informing rseq can lead to segfaults
and other badness in userspace VMMs that use rseq in combination with KVM,
e.g. due to the CPU ID being stale after task migration.

Fixes: 72c3c0f ("x86/kvm: Use generic xfer to guest work function")
Reported-by: Peter Foley <pefoley@google.com>
Bisected-by: Doug Evans <dje@google.com>
Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Shakeel Butt <shakeelb@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20210901203030.1292304-2-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
sean-jc authored and gregkh committed Sep 30, 2021
1 parent 9fc198f commit 336dabf
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 4 deletions.
4 changes: 3 additions & 1 deletion kernel/entry/kvm.c
Expand Up @@ -19,8 +19,10 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
if (ti_work & _TIF_NEED_RESCHED)
schedule();

if (ti_work & _TIF_NOTIFY_RESUME)
if (ti_work & _TIF_NOTIFY_RESUME) {
tracehook_notify_resume(NULL);
rseq_handle_notify_resume(NULL, NULL);
}

ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
if (ret)
Expand Down
14 changes: 11 additions & 3 deletions kernel/rseq.c
Expand Up @@ -282,9 +282,17 @@ void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)

if (unlikely(t->flags & PF_EXITING))
return;
ret = rseq_ip_fixup(regs);
if (unlikely(ret < 0))
goto error;

/*
* regs is NULL if and only if the caller is in a syscall path. Skip
* fixup and leave rseq_cs as is so that rseq_sycall() will detect and
* kill a misbehaving userspace on debug kernels.
*/
if (regs) {
ret = rseq_ip_fixup(regs);
if (unlikely(ret < 0))
goto error;
}
if (unlikely(rseq_update_cpu_id(t)))
goto error;
return;
Expand Down

0 comments on commit 336dabf

Please sign in to comment.