提交 f658df44 编写于 作者: S Sean Christopherson 提交者: Zheng Zengkai

KVM: rseq: Update rseq when processing NOTIFY_RESUME on xfer to KVM guest

stable inclusion
from stable-5.10.71
commit 249e5e5a501ee69b26d55b68f863671396e62f7f
bugzilla: 182981 https://gitee.com/openeuler/kernel/issues/I4I3KD

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=249e5e5a501ee69b26d55b68f863671396e62f7f

--------------------------------

commit 8646e536 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: 72c3c0fe ("x86/kvm: Use generic xfer to guest work function")
Reported-by: NPeter Foley <pefoley@google.com>
Bisected-by: NDoug Evans <dje@google.com>
Acked-by: NMathieu 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: NSean Christopherson <seanjc@google.com>
Message-Id: <20210901203030.1292304-2-seanjc@google.com>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
[sean: Resolve benign conflict due to unrelated access_ok() check in 5.10]
Signed-off-by: NSean Christopherson <seanjc@google.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Acked-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 e58c0892
...@@ -16,8 +16,10 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work) ...@@ -16,8 +16,10 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
if (ti_work & _TIF_NEED_RESCHED) if (ti_work & _TIF_NEED_RESCHED)
schedule(); schedule();
if (ti_work & _TIF_NOTIFY_RESUME) if (ti_work & _TIF_NOTIFY_RESUME) {
tracehook_notify_resume(NULL); tracehook_notify_resume(NULL);
rseq_handle_notify_resume(NULL, NULL);
}
ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work); ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
if (ret) if (ret)
......
...@@ -268,9 +268,16 @@ void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs) ...@@ -268,9 +268,16 @@ void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)
return; return;
if (unlikely(!access_ok(t->rseq, sizeof(*t->rseq)))) if (unlikely(!access_ok(t->rseq, sizeof(*t->rseq))))
goto error; goto error;
ret = rseq_ip_fixup(regs); /*
if (unlikely(ret < 0)) * regs is NULL if and only if the caller is in a syscall path. Skip
goto error; * 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))) if (unlikely(rseq_update_cpu_id(t)))
goto error; goto error;
return; return;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册