Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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      * This is invoked from the outer guest loop with interrupts and
0037      * preemption enabled.
0038      *
0039      * KVM invokes xfer_to_guest_mode_work_pending() with interrupts
0040      * disabled in the inner loop before going into guest mode. No need
0041      * to disable interrupts here.
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);