diff options
| author | Jiri Kosina <jkosina@suse.cz> | 2020-09-01 14:19:48 +0200 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2020-09-01 14:19:48 +0200 |
| commit | ead5d1f4d877e92c051e1a1ade623d0d30e71619 (patch) | |
| tree | cb9db5698a546e7b96f7d5bef5ce544629dd37a2 /kernel/entry/kvm.c | |
| parent | f53fa968a7344970b8f8a5707c39cdcf17a6f367 (diff) | |
| parent | b51594df17d0ce80b9f9f35394a1f42d7ac94472 (diff) | |
| download | linux-ead5d1f4d877e92c051e1a1ade623d0d30e71619.tar.gz linux-ead5d1f4d877e92c051e1a1ade623d0d30e71619.tar.bz2 linux-ead5d1f4d877e92c051e1a1ade623d0d30e71619.zip | |
Merge branch 'master' into for-next
Sync with Linus' branch in order to be able to apply fixups
of more recent patches.
Diffstat (limited to 'kernel/entry/kvm.c')
| -rw-r--r-- | kernel/entry/kvm.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c new file mode 100644 index 000000000000..eb1a8a4c867c --- /dev/null +++ b/kernel/entry/kvm.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/entry-kvm.h> +#include <linux/kvm_host.h> + +static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work) +{ + do { + int ret; + + if (ti_work & _TIF_SIGPENDING) { + kvm_handle_signal_exit(vcpu); + return -EINTR; + } + + if (ti_work & _TIF_NEED_RESCHED) + schedule(); + + if (ti_work & _TIF_NOTIFY_RESUME) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(NULL); + } + + ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work); + if (ret) + return ret; + + ti_work = READ_ONCE(current_thread_info()->flags); + } while (ti_work & XFER_TO_GUEST_MODE_WORK || need_resched()); + return 0; +} + +int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu) +{ + unsigned long ti_work; + + /* + * This is invoked from the outer guest loop with interrupts and + * preemption enabled. + * + * KVM invokes xfer_to_guest_mode_work_pending() with interrupts + * disabled in the inner loop before going into guest mode. No need + * to disable interrupts here. + */ + ti_work = READ_ONCE(current_thread_info()->flags); + if (!(ti_work & XFER_TO_GUEST_MODE_WORK)) + return 0; + + return xfer_to_guest_mode_work(vcpu, ti_work); +} +EXPORT_SYMBOL_GPL(xfer_to_guest_mode_handle_work); |
