0001
0002
0003 #include <linux/entry-kvm.h>
0004 #include <linux/kvm_host.h>
0005
0006 static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
0007 {
0008 do {
0009 int ret;
0010
0011 if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
0012 kvm_handle_signal_exit(vcpu);
0013 return -EINTR;
0014 }
0015
0016 if (ti_work & _TIF_NEED_RESCHED)
0017 schedule();
0018
0019 if (ti_work & _TIF_NOTIFY_RESUME)
0020 resume_user_mode_work(NULL);
0021
0022 ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
0023 if (ret)
0024 return ret;
0025
0026 ti_work = read_thread_flags();
0027 } while (ti_work & XFER_TO_GUEST_MODE_WORK || need_resched());
0028 return 0;
0029 }
0030
0031 int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
0032 {
0033 unsigned long ti_work;
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 ti_work = read_thread_flags();
0044 if (!(ti_work & XFER_TO_GUEST_MODE_WORK))
0045 return 0;
0046
0047 return xfer_to_guest_mode_work(vcpu, ti_work);
0048 }
0049 EXPORT_SYMBOL_GPL(xfer_to_guest_mode_handle_work);