kvm.c 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/entry-kvm.h>
  3. #include <linux/kvm_host.h>
  4. static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
  5. {
  6. do {
  7. int ret;
  8. if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
  9. kvm_handle_signal_exit(vcpu);
  10. return -EINTR;
  11. }
  12. if (ti_work & _TIF_NEED_RESCHED)
  13. schedule();
  14. if (ti_work & _TIF_NOTIFY_RESUME)
  15. resume_user_mode_work(NULL);
  16. ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
  17. if (ret)
  18. return ret;
  19. ti_work = read_thread_flags();
  20. } while (ti_work & XFER_TO_GUEST_MODE_WORK || need_resched());
  21. return 0;
  22. }
  23. int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
  24. {
  25. unsigned long ti_work;
  26. /*
  27. * This is invoked from the outer guest loop with interrupts and
  28. * preemption enabled.
  29. *
  30. * KVM invokes xfer_to_guest_mode_work_pending() with interrupts
  31. * disabled in the inner loop before going into guest mode. No need
  32. * to disable interrupts here.
  33. */
  34. ti_work = read_thread_flags();
  35. if (!(ti_work & XFER_TO_GUEST_MODE_WORK))
  36. return 0;
  37. return xfer_to_guest_mode_work(vcpu, ti_work);
  38. }
  39. EXPORT_SYMBOL_GPL(xfer_to_guest_mode_handle_work);