Merge remote-tracking branch 'drm-misc/drm-misc-next-fixes' into drm-misc-fixes
[linux-2.6-microblaze.git] / kernel / entry / kvm.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 #include <linux/entry-kvm.h>
4 #include <linux/kvm_host.h>
5
6 static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
7 {
8         do {
9                 int ret;
10
11                 if (ti_work & _TIF_SIGPENDING) {
12                         kvm_handle_signal_exit(vcpu);
13                         return -EINTR;
14                 }
15
16                 if (ti_work & _TIF_NEED_RESCHED)
17                         schedule();
18
19                 if (ti_work & _TIF_NOTIFY_RESUME)
20                         tracehook_notify_resume(NULL);
21
22                 ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
23                 if (ret)
24                         return ret;
25
26                 ti_work = READ_ONCE(current_thread_info()->flags);
27         } while (ti_work & XFER_TO_GUEST_MODE_WORK || need_resched());
28         return 0;
29 }
30
31 int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
32 {
33         unsigned long ti_work;
34
35         /*
36          * This is invoked from the outer guest loop with interrupts and
37          * preemption enabled.
38          *
39          * KVM invokes xfer_to_guest_mode_work_pending() with interrupts
40          * disabled in the inner loop before going into guest mode. No need
41          * to disable interrupts here.
42          */
43         ti_work = READ_ONCE(current_thread_info()->flags);
44         if (!(ti_work & XFER_TO_GUEST_MODE_WORK))
45                 return 0;
46
47         return xfer_to_guest_mode_work(vcpu, ti_work);
48 }
49 EXPORT_SYMBOL_GPL(xfer_to_guest_mode_handle_work);