Lines Matching +full:p +full:- +full:states
1 // SPDX-License-Identifier: GPL-2.0-only
11 #include <linux/entry-virt.h>
28 #include <linux/page-flags.h>
39 MODULE_DESCRIPTION("Microsoft Hyper-V root partition VMM interface /dev/mshv");
164 return -EFAULT; in mshv_ioctl_passthru_hvcall()
168 return -EINVAL; in mshv_ioctl_passthru_hvcall()
171 return -EINVAL; in mshv_ioctl_passthru_hvcall()
178 return -EINVAL; in mshv_ioctl_passthru_hvcall()
184 return -EINVAL; in mshv_ioctl_passthru_hvcall()
193 return -ENOMEM; in mshv_ioctl_passthru_hvcall()
203 ret = -EFAULT; in mshv_ioctl_passthru_hvcall()
211 *(u64 *)input_pg = partition->pt_id; in mshv_ioctl_passthru_hvcall()
223 ret = -EBADFD; in mshv_ioctl_passthru_hvcall()
229 ret = hv_call_deposit_pages(NUMA_NO_NODE, partition->pt_id, 1); in mshv_ioctl_passthru_hvcall()
231 ret = -EAGAIN; in mshv_ioctl_passthru_hvcall()
245 ret = -EFAULT; in mshv_ioctl_passthru_hvcall()
249 ret = -EFAULT; in mshv_ioctl_passthru_hvcall()
289 * 1. implicit suspend bit set -> explicit suspend bit set -> message sent
290 * 2. implicit suspend bit set -> message sent -> explicit suspend bit set
310 es->suspended = 1; in mshv_suspend_vp()
312 ret = mshv_set_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in mshv_suspend_vp()
319 ret = mshv_get_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in mshv_suspend_vp()
326 *message_in_flight = is->suspended; in mshv_suspend_vp()
352 ret = mshv_set_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in mshv_run_vp_with_hyp_scheduler()
359 ret = wait_event_interruptible(vp->run.vp_suspend_queue, in mshv_run_vp_with_hyp_scheduler()
360 vp->run.kicked_by_hv == 1); in mshv_run_vp_with_hyp_scheduler()
374 return -EINTR; in mshv_run_vp_with_hyp_scheduler()
377 wait_event(vp->run.vp_suspend_queue, vp->run.kicked_by_hv == 1); in mshv_run_vp_with_hyp_scheduler()
384 vp->run.kicked_by_hv = 0; in mshv_run_vp_with_hyp_scheduler()
404 input->partition_id = vp->vp_partition->pt_id; in mshv_vp_dispatch()
405 input->vp_index = vp->vp_index; in mshv_vp_dispatch()
406 input->time_slice = 0; /* Run forever until something happens */ in mshv_vp_dispatch()
407 input->spec_ctrl = 0; /* TODO: set sensible flags */ in mshv_vp_dispatch()
408 input->flags = flags; in mshv_vp_dispatch()
410 vp->run.flags.root_sched_dispatched = 1; in mshv_vp_dispatch()
412 vp->run.flags.root_sched_dispatched = 0; in mshv_vp_dispatch()
433 ret = mshv_set_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in mshv_vp_clear_explicit_suspend()
445 if (!vp->vp_register_page) in mshv_vp_interrupt_pending()
447 return vp->vp_register_page->interrupt_vectors.as_uint64; in mshv_vp_interrupt_pending()
458 struct hv_stats_page **stats = vp->vp_stats_pages; in mshv_vp_dispatch_thread_blocked()
459 u64 *self_vp_cntrs = stats[HV_STATS_AREA_SELF]->vp_cntrs; in mshv_vp_dispatch_thread_blocked()
460 u64 *parent_vp_cntrs = stats[HV_STATS_AREA_PARENT]->vp_cntrs; in mshv_vp_dispatch_thread_blocked()
472 ret = wait_event_interruptible(vp->run.vp_suspend_queue, in mshv_vp_wait_for_hv_kick()
473 (vp->run.kicked_by_hv == 1 && in mshv_vp_wait_for_hv_kick()
477 return -EINTR; in mshv_vp_wait_for_hv_kick()
479 vp->run.flags.root_sched_blocked = 0; in mshv_vp_wait_for_hv_kick()
480 vp->run.kicked_by_hv = 0; in mshv_vp_wait_for_hv_kick()
490 if (vp->run.flags.root_sched_blocked) { in mshv_run_vp_with_root_scheduler()
511 if (vp->run.flags.intercept_suspend) in mshv_run_vp_with_root_scheduler()
521 vp->run.flags.intercept_suspend = 0; in mshv_run_vp_with_root_scheduler()
530 WARN_ONCE(atomic64_read(&vp->run.vp_signaled_count), in mshv_run_vp_with_root_scheduler()
532 __func__, vp->vp_index); in mshv_run_vp_with_root_scheduler()
537 * - set right after the first VP dispatch or in mshv_run_vp_with_root_scheduler()
538 * - set explicitly via hypercall in mshv_run_vp_with_root_scheduler()
550 vp->run.flags.root_sched_blocked = 1; in mshv_run_vp_with_root_scheduler()
559 vp->run.flags.intercept_suspend = 1; in mshv_run_vp_with_root_scheduler()
561 } while (!vp->run.flags.intercept_suspend); in mshv_run_vp_with_root_scheduler()
581 if (copy_to_user(ret_msg, vp->vp_intercept_msg_page, in mshv_vp_ioctl_run_vp()
583 rc = -EFAULT; in mshv_vp_ioctl_run_vp()
599 return -EINVAL; in mshv_vp_ioctl_get_set_state_pfn()
603 * (user_pfn + (page_count - 1)) * PAGE_SIZE in mshv_vp_ioctl_get_set_state_pfn()
605 if (check_add_overflow(user_pfn, (page_count - 1), &check)) in mshv_vp_ioctl_get_set_state_pfn()
606 return -EOVERFLOW; in mshv_vp_ioctl_get_set_state_pfn()
608 return -EOVERFLOW; in mshv_vp_ioctl_get_set_state_pfn()
613 return -ENOMEM; in mshv_vp_ioctl_get_set_state_pfn()
617 int remaining = page_count - completed; in mshv_vp_ioctl_get_set_state_pfn()
629 ret = hv_call_set_vp_state(vp->vp_index, in mshv_vp_ioctl_get_set_state_pfn()
630 vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state_pfn()
634 ret = hv_call_get_vp_state(vp->vp_index, in mshv_vp_ioctl_get_set_state_pfn()
635 vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state_pfn()
657 return -EFAULT; in mshv_vp_ioctl_get_set_state()
662 return -EINVAL; in mshv_vp_ioctl_get_set_state()
665 return -EFAULT; in mshv_vp_ioctl_get_set_state()
676 ret = hv_call_get_partition_property(vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state()
678 &state_data.xsave.states.as_uint64); in mshv_vp_ioctl_get_set_state()
682 ret = hv_call_get_partition_property(vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state()
690 /* Always request legacy states */ in mshv_vp_ioctl_get_set_state()
691 state_data.xsave.states.legacy_x87 = 1; in mshv_vp_ioctl_get_set_state()
692 state_data.xsave.states.legacy_sse = 1; in mshv_vp_ioctl_get_set_state()
709 return -EINVAL; in mshv_vp_ioctl_get_set_state()
712 if (copy_to_user(&user_args->buf_sz, &data_sz, sizeof(user_args->buf_sz))) in mshv_vp_ioctl_get_set_state()
713 return -EFAULT; in mshv_vp_ioctl_get_set_state()
716 return -EINVAL; in mshv_vp_ioctl_get_set_state()
727 /* Paranoia check - this shouldn't happen! */ in mshv_vp_ioctl_get_set_state()
730 return -EINVAL; in mshv_vp_ioctl_get_set_state()
735 return -EFAULT; in mshv_vp_ioctl_get_set_state()
737 return hv_call_set_vp_state(vp->vp_index, in mshv_vp_ioctl_get_set_state()
738 vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state()
743 ret = hv_call_get_vp_state(vp->vp_index, vp->vp_partition->pt_id, in mshv_vp_ioctl_get_set_state()
749 return -EFAULT; in mshv_vp_ioctl_get_set_state()
757 struct mshv_vp *vp = filp->private_data; in mshv_vp_ioctl()
758 long r = -ENOTTY; in mshv_vp_ioctl()
760 if (mutex_lock_killable(&vp->vp_mutex)) in mshv_vp_ioctl()
761 return -EINTR; in mshv_vp_ioctl()
774 r = mshv_ioctl_passthru_hvcall(vp->vp_partition, false, in mshv_vp_ioctl()
781 mutex_unlock(&vp->vp_mutex); in mshv_vp_ioctl()
788 struct mshv_vp *vp = vmf->vma->vm_file->private_data; in mshv_vp_fault()
790 switch (vmf->vma->vm_pgoff) { in mshv_vp_fault()
792 vmf->page = virt_to_page(vp->vp_register_page); in mshv_vp_fault()
795 vmf->page = virt_to_page(vp->vp_intercept_msg_page); in mshv_vp_fault()
798 vmf->page = virt_to_page(vp->vp_ghcb_page); in mshv_vp_fault()
804 get_page(vmf->page); in mshv_vp_fault()
811 struct mshv_vp *vp = file->private_data; in mshv_vp_mmap()
813 switch (vma->vm_pgoff) { in mshv_vp_mmap()
815 if (!vp->vp_register_page) in mshv_vp_mmap()
816 return -ENODEV; in mshv_vp_mmap()
819 if (!vp->vp_intercept_msg_page) in mshv_vp_mmap()
820 return -ENODEV; in mshv_vp_mmap()
823 if (!vp->vp_ghcb_page) in mshv_vp_mmap()
824 return -ENODEV; in mshv_vp_mmap()
827 return -EINVAL; in mshv_vp_mmap()
830 vma->vm_ops = &mshv_vp_vm_ops; in mshv_vp_mmap()
837 struct mshv_vp *vp = filp->private_data; in mshv_vp_release()
840 mshv_partition_put(vp->vp_partition); in mshv_vp_release()
898 return -EFAULT; in mshv_partition_ioctl_create_vp()
901 return -EINVAL; in mshv_partition_ioctl_create_vp()
903 if (partition->pt_vp_array[args.vp_index]) in mshv_partition_ioctl_create_vp()
904 return -EEXIST; in mshv_partition_ioctl_create_vp()
906 ret = hv_call_create_vp(NUMA_NO_NODE, partition->pt_id, args.vp_index, in mshv_partition_ioctl_create_vp()
911 ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index, in mshv_partition_ioctl_create_vp()
919 ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index, in mshv_partition_ioctl_create_vp()
929 ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index, in mshv_partition_ioctl_create_vp()
938 ret = mshv_vp_stats_map(partition->pt_id, args.vp_index, in mshv_partition_ioctl_create_vp()
948 vp->vp_partition = mshv_partition_get(partition); in mshv_partition_ioctl_create_vp()
949 if (!vp->vp_partition) { in mshv_partition_ioctl_create_vp()
950 ret = -EBADF; in mshv_partition_ioctl_create_vp()
954 mutex_init(&vp->vp_mutex); in mshv_partition_ioctl_create_vp()
955 init_waitqueue_head(&vp->run.vp_suspend_queue); in mshv_partition_ioctl_create_vp()
956 atomic64_set(&vp->run.vp_signaled_count, 0); in mshv_partition_ioctl_create_vp()
958 vp->vp_index = args.vp_index; in mshv_partition_ioctl_create_vp()
959 vp->vp_intercept_msg_page = page_to_virt(intercept_message_page); in mshv_partition_ioctl_create_vp()
961 vp->vp_register_page = page_to_virt(register_page); in mshv_partition_ioctl_create_vp()
964 vp->vp_ghcb_page = page_to_virt(ghcb_page); in mshv_partition_ioctl_create_vp()
967 memcpy(vp->vp_stats_pages, stats_pages, sizeof(stats_pages)); in mshv_partition_ioctl_create_vp()
979 partition->pt_vp_count++; in mshv_partition_ioctl_create_vp()
980 partition->pt_vp_array[args.vp_index] = vp; in mshv_partition_ioctl_create_vp()
990 mshv_vp_stats_unmap(partition->pt_id, args.vp_index); in mshv_partition_ioctl_create_vp()
993 hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index, in mshv_partition_ioctl_create_vp()
999 hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index, in mshv_partition_ioctl_create_vp()
1004 hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index, in mshv_partition_ioctl_create_vp()
1008 hv_call_delete_vp(partition->pt_id, args.vp_index); in mshv_partition_ioctl_create_vp()
1014 if (completion_done(&partition->async_hypercall)) { in mshv_init_async_handler()
1017 return -EPERM; in mshv_init_async_handler()
1020 reinit_completion(&partition->async_hypercall); in mshv_init_async_handler()
1028 wait_for_completion(&partition->async_hypercall); in mshv_async_hvcall_handler()
1031 *status = partition->async_hypercall_status; in mshv_async_hvcall_handler()
1039 if (region->flags.large_pages) in mshv_partition_region_share()
1042 return hv_call_modify_spa_host_access(region->partition->pt_id, in mshv_partition_region_share()
1043 region->pages, region->nr_pages, in mshv_partition_region_share()
1053 if (region->flags.large_pages) in mshv_partition_region_unshare()
1056 return hv_call_modify_spa_host_access(region->partition->pt_id, in mshv_partition_region_unshare()
1057 region->pages, region->nr_pages, in mshv_partition_region_unshare()
1066 if (page_offset + page_count > region->nr_pages) in mshv_region_remap_pages()
1067 return -EINVAL; in mshv_region_remap_pages()
1069 if (region->flags.large_pages) in mshv_region_remap_pages()
1073 return hv_call_map_gpa_pages(region->partition->pt_id, in mshv_region_remap_pages()
1074 region->start_gfn + page_offset, in mshv_region_remap_pages()
1076 region->pages + page_offset); in mshv_region_remap_pages()
1082 u32 map_flags = region->hv_map_flags; in mshv_region_map()
1085 0, region->nr_pages); in mshv_region_map()
1092 if (region->flags.range_pinned) in mshv_region_evict_pages()
1093 unpin_user_pages(region->pages + page_offset, page_count); in mshv_region_evict_pages()
1095 memset(region->pages + page_offset, 0, in mshv_region_evict_pages()
1102 mshv_region_evict_pages(region, 0, region->nr_pages); in mshv_region_evict()
1114 if (page_offset + page_count > region->nr_pages) in mshv_region_populate_pages()
1115 return -EINVAL; in mshv_region_populate_pages()
1118 pages = region->pages + page_offset + done_count; in mshv_region_populate_pages()
1119 userspace_addr = region->start_uaddr + in mshv_region_populate_pages()
1122 nr_pages = min(page_count - done_count, in mshv_region_populate_pages()
1133 if (region->flags.range_pinned) in mshv_region_populate_pages()
1139 ret = -EOPNOTSUPP; in mshv_region_populate_pages()
1145 if (PageHuge(region->pages[page_offset])) in mshv_region_populate_pages()
1146 region->flags.large_pages = true; in mshv_region_populate_pages()
1158 return mshv_region_populate_pages(region, 0, region->nr_pages); in mshv_region_populate()
1166 hlist_for_each_entry(region, &partition->pt_mem_regions, hnode) { in mshv_partition_region_by_gfn()
1167 if (gfn >= region->start_gfn && in mshv_partition_region_by_gfn()
1168 gfn < region->start_gfn + region->nr_pages) in mshv_partition_region_by_gfn()
1180 hlist_for_each_entry(region, &partition->pt_mem_regions, hnode) { in mshv_partition_region_by_uaddr()
1181 if (uaddr >= region->start_uaddr && in mshv_partition_region_by_uaddr()
1182 uaddr < region->start_uaddr + in mshv_partition_region_by_uaddr()
1183 (region->nr_pages << HV_HYP_PAGE_SHIFT)) in mshv_partition_region_by_uaddr()
1191 * NB: caller checks and makes sure mem->size is page aligned
1192 * Returns: 0 with regionpp updated on success, or -errno
1200 u64 nr_pages = HVPFN_DOWN(mem->size); in mshv_partition_create_region()
1203 if (mshv_partition_region_by_gfn(partition, mem->guest_pfn) || in mshv_partition_create_region()
1204 mshv_partition_region_by_gfn(partition, mem->guest_pfn + nr_pages - 1) || in mshv_partition_create_region()
1205 mshv_partition_region_by_uaddr(partition, mem->userspace_addr) || in mshv_partition_create_region()
1206 mshv_partition_region_by_uaddr(partition, mem->userspace_addr + mem->size - 1)) in mshv_partition_create_region()
1207 return -EEXIST; in mshv_partition_create_region()
1211 return -ENOMEM; in mshv_partition_create_region()
1213 region->nr_pages = nr_pages; in mshv_partition_create_region()
1214 region->start_gfn = mem->guest_pfn; in mshv_partition_create_region()
1215 region->start_uaddr = mem->userspace_addr; in mshv_partition_create_region()
1216 region->hv_map_flags = HV_MAP_GPA_READABLE | HV_MAP_GPA_ADJUSTABLE; in mshv_partition_create_region()
1217 if (mem->flags & BIT(MSHV_SET_MEM_BIT_WRITABLE)) in mshv_partition_create_region()
1218 region->hv_map_flags |= HV_MAP_GPA_WRITABLE; in mshv_partition_create_region()
1219 if (mem->flags & BIT(MSHV_SET_MEM_BIT_EXECUTABLE)) in mshv_partition_create_region()
1220 region->hv_map_flags |= HV_MAP_GPA_EXECUTABLE; in mshv_partition_create_region()
1224 region->flags.range_pinned = true; in mshv_partition_create_region()
1226 region->partition = partition; in mshv_partition_create_region()
1240 struct mshv_partition *partition = region->partition; in mshv_partition_mem_region_map()
1262 region->start_gfn, ret); in mshv_partition_mem_region_map()
1277 region->start_gfn, shrc); in mshv_partition_mem_region_map()
1297 * - vfio overloads vm_pgoff to store the mmio start pfn/spa.
1298 * - Two things need to happen for mapping mmio range:
1300 * 2. mapped in the hwpt (gfn <-> mmio phys addr) so guest can access it.
1317 return -EINVAL; in mshv_map_user_memory()
1319 mmap_read_lock(current->mm); in mshv_map_user_memory()
1320 vma = vma_lookup(current->mm, mem.userspace_addr); in mshv_map_user_memory()
1321 is_mmio = vma ? !!(vma->vm_flags & (VM_IO | VM_PFNMAP)) : 0; in mshv_map_user_memory()
1322 mmio_pfn = is_mmio ? vma->vm_pgoff : 0; in mshv_map_user_memory()
1323 mmap_read_unlock(current->mm); in mshv_map_user_memory()
1326 return -EINVAL; in mshv_map_user_memory()
1334 ret = hv_call_map_mmio_pages(partition->pt_id, mem.guest_pfn, in mshv_map_user_memory()
1343 hlist_add_head(®ion->hnode, &partition->pt_mem_regions); in mshv_map_user_memory()
1361 return -EINVAL; in mshv_unmap_user_memory()
1365 return -EINVAL; in mshv_unmap_user_memory()
1368 if (region->start_uaddr != mem.userspace_addr || in mshv_unmap_user_memory()
1369 region->start_gfn != mem.guest_pfn || in mshv_unmap_user_memory()
1370 region->nr_pages != HVPFN_DOWN(mem.size)) in mshv_unmap_user_memory()
1371 return -EINVAL; in mshv_unmap_user_memory()
1373 hlist_del(®ion->hnode); in mshv_unmap_user_memory()
1375 if (region->flags.large_pages) in mshv_unmap_user_memory()
1379 hv_call_unmap_gpa_pages(partition->pt_id, region->start_gfn, in mshv_unmap_user_memory()
1380 region->nr_pages, unmap_flags); in mshv_unmap_user_memory()
1395 return -EFAULT; in mshv_partition_ioctl_set_memory()
1402 return -EINVAL; in mshv_partition_ioctl_set_memory()
1417 return -EFAULT; in mshv_partition_ioctl_ioeventfd()
1429 return -EFAULT; in mshv_partition_ioctl_irqfd()
1439 union hv_gpa_page_access_state *states; in mshv_partition_ioctl_get_gpap_access_bitmap() local
1447 return -EFAULT; in mshv_partition_ioctl_get_gpap_access_bitmap()
1453 return -EINVAL; in mshv_partition_ioctl_get_gpap_access_bitmap()
1455 if (check_mul_overflow(args.page_count, sizeof(*states), &states_buf_sz)) in mshv_partition_ioctl_get_gpap_access_bitmap()
1456 return -E2BIG; in mshv_partition_ioctl_get_gpap_access_bitmap()
1463 return -EBADFD; in mshv_partition_ioctl_get_gpap_access_bitmap()
1488 states = vzalloc(states_buf_sz); in mshv_partition_ioctl_get_gpap_access_bitmap()
1489 if (!states) in mshv_partition_ioctl_get_gpap_access_bitmap()
1490 return -ENOMEM; in mshv_partition_ioctl_get_gpap_access_bitmap()
1492 ret = hv_call_get_gpa_access_states(partition->pt_id, args.page_count, in mshv_partition_ioctl_get_gpap_access_bitmap()
1494 states); in mshv_partition_ioctl_get_gpap_access_bitmap()
1499 * Overwrite states buffer with bitmap - the bits in hv_type_mask in mshv_partition_ioctl_get_gpap_access_bitmap()
1503 __assign_bit(i, (ulong *)states, in mshv_partition_ioctl_get_gpap_access_bitmap()
1504 states[i].as_uint8 & hv_type_mask); in mshv_partition_ioctl_get_gpap_access_bitmap()
1508 __clear_bit(i, (ulong *)states); in mshv_partition_ioctl_get_gpap_access_bitmap()
1510 if (copy_to_user((void __user *)args.bitmap_ptr, states, bitmap_buf_sz)) in mshv_partition_ioctl_get_gpap_access_bitmap()
1511 ret = -EFAULT; in mshv_partition_ioctl_get_gpap_access_bitmap()
1514 vfree(states); in mshv_partition_ioctl_get_gpap_access_bitmap()
1527 return -EFAULT; in mshv_partition_ioctl_set_msi_routing()
1531 return -EINVAL; in mshv_partition_ioctl_set_msi_routing()
1536 entries = vmemdup_user(urouting->entries, in mshv_partition_ioctl_set_msi_routing()
1553 if (partition->pt_initialized) in mshv_partition_ioctl_initialize()
1556 ret = hv_call_initialize_partition(partition->pt_id); in mshv_partition_ioctl_initialize()
1560 partition->pt_initialized = true; in mshv_partition_ioctl_initialize()
1565 hv_call_withdraw_memory(U64_MAX, NUMA_NO_NODE, partition->pt_id); in mshv_partition_ioctl_initialize()
1573 struct mshv_partition *partition = filp->private_data; in mshv_partition_ioctl()
1577 if (mutex_lock_killable(&partition->pt_mutex)) in mshv_partition_ioctl()
1578 return -EINTR; in mshv_partition_ioctl()
1607 ret = -ENOTTY; in mshv_partition_ioctl()
1610 mutex_unlock(&partition->pt_mutex); in mshv_partition_ioctl()
1623 ret = mshv_set_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in disable_vp_dispatch()
1639 ret = mshv_get_vp_registers(vp->vp_index, vp->vp_partition->pt_id, in get_vp_signaled_count()
1661 vp_signal_count = atomic64_read(&vp->run.vp_signaled_count); in drain_vp_signals()
1668 WARN_ON(hv_signal_count - vp_signal_count != 1); in drain_vp_signals()
1670 if (wait_event_interruptible(vp->run.vp_suspend_queue, in drain_vp_signals()
1671 vp->run.kicked_by_hv == 1)) in drain_vp_signals()
1673 vp->run.kicked_by_hv = 0; in drain_vp_signals()
1674 vp_signal_count = atomic64_read(&vp->run.vp_signaled_count); in drain_vp_signals()
1689 vp = partition->pt_vp_array[i]; in drain_all_vps()
1706 hlist_del_rcu(&partition->pt_hnode); in remove_partition()
1723 if (refcount_read(&partition->pt_ref_count)) { in destroy_partition()
1729 if (partition->pt_initialized) { in destroy_partition()
1739 vp = partition->pt_vp_array[i]; in destroy_partition()
1744 mshv_vp_stats_unmap(partition->pt_id, vp->vp_index); in destroy_partition()
1746 if (vp->vp_register_page) { in destroy_partition()
1747 (void)hv_call_unmap_vp_state_page(partition->pt_id, in destroy_partition()
1748 vp->vp_index, in destroy_partition()
1751 vp->vp_register_page = NULL; in destroy_partition()
1754 (void)hv_call_unmap_vp_state_page(partition->pt_id, in destroy_partition()
1755 vp->vp_index, in destroy_partition()
1758 vp->vp_intercept_msg_page = NULL; in destroy_partition()
1760 if (vp->vp_ghcb_page) { in destroy_partition()
1761 (void)hv_call_unmap_vp_state_page(partition->pt_id, in destroy_partition()
1762 vp->vp_index, in destroy_partition()
1765 vp->vp_ghcb_page = NULL; in destroy_partition()
1770 partition->pt_vp_array[i] = NULL; in destroy_partition()
1774 hv_call_finalize_partition(partition->pt_id); in destroy_partition()
1776 partition->pt_initialized = false; in destroy_partition()
1782 hlist_for_each_entry_safe(region, n, &partition->pt_mem_regions, in destroy_partition()
1784 hlist_del(®ion->hnode); in destroy_partition()
1802 hv_call_withdraw_memory(U64_MAX, NUMA_NO_NODE, partition->pt_id); in destroy_partition()
1803 hv_call_delete_partition(partition->pt_id); in destroy_partition()
1812 if (refcount_inc_not_zero(&partition->pt_ref_count)) in mshv_partition_get()
1821 struct mshv_partition *p; in mshv_partition_find() local
1823 hash_for_each_possible_rcu(mshv_root.pt_htable, p, pt_hnode, in mshv_partition_find()
1825 if (p->pt_id == partition_id) in mshv_partition_find()
1826 return p; in mshv_partition_find()
1834 if (refcount_dec_and_test(&partition->pt_ref_count)) in mshv_partition_put()
1841 struct mshv_partition *partition = filp->private_data; in mshv_partition_release()
1845 cleanup_srcu_struct(&partition->pt_irq_srcu); in mshv_partition_release()
1857 hash_add_rcu(mshv_root.pt_htable, &partition->pt_hnode, in add_partition()
1858 partition->pt_id); in add_partition()
1878 return -EFAULT; in mshv_ioctl_create_partition()
1882 return -EINVAL; in mshv_ioctl_create_partition()
1904 return -ENOMEM; in mshv_ioctl_create_partition()
1906 partition->pt_module_dev = module_dev; in mshv_ioctl_create_partition()
1907 partition->isolation_type = isolation_properties.isolation_type; in mshv_ioctl_create_partition()
1909 refcount_set(&partition->pt_ref_count, 1); in mshv_ioctl_create_partition()
1911 mutex_init(&partition->pt_mutex); in mshv_ioctl_create_partition()
1913 mutex_init(&partition->pt_irq_lock); in mshv_ioctl_create_partition()
1915 init_completion(&partition->async_hypercall); in mshv_ioctl_create_partition()
1917 INIT_HLIST_HEAD(&partition->irq_ack_notifier_list); in mshv_ioctl_create_partition()
1919 INIT_HLIST_HEAD(&partition->pt_devices); in mshv_ioctl_create_partition()
1921 INIT_HLIST_HEAD(&partition->pt_mem_regions); in mshv_ioctl_create_partition()
1925 ret = init_srcu_struct(&partition->pt_irq_srcu); in mshv_ioctl_create_partition()
1932 &partition->pt_id); in mshv_ioctl_create_partition()
1966 hv_call_delete_partition(partition->pt_id); in mshv_ioctl_create_partition()
1968 cleanup_srcu_struct(&partition->pt_irq_srcu); in mshv_ioctl_create_partition()
1978 struct miscdevice *misc = filp->private_data; in mshv_dev_ioctl()
1983 misc->this_device); in mshv_dev_ioctl()
1986 return -ENOTTY; in mshv_dev_ioctl()
2034 input->property_id = HV_SYSTEM_PROPERTY_SCHEDULER_TYPE; in hv_retrieve_scheduler_type()
2043 *out = output->scheduler_type; in hv_retrieve_scheduler_type()
2075 return -EOPNOTSUPP; in mshv_retrieve_scheduler_type()
2083 void **inputarg, **outputarg, *p; in mshv_root_scheduler_init() local
2089 p = kmalloc(2 * HV_HYP_PAGE_SIZE, GFP_KERNEL); in mshv_root_scheduler_init()
2090 if (!p) in mshv_root_scheduler_init()
2091 return -ENOMEM; in mshv_root_scheduler_init()
2093 *inputarg = p; in mshv_root_scheduler_init()
2094 *outputarg = (char *)p + HV_HYP_PAGE_SIZE; in mshv_root_scheduler_init()
2101 void *p, **inputarg, **outputarg; in mshv_root_scheduler_cleanup() local
2106 p = *inputarg; in mshv_root_scheduler_cleanup()
2111 kfree(p); in mshv_root_scheduler_cleanup()
2130 ret = -ENOMEM; in root_scheduler_init()
2207 return -ENODEV; in mshv_parent_partition_init()
2210 return -ENODEV; in mshv_parent_partition_init()
2220 dev_err(dev, "Running on unvalidated Hyper-V version\n"); in mshv_parent_partition_init()
2229 ret = -ENOMEM; in mshv_parent_partition_init()