Lines Matching full:vp

303  * should be awaited to keep the VP loop consistent (i.e. no message pending
304 * upon VP resume).
305 * VP intercept suspend can't be done when the VP is explicitly suspended
314 mshv_suspend_vp(const struct mshv_vp *vp, bool *message_in_flight) in mshv_suspend_vp() argument
330 ret = mshv_set_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in mshv_suspend_vp()
333 vp_err(vp, "Failed to explicitly suspend vCPU\n"); in mshv_suspend_vp()
337 ret = mshv_get_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in mshv_suspend_vp()
340 vp_err(vp, "Failed to get intercept suspend state\n"); in mshv_suspend_vp()
357 * after VP is released from HV_REGISTER_EXPLICIT_SUSPEND in case of the
360 static long mshv_run_vp_with_hyp_scheduler(struct mshv_vp *vp) in mshv_run_vp_with_hyp_scheduler() argument
369 /* Resume VP execution */ in mshv_run_vp_with_hyp_scheduler()
370 ret = mshv_set_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in mshv_run_vp_with_hyp_scheduler()
373 vp_err(vp, "Failed to resume vp execution. %lx\n", ret); in mshv_run_vp_with_hyp_scheduler()
377 ret = wait_event_interruptible(vp->run.vp_suspend_queue, in mshv_run_vp_with_hyp_scheduler()
378 vp->run.kicked_by_hv == 1); in mshv_run_vp_with_hyp_scheduler()
386 ret = mshv_suspend_vp(vp, &message_in_flight); in mshv_run_vp_with_hyp_scheduler()
395 wait_event(vp->run.vp_suspend_queue, vp->run.kicked_by_hv == 1); in mshv_run_vp_with_hyp_scheduler()
402 vp->run.kicked_by_hv = 0; in mshv_run_vp_with_hyp_scheduler()
408 mshv_vp_dispatch(struct mshv_vp *vp, u32 flags, in mshv_vp_dispatch() argument
422 input->partition_id = vp->vp_partition->pt_id; in mshv_vp_dispatch()
423 input->vp_index = vp->vp_index; in mshv_vp_dispatch()
428 vp->run.flags.root_sched_dispatched = 1; in mshv_vp_dispatch()
430 vp->run.flags.root_sched_dispatched = 0; in mshv_vp_dispatch()
432 trace_mshv_hvcall_dispatch_vp(vp->vp_partition->pt_id, in mshv_vp_dispatch()
433 vp->vp_index, flags, in mshv_vp_dispatch()
437 vp->vp_register_page->interrupt_vectors.as_uint64, in mshv_vp_dispatch()
447 vp_err(vp, "%s: status %s\n", __func__, in mshv_vp_dispatch()
454 mshv_vp_clear_explicit_suspend(struct mshv_vp *vp) in mshv_vp_clear_explicit_suspend() argument
462 ret = mshv_set_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in mshv_vp_clear_explicit_suspend()
465 trace_mshv_vp_clear_explicit_suspend(vp->vp_partition->pt_id, in mshv_vp_clear_explicit_suspend()
466 vp->vp_index, ret); in mshv_vp_clear_explicit_suspend()
469 vp_err(vp, "Failed to unsuspend\n"); in mshv_vp_clear_explicit_suspend()
475 static u64 mshv_vp_interrupt_pending(struct mshv_vp *vp) in mshv_vp_interrupt_pending() argument
477 if (!vp->vp_register_page) in mshv_vp_interrupt_pending()
479 return vp->vp_register_page->interrupt_vectors.as_uint64; in mshv_vp_interrupt_pending()
482 static u64 mshv_vp_interrupt_pending(struct mshv_vp *vp) in mshv_vp_interrupt_pending() argument
488 static bool mshv_vp_dispatch_thread_blocked(struct mshv_vp *vp) in mshv_vp_dispatch_thread_blocked() argument
490 struct hv_stats_page **stats = vp->vp_stats_pages; in mshv_vp_dispatch_thread_blocked()
499 mshv_vp_wait_for_hv_kick(struct mshv_vp *vp) in mshv_vp_wait_for_hv_kick() argument
503 ret = wait_event_interruptible(vp->run.vp_suspend_queue, in mshv_vp_wait_for_hv_kick()
504 (vp->run.kicked_by_hv == 1 && in mshv_vp_wait_for_hv_kick()
505 !mshv_vp_dispatch_thread_blocked(vp)) || in mshv_vp_wait_for_hv_kick()
506 mshv_vp_interrupt_pending(vp)); in mshv_vp_wait_for_hv_kick()
510 trace_mshv_vp_wait_for_hv_kick(vp->vp_partition->pt_id, in mshv_vp_wait_for_hv_kick()
511 vp->vp_index, in mshv_vp_wait_for_hv_kick()
512 vp->run.kicked_by_hv, in mshv_vp_wait_for_hv_kick()
513 mshv_vp_dispatch_thread_blocked(vp), in mshv_vp_wait_for_hv_kick()
514 mshv_vp_interrupt_pending(vp)); in mshv_vp_wait_for_hv_kick()
516 vp->run.flags.root_sched_blocked = 0; in mshv_vp_wait_for_hv_kick()
517 vp->run.kicked_by_hv = 0; in mshv_vp_wait_for_hv_kick()
523 static long mshv_run_vp_with_root_scheduler(struct mshv_vp *vp) in mshv_run_vp_with_root_scheduler() argument
527 if (vp->run.flags.root_sched_blocked) { in mshv_run_vp_with_root_scheduler()
529 * Dispatch state of this VP is blocked. Need to wait in mshv_run_vp_with_root_scheduler()
533 ret = mshv_vp_wait_for_hv_kick(vp); in mshv_run_vp_with_root_scheduler()
545 trace_mshv_xfer_to_guest_mode_work(vp->vp_partition->pt_id, in mshv_run_vp_with_root_scheduler()
546 vp->vp_index, in mshv_run_vp_with_root_scheduler()
554 if (vp->run.flags.intercept_suspend) in mshv_run_vp_with_root_scheduler()
557 if (mshv_vp_interrupt_pending(vp)) in mshv_run_vp_with_root_scheduler()
560 ret = mshv_vp_dispatch(vp, flags, &output); in mshv_run_vp_with_root_scheduler()
564 vp->run.flags.intercept_suspend = 0; in mshv_run_vp_with_root_scheduler()
570 * TODO: remove the warning once VP canceling in mshv_run_vp_with_root_scheduler()
573 WARN_ONCE(atomic64_read(&vp->run.vp_signaled_count), in mshv_run_vp_with_root_scheduler()
574 "%s: vp#%d: unexpected explicit suspend\n", in mshv_run_vp_with_root_scheduler()
575 __func__, vp->vp_index); in mshv_run_vp_with_root_scheduler()
580 * - set right after the first VP dispatch or in mshv_run_vp_with_root_scheduler()
585 ret = mshv_vp_clear_explicit_suspend(vp); in mshv_run_vp_with_root_scheduler()
589 ret = mshv_vp_wait_for_hv_kick(vp); in mshv_run_vp_with_root_scheduler()
593 vp->run.flags.root_sched_blocked = 1; in mshv_run_vp_with_root_scheduler()
594 ret = mshv_vp_wait_for_hv_kick(vp); in mshv_run_vp_with_root_scheduler()
602 vp->run.flags.intercept_suspend = 1; in mshv_run_vp_with_root_scheduler()
604 } while (!vp->run.flags.intercept_suspend); in mshv_run_vp_with_root_scheduler()
646 * @vp: Pointer to the virtual processor structure.
655 static bool mshv_handle_gpa_intercept(struct mshv_vp *vp) in mshv_handle_gpa_intercept() argument
657 struct mshv_partition *p = vp->vp_partition; in mshv_handle_gpa_intercept()
664 vp->vp_intercept_msg_page->u.payload; in mshv_handle_gpa_intercept()
668 vp->vp_intercept_msg_page->u.payload; in mshv_handle_gpa_intercept()
694 trace_mshv_handle_gpa_intercept(p->pt_id, vp->vp_index, gfn, in mshv_handle_gpa_intercept()
699 static bool mshv_vp_handle_intercept(struct mshv_vp *vp) in mshv_vp_handle_intercept() argument
701 switch (vp->vp_intercept_msg_page->header.message_type) { in mshv_vp_handle_intercept()
703 return mshv_handle_gpa_intercept(vp); in mshv_vp_handle_intercept()
708 static long mshv_vp_ioctl_run_vp(struct mshv_vp *vp, void __user *ret_msg) in mshv_vp_ioctl_run_vp() argument
712 trace_mshv_run_vp_entry(vp->vp_partition->pt_id, vp->vp_index); in mshv_vp_ioctl_run_vp()
716 rc = mshv_run_vp_with_root_scheduler(vp); in mshv_vp_ioctl_run_vp()
718 rc = mshv_run_vp_with_hyp_scheduler(vp); in mshv_vp_ioctl_run_vp()
719 } while (rc == 0 && mshv_vp_handle_intercept(vp)); in mshv_vp_ioctl_run_vp()
721 trace_mshv_run_vp_exit(vp->vp_partition->pt_id, vp->vp_index, in mshv_vp_ioctl_run_vp()
722 vp->vp_intercept_msg_page->header.message_type, in mshv_vp_ioctl_run_vp()
728 if (copy_to_user(ret_msg, vp->vp_intercept_msg_page, in mshv_vp_ioctl_run_vp()
736 mshv_vp_ioctl_get_set_state_pfn(struct mshv_vp *vp, in mshv_vp_ioctl_get_set_state_pfn() argument
769 vp_err(vp, "%s: Failed to pin user pages error %i\n", in mshv_vp_ioctl_get_set_state_pfn()
776 ret = hv_call_set_vp_state(vp->vp_index, in mshv_vp_ioctl_get_set_state_pfn()
777 vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state_pfn()
781 ret = hv_call_get_vp_state(vp->vp_index, in mshv_vp_ioctl_get_set_state_pfn()
782 vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state_pfn()
793 mshv_vp_ioctl_get_set_state(struct mshv_vp *vp, in mshv_vp_ioctl_get_set_state() argument
823 ret = hv_call_get_partition_property(vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state()
829 ret = hv_call_get_partition_property(vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state()
870 return mshv_vp_ioctl_get_set_state_pfn(vp, state_data, user_pfn, in mshv_vp_ioctl_get_set_state()
876 vp_err(vp, "Invalid vp state data size!\n"); in mshv_vp_ioctl_get_set_state()
884 return hv_call_set_vp_state(vp->vp_index, in mshv_vp_ioctl_get_set_state()
885 vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state()
890 ret = hv_call_get_vp_state(vp->vp_index, vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state()
904 struct mshv_vp *vp = filp->private_data; in mshv_vp_ioctl() local
907 if (mutex_lock_killable(&vp->vp_mutex)) in mshv_vp_ioctl()
912 r = mshv_vp_ioctl_run_vp(vp, (void __user *)arg); in mshv_vp_ioctl()
915 r = mshv_vp_ioctl_get_set_state(vp, (void __user *)arg, false); in mshv_vp_ioctl()
918 r = mshv_vp_ioctl_get_set_state(vp, (void __user *)arg, true); in mshv_vp_ioctl()
921 r = mshv_ioctl_passthru_hvcall(vp->vp_partition, false, in mshv_vp_ioctl()
925 vp_warn(vp, "Invalid ioctl: %#x\n", ioctl); in mshv_vp_ioctl()
928 mutex_unlock(&vp->vp_mutex); in mshv_vp_ioctl()
935 struct mshv_vp *vp = vmf->vma->vm_file->private_data; in mshv_vp_fault() local
939 vmf->page = virt_to_page(vp->vp_register_page); in mshv_vp_fault()
942 vmf->page = virt_to_page(vp->vp_intercept_msg_page); in mshv_vp_fault()
945 vmf->page = virt_to_page(vp->vp_ghcb_page); in mshv_vp_fault()
958 struct mshv_vp *vp = file->private_data; in mshv_vp_mmap() local
962 if (!vp->vp_register_page) in mshv_vp_mmap()
966 if (!vp->vp_intercept_msg_page) in mshv_vp_mmap()
970 if (!vp->vp_ghcb_page) in mshv_vp_mmap()
984 struct mshv_vp *vp = filp->private_data; in mshv_vp_release() local
986 trace_mshv_vp_release(vp->vp_partition->pt_id, vp->vp_index); in mshv_vp_release()
988 /* Rest of VP cleanup happens in destroy_partition() */ in mshv_vp_release()
989 mshv_partition_put(vp->vp_partition); in mshv_vp_release()
997 .vp.partition_id = partition_id, in mshv_vp_stats_unmap()
998 .vp.vp_index = vp_index, in mshv_vp_stats_unmap()
1002 identity.vp.stats_area_type = HV_STATS_AREA_SELF; in mshv_vp_stats_unmap()
1007 pr_err("%s: failed to unmap partition %llu vp %u self stats, err: %d\n", in mshv_vp_stats_unmap()
1011 identity.vp.stats_area_type = HV_STATS_AREA_PARENT; in mshv_vp_stats_unmap()
1016 pr_err("%s: failed to unmap partition %llu vp %u parent stats, err: %d\n", in mshv_vp_stats_unmap()
1025 .vp.partition_id = partition_id, in mshv_vp_stats_map()
1026 .vp.vp_index = vp_index, in mshv_vp_stats_map()
1030 identity.vp.stats_area_type = HV_STATS_AREA_SELF; in mshv_vp_stats_map()
1034 pr_err("%s: failed to map partition %llu vp %u self stats, err: %d\n", in mshv_vp_stats_map()
1040 * L1VH partition cannot access its vp stats in parent area. in mshv_vp_stats_map()
1045 identity.vp.stats_area_type = HV_STATS_AREA_PARENT; in mshv_vp_stats_map()
1049 pr_err("%s: failed to map partition %llu vp %u parent stats, err: %d\n", in mshv_vp_stats_map()
1060 identity.vp.stats_area_type = HV_STATS_AREA_SELF; in mshv_vp_stats_map()
1072 struct mshv_vp *vp; in mshv_partition_ioctl_create_vp() local
1121 vp = kzalloc_obj(*vp); in mshv_partition_ioctl_create_vp()
1122 if (!vp) { in mshv_partition_ioctl_create_vp()
1127 vp->vp_partition = mshv_partition_get(partition); in mshv_partition_ioctl_create_vp()
1128 if (!vp->vp_partition) { in mshv_partition_ioctl_create_vp()
1133 mutex_init(&vp->vp_mutex); in mshv_partition_ioctl_create_vp()
1134 init_waitqueue_head(&vp->run.vp_suspend_queue); in mshv_partition_ioctl_create_vp()
1135 atomic64_set(&vp->run.vp_signaled_count, 0); in mshv_partition_ioctl_create_vp()
1137 vp->vp_index = args.vp_index; in mshv_partition_ioctl_create_vp()
1138 vp->vp_intercept_msg_page = page_to_virt(intercept_msg_page); in mshv_partition_ioctl_create_vp()
1140 vp->vp_register_page = page_to_virt(register_page); in mshv_partition_ioctl_create_vp()
1143 vp->vp_ghcb_page = page_to_virt(ghcb_page); in mshv_partition_ioctl_create_vp()
1145 memcpy(vp->vp_stats_pages, stats_pages, sizeof(stats_pages)); in mshv_partition_ioctl_create_vp()
1147 ret = mshv_debugfs_vp_create(vp); in mshv_partition_ioctl_create_vp()
1157 file = anon_inode_getfile("mshv_vp", &mshv_vp_fops, vp, in mshv_partition_ioctl_create_vp()
1169 * The release ensures the VP's initialising stores are visible to any in mshv_partition_ioctl_create_vp()
1172 smp_store_release(&partition->pt_vp_array[args.vp_index], vp); in mshv_partition_ioctl_create_vp()
1186 mshv_debugfs_vp_remove(vp); in mshv_partition_ioctl_create_vp()
1190 kfree(vp); in mshv_partition_ioctl_create_vp()
1696 disable_vp_dispatch(struct mshv_vp *vp) in disable_vp_dispatch() argument
1704 ret = mshv_set_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in disable_vp_dispatch()
1707 vp_err(vp, "failed to suspend\n"); in disable_vp_dispatch()
1709 trace_mshv_disable_vp_dispatch(vp->vp_partition->pt_id, in disable_vp_dispatch()
1710 vp->vp_index, ret); in disable_vp_dispatch()
1716 get_vp_signaled_count(struct mshv_vp *vp, u64 *count) in get_vp_signaled_count() argument
1723 ret = mshv_get_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in get_vp_signaled_count()
1727 vp_err(vp, "Failed to get root signal count"); in get_vp_signaled_count()
1738 drain_vp_signals(struct mshv_vp *vp) in drain_vp_signals() argument
1743 get_vp_signaled_count(vp, &hv_signal_count); in drain_vp_signals()
1745 vp_signal_count = atomic64_read(&vp->run.vp_signaled_count); in drain_vp_signals()
1754 if (wait_event_interruptible(vp->run.vp_suspend_queue, in drain_vp_signals()
1755 vp->run.kicked_by_hv == 1)) in drain_vp_signals()
1757 vp->run.kicked_by_hv = 0; in drain_vp_signals()
1758 vp_signal_count = atomic64_read(&vp->run.vp_signaled_count); in drain_vp_signals()
1761 trace_mshv_drain_vp_signals(vp->vp_partition->pt_id, vp->vp_index); in drain_vp_signals()
1767 struct mshv_vp *vp; in drain_all_vps() local
1775 vp = partition->pt_vp_array[i]; in drain_all_vps()
1776 if (!vp) in drain_all_vps()
1779 * Disable dispatching of the VP in the hypervisor. After this in drain_all_vps()
1781 * the VP and the hypervisor's VP signal count won't change. in drain_all_vps()
1783 disable_vp_dispatch(vp); in drain_all_vps()
1784 drain_vp_signals(vp); in drain_all_vps()
1804 struct mshv_vp *vp; in destroy_partition() local
1827 vp = partition->pt_vp_array[i]; in destroy_partition()
1828 if (!vp) in destroy_partition()
1831 mshv_debugfs_vp_remove(vp); in destroy_partition()
1832 mshv_vp_stats_unmap(partition->pt_id, vp->vp_index, in destroy_partition()
1833 vp->vp_stats_pages); in destroy_partition()
1835 if (vp->vp_register_page) { in destroy_partition()
1837 vp->vp_index, in destroy_partition()
1839 virt_to_page(vp->vp_register_page), in destroy_partition()
1841 vp->vp_register_page = NULL; in destroy_partition()
1845 vp->vp_index, in destroy_partition()
1847 virt_to_page(vp->vp_intercept_msg_page), in destroy_partition()
1849 vp->vp_intercept_msg_page = NULL; in destroy_partition()
1851 if (vp->vp_ghcb_page) { in destroy_partition()
1853 vp->vp_index, in destroy_partition()
1855 virt_to_page(vp->vp_ghcb_page), in destroy_partition()
1857 vp->vp_ghcb_page = NULL; in destroy_partition()
1860 kfree(vp); in destroy_partition()