Patch "KVM: Let KVM_SET_SIGNAL_MASK work as advertised" has been added to the 4.14-stable tree
Subsystems (10)
This is a note to let you know that I've just added the patch titled
KVM: Let KVM_SET_SIGNAL_MASK work as advertised
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
kvm-let-kvm_set_signal_mask-work-as-advertised.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu Feb 1 13:45:42 CET 2018
From: "Jan H. Sch�nherr" <[email protected]>
Date: Fri, 24 Nov 2017 22:39:01 +0100
Subject: KVM: Let KVM_SET_SIGNAL_MASK work as advertised
From: "Jan H. Sch�nherr" <[email protected]>
[ Upstream commit 20b7035c66bacc909ae3ffe92c1a1ea7db99fe4f ]
KVM API says for the signal mask you set via KVM_SET_SIGNAL_MASK, that "any unblocked signal received [...] will cause KVM_RUN to return with -EINTR" and that "the signal will only be delivered if not blocked by the original signal mask".
This, however, is only true, when the calling task has a signal handler registered for a signal. If not, signal evaluation is short-circuited for SIG_IGN and SIG_DFL, and the signal is either ignored without KVM_RUN returning or the whole process is terminated.
Make KVM_SET_SIGNAL_MASK behave as advertised by utilizing logic similar to that in do_sigtimedwait() to avoid short-circuiting of signals.
--- arch/mips/kvm/mips.c | 7 ++----- arch/powerpc/kvm/powerpc.c | 7 ++----- arch/s390/kvm/kvm-s390.c | 7 ++----- arch/x86/kvm/x86.c | 7 ++----- include/linux/kvm_host.h | 3 +++ virt/kvm/arm/arm.c | 8 +++----- virt/kvm/kvm_main.c | 23 +++++++++++++++++++++++ 7 files changed, 37 insertions(+), 25 deletions(-)
arch/mips/kvm/mips.c +2 -5
@@ -445,10 +445,8 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(int kvm_arch_vcpu_ioctl_run (struct kvm_vcpu *vcpu,struct kvm_run *run) {int r = -EINTR ; -sigset_t sigsaved; -if (vcpu->sigset_active) -sigprocmask (SIG_SETMASK , &vcpu->sigset, &sigsaved); +kvm_sigset_activate (vcpu);if (vcpu->mmio_needed) {if (!vcpu->mmio_is_write)
@@ -480,8 +478,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vlocal_irq_enable (); out: -if (vcpu->sigset_active) -sigprocmask (SIG_SETMASK , &sigsaved,NULL ); +kvm_sigset_deactivate (vcpu);return r; }
arch/powerpc/kvm/powerpc.c +2 -5
@@ -1407,7 +1407,6 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvint kvm_arch_vcpu_ioctl_run (struct kvm_vcpu *vcpu,struct kvm_run *run) {int r; -sigset_t sigsaved;if (vcpu->mmio_needed) { vcpu->mmio_needed =0 ;
@@ -1448,16 +1447,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v#endif } -if (vcpu->sigset_active) -sigprocmask (SIG_SETMASK , &vcpu->sigset, &sigsaved); +kvm_sigset_activate (vcpu);if (run->immediate_exit) r = -EINTR ;else r =kvmppc_vcpu_run (run, vcpu); -if (vcpu->sigset_active) -sigprocmask (SIG_SETMASK , &sigsaved,NULL ); +kvm_sigset_deactivate (vcpu);return r; }
arch/s390/kvm/kvm-s390.c +2 -5
@@ -3378,7 +3378,6 @@ static void store_regs(struct kvm_vcpu *int kvm_arch_vcpu_ioctl_run (struct kvm_vcpu *vcpu,struct kvm_run *kvm_run) {int rc; -sigset_t sigsaved;if (kvm_run->immediate_exit)return -EINTR ;
@@ -3388,8 +3387,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vreturn 0 ; } -if (vcpu->sigset_active) -sigprocmask (SIG_SETMASK , &vcpu->sigset, &sigsaved); +kvm_sigset_activate (vcpu);if (!kvm_s390_user_cpu_state_ctrl (vcpu->kvm)) {kvm_s390_vcpu_start (vcpu);
@@ -3423,8 +3421,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vdisable_cpu_timer_accounting (vcpu);store_regs (vcpu, kvm_run); -if (vcpu->sigset_active) -sigprocmask (SIG_SETMASK , &sigsaved,NULL ); +kvm_sigset_deactivate (vcpu); vcpu->stat.exit_userspace++;return rc;
arch/x86/kvm/x86.c +2 -5
@@ -7245,12 +7245,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v {struct fpu *fpu = ¤t->thread.fpu;int r; -sigset_t sigsaved;fpu__initialize (fpu); -if (vcpu->sigset_active) -sigprocmask (SIG_SETMASK , &vcpu->sigset, &sigsaved); +kvm_sigset_activate (vcpu);if (unlikely (vcpu->arch.mp_state ==KVM_MP_STATE_UNINITIALIZED )) {if (kvm_run->immediate_exit) {
@@ -7293,8 +7291,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v out:post_kvm_run_save (vcpu); -if (vcpu->sigset_active) -sigprocmask (SIG_SETMASK , &sigsaved,NULL ); +kvm_sigset_deactivate (vcpu);return r; }
include/linux/kvm_host.h +3 -0
@@ -714,6 +714,9 @@ int kvm_vcpu_write_guest(struct kvm_vcpu unsigned long len);void kvm_vcpu_mark_page_dirty (struct kvm_vcpu *vcpu,gfn_t gfn); +void kvm_sigset_activate (struct kvm_vcpu *vcpu); +void kvm_sigset_deactivate (struct kvm_vcpu *vcpu); +void kvm_vcpu_block (struct kvm_vcpu *vcpu);void kvm_arch_vcpu_blocking (struct kvm_vcpu *vcpu);void kvm_arch_vcpu_unblocking (struct kvm_vcpu *vcpu);
virt/kvm/arm/arm.c +3 -5
@@ -612,7 +612,6 @@ static void check_vcpu_requests(struct kint kvm_arch_vcpu_ioctl_run (struct kvm_vcpu *vcpu,struct kvm_run *run) {int ret; -sigset_t sigsaved;if (unlikely (!kvm_vcpu_initialized (vcpu)))return -ENOEXEC ;
@@ -630,8 +629,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vif (run->immediate_exit)return -EINTR ; -if (vcpu->sigset_active) -sigprocmask (SIG_SETMASK , &vcpu->sigset, &sigsaved); +kvm_sigset_activate (vcpu); ret =1 ; run->exit_reason =KVM_EXIT_UNKNOWN ;
@@ -753,8 +751,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vkvm_pmu_update_run (vcpu); } -if (vcpu->sigset_active) -sigprocmask (SIG_SETMASK , &sigsaved,NULL ); +kvm_sigset_deactivate (vcpu); +return ret; }
virt/kvm/kvm_main.c +23 -0
@@ -2073,6 +2073,29 @@ void kvm_vcpu_mark_page_dirty(struct kvm }EXPORT_SYMBOL_GPL (kvm_vcpu_mark_page_dirty); +void kvm_sigset_activate (struct kvm_vcpu *vcpu) +{ +if (!vcpu->sigset_active) +return ; + +/* +* This does a lockless modification of ->real_blocked, which is fine +* because, only current can change ->real_blocked and all readers of +* ->real_blocked don't care as long ->real_blocked is always a subset +* of ->blocked. +*/ +sigprocmask (SIG_SETMASK , &vcpu->sigset, ¤t->real_blocked); +} + +void kvm_sigset_deactivate (struct kvm_vcpu *vcpu) +{ +if (!vcpu->sigset_active) +return ; + +sigprocmask (SIG_SETMASK , ¤t->real_blocked,NULL ); +sigemptyset (¤t->real_blocked); +} +static void grow_halt_poll_ns (struct kvm_vcpu *vcpu) {unsigned int old, val, grow;
Patches currently in stable-queue which might be from [email protected] are
queue-4.14/kvm-let-kvm_set_signal_mask-work-as-advertised.patch