MAINTAINERS: update the LSM maintainer info
[platform/kernel/linux-starfive.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 | _TIF_NOTIFY_SIGNAL)) {
12                         clear_notify_signal();
13                         if (task_work_pending(current))
14                                 task_work_run();
15                 }
16
17                 if (ti_work & _TIF_SIGPENDING) {
18                         kvm_handle_signal_exit(vcpu);
19                         return -EINTR;
20                 }
21
22                 if (ti_work & _TIF_NEED_RESCHED)
23                         schedule();
24
25                 if (ti_work & _TIF_NOTIFY_RESUME)
26                         resume_user_mode_work(NULL);
27
28                 ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
29                 if (ret)
30                         return ret;
31
32                 ti_work = read_thread_flags();
33         } while (ti_work & XFER_TO_GUEST_MODE_WORK || need_resched());
34         return 0;
35 }
36
37 int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
38 {
39         unsigned long ti_work;
40
41         /*
42          * This is invoked from the outer guest loop with interrupts and
43          * preemption enabled.
44          *
45          * KVM invokes xfer_to_guest_mode_work_pending() with interrupts
46          * disabled in the inner loop before going into guest mode. No need
47          * to disable interrupts here.
48          */
49         ti_work = read_thread_flags();
50         if (!(ti_work & XFER_TO_GUEST_MODE_WORK))
51                 return 0;
52
53         return xfer_to_guest_mode_work(vcpu, ti_work);
54 }
55 EXPORT_SYMBOL_GPL(xfer_to_guest_mode_handle_work);