1935ace2fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0 2935ace2fSThomas Gleixner 3935ace2fSThomas Gleixner #include <linux/entry-kvm.h> 4935ace2fSThomas Gleixner #include <linux/kvm_host.h> 5935ace2fSThomas Gleixner xfer_to_guest_mode_work(struct kvm_vcpu * vcpu,unsigned long ti_work)6935ace2fSThomas Gleixnerstatic int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work) 7935ace2fSThomas Gleixner { 8935ace2fSThomas Gleixner do { 9935ace2fSThomas Gleixner int ret; 10935ace2fSThomas Gleixner 117c5d8fa6SEric W. Biederman if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) { 12935ace2fSThomas Gleixner kvm_handle_signal_exit(vcpu); 13935ace2fSThomas Gleixner return -EINTR; 14935ace2fSThomas Gleixner } 15935ace2fSThomas Gleixner 16935ace2fSThomas Gleixner if (ti_work & _TIF_NEED_RESCHED) 17935ace2fSThomas Gleixner schedule(); 18935ace2fSThomas Gleixner 193c532798SJens Axboe if (ti_work & _TIF_NOTIFY_RESUME) 20*03248addSEric W. Biederman resume_user_mode_work(NULL); 21935ace2fSThomas Gleixner 22935ace2fSThomas Gleixner ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work); 23935ace2fSThomas Gleixner if (ret) 24935ace2fSThomas Gleixner return ret; 25935ace2fSThomas Gleixner 266ce89512SMark Rutland ti_work = read_thread_flags(); 27935ace2fSThomas Gleixner } while (ti_work & XFER_TO_GUEST_MODE_WORK || need_resched()); 28935ace2fSThomas Gleixner return 0; 29935ace2fSThomas Gleixner } 30935ace2fSThomas Gleixner xfer_to_guest_mode_handle_work(struct kvm_vcpu * vcpu)31935ace2fSThomas Gleixnerint xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu) 32935ace2fSThomas Gleixner { 33935ace2fSThomas Gleixner unsigned long ti_work; 34935ace2fSThomas Gleixner 35935ace2fSThomas Gleixner /* 36935ace2fSThomas Gleixner * This is invoked from the outer guest loop with interrupts and 37935ace2fSThomas Gleixner * preemption enabled. 38935ace2fSThomas Gleixner * 39935ace2fSThomas Gleixner * KVM invokes xfer_to_guest_mode_work_pending() with interrupts 40935ace2fSThomas Gleixner * disabled in the inner loop before going into guest mode. No need 41935ace2fSThomas Gleixner * to disable interrupts here. 42935ace2fSThomas Gleixner */ 436ce89512SMark Rutland ti_work = read_thread_flags(); 44935ace2fSThomas Gleixner if (!(ti_work & XFER_TO_GUEST_MODE_WORK)) 45935ace2fSThomas Gleixner return 0; 46935ace2fSThomas Gleixner 47935ace2fSThomas Gleixner return xfer_to_guest_mode_work(vcpu, ti_work); 48935ace2fSThomas Gleixner } 49935ace2fSThomas Gleixner EXPORT_SYMBOL_GPL(xfer_to_guest_mode_handle_work); 50