Lines Matching full:partition
39 MODULE_DESCRIPTION("Microsoft Hyper-V root partition VMM interface /dev/mshv");
75 static int mshv_init_async_handler(struct mshv_partition *partition);
119 * Only allow hypercalls that have a u64 partition id as the first member of
150 static int mshv_ioctl_passthru_hvcall(struct mshv_partition *partition, in mshv_ioctl_passthru_hvcall() argument
182 /* async hypercalls can only be called from partition fd */ in mshv_ioctl_passthru_hvcall()
185 ret = mshv_init_async_handler(partition); in mshv_ioctl_passthru_hvcall()
211 *(u64 *)input_pg = partition->pt_id; in mshv_ioctl_passthru_hvcall()
221 mshv_async_hvcall_handler(partition, &status); in mshv_ioctl_passthru_hvcall()
229 ret = hv_call_deposit_pages(NUMA_NO_NODE, partition->pt_id, 1); in mshv_ioctl_passthru_hvcall()
888 mshv_partition_ioctl_create_vp(struct mshv_partition *partition, in mshv_partition_ioctl_create_vp() argument
903 if (partition->pt_vp_array[args.vp_index]) 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()
907 0 /* Only valid for root partition VPs */); 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()
918 if (!mshv_partition_encrypted(partition)) { 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()
927 if (mshv_partition_encrypted(partition) && 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()
960 if (!mshv_partition_encrypted(partition)) in mshv_partition_ioctl_create_vp()
963 if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) in mshv_partition_ioctl_create_vp()
978 /* already exclusive with the partition mutex for all ioctls */ 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()
985 mshv_partition_put(partition); in mshv_partition_ioctl_create_vp()
990 mshv_vp_stats_unmap(partition->pt_id, args.vp_index); in mshv_partition_ioctl_create_vp()
992 if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) { 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()
998 if (!mshv_partition_encrypted(partition)) { 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()
1012 static int mshv_init_async_handler(struct mshv_partition *partition) in mshv_init_async_handler() argument
1014 if (completion_done(&partition->async_hypercall)) { in mshv_init_async_handler()
1015 pt_err(partition, in mshv_init_async_handler()
1020 reinit_completion(&partition->async_hypercall); in mshv_init_async_handler()
1026 struct mshv_partition *partition = data; in mshv_async_hvcall_handler() local
1028 wait_for_completion(&partition->async_hypercall); in mshv_async_hvcall_handler()
1029 pt_dbg(partition, "Async hypercall completed!\n"); in mshv_async_hvcall_handler()
1031 *status = partition->async_hypercall_status; in mshv_async_hvcall_handler()
1042 return hv_call_modify_spa_host_access(region->partition->pt_id, in mshv_partition_region_share()
1056 return hv_call_modify_spa_host_access(region->partition->pt_id, in mshv_partition_region_unshare()
1073 return hv_call_map_gpa_pages(region->partition->pt_id, in mshv_region_remap_pages()
1162 mshv_partition_region_by_gfn(struct mshv_partition *partition, u64 gfn) in mshv_partition_region_by_gfn() argument
1166 hlist_for_each_entry(region, &partition->pt_mem_regions, hnode) { in mshv_partition_region_by_gfn()
1176 mshv_partition_region_by_uaddr(struct mshv_partition *partition, u64 uaddr) in mshv_partition_region_by_uaddr() argument
1180 hlist_for_each_entry(region, &partition->pt_mem_regions, hnode) { in mshv_partition_region_by_uaddr()
1194 static int mshv_partition_create_region(struct mshv_partition *partition, in mshv_partition_create_region() argument
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()
1226 region->partition = partition; in mshv_partition_create_region()
1240 struct mshv_partition *partition = region->partition; in mshv_partition_mem_region_map() local
1245 pt_err(partition, "Failed to populate memory region: %d\n", in mshv_partition_mem_region_map()
1251 * For an SNP partition it is a requirement that for every memory region in mshv_partition_mem_region_map()
1252 * that we are going to map for this partition we should make sure that in mshv_partition_mem_region_map()
1257 if (mshv_partition_encrypted(partition)) { in mshv_partition_mem_region_map()
1260 pt_err(partition, in mshv_partition_mem_region_map()
1268 if (ret && mshv_partition_encrypted(partition)) { in mshv_partition_mem_region_map()
1275 pt_err(partition, in mshv_partition_mem_region_map()
1306 mshv_map_user_memory(struct mshv_partition *partition, in mshv_map_user_memory() argument
1328 ret = mshv_partition_create_region(partition, &mem, ®ion, 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()
1354 mshv_unmap_user_memory(struct mshv_partition *partition, in mshv_unmap_user_memory() argument
1363 region = mshv_partition_region_by_gfn(partition, mem.guest_pfn); in mshv_unmap_user_memory()
1379 hv_call_unmap_gpa_pages(partition->pt_id, region->start_gfn, in mshv_unmap_user_memory()
1389 mshv_partition_ioctl_set_memory(struct mshv_partition *partition, in mshv_partition_ioctl_set_memory() argument
1405 return mshv_unmap_user_memory(partition, mem); in mshv_partition_ioctl_set_memory()
1407 return mshv_map_user_memory(partition, mem); in mshv_partition_ioctl_set_memory()
1411 mshv_partition_ioctl_ioeventfd(struct mshv_partition *partition, in mshv_partition_ioctl_ioeventfd() argument
1419 return mshv_set_unset_ioeventfd(partition, &args); in mshv_partition_ioctl_ioeventfd()
1423 mshv_partition_ioctl_irqfd(struct mshv_partition *partition, in mshv_partition_ioctl_irqfd() argument
1431 return mshv_set_unset_irqfd(partition, &args); in mshv_partition_ioctl_irqfd()
1435 mshv_partition_ioctl_get_gpap_access_bitmap(struct mshv_partition *partition, in mshv_partition_ioctl_get_gpap_access_bitmap() argument
1492 ret = hv_call_get_gpa_access_states(partition->pt_id, args.page_count, in mshv_partition_ioctl_get_gpap_access_bitmap()
1519 mshv_partition_ioctl_set_msi_routing(struct mshv_partition *partition, in mshv_partition_ioctl_set_msi_routing() argument
1542 ret = mshv_update_routing_table(partition, entries, args.nr); in mshv_partition_ioctl_set_msi_routing()
1549 mshv_partition_ioctl_initialize(struct mshv_partition *partition) in mshv_partition_ioctl_initialize() argument
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() local
1577 if (mutex_lock_killable(&partition->pt_mutex)) in mshv_partition_ioctl()
1582 ret = mshv_partition_ioctl_initialize(partition); in mshv_partition_ioctl()
1585 ret = mshv_partition_ioctl_set_memory(partition, uarg); in mshv_partition_ioctl()
1588 ret = mshv_partition_ioctl_create_vp(partition, uarg); in mshv_partition_ioctl()
1591 ret = mshv_partition_ioctl_irqfd(partition, uarg); in mshv_partition_ioctl()
1594 ret = mshv_partition_ioctl_ioeventfd(partition, uarg); in mshv_partition_ioctl()
1597 ret = mshv_partition_ioctl_set_msi_routing(partition, uarg); in mshv_partition_ioctl()
1600 ret = mshv_partition_ioctl_get_gpap_access_bitmap(partition, in mshv_partition_ioctl()
1604 ret = mshv_ioctl_passthru_hvcall(partition, true, uarg); in mshv_partition_ioctl()
1610 mutex_unlock(&partition->pt_mutex); in mshv_partition_ioctl()
1678 static void drain_all_vps(const struct mshv_partition *partition) in drain_all_vps() argument
1684 * VPs are reachable from ISR. It is safe to not take the partition in drain_all_vps()
1686 * partition from the list. in drain_all_vps()
1689 vp = partition->pt_vp_array[i]; in drain_all_vps()
1703 remove_partition(struct mshv_partition *partition) in remove_partition() argument
1706 hlist_del_rcu(&partition->pt_hnode); in remove_partition()
1713 * Tear down a partition and remove it from the list.
1714 * Partition's refcount must be 0
1716 static void destroy_partition(struct mshv_partition *partition) in destroy_partition() argument
1723 if (refcount_read(&partition->pt_ref_count)) { in destroy_partition()
1724 pt_err(partition, in destroy_partition()
1725 "Attempt to destroy partition but refcount > 0\n"); in destroy_partition()
1729 if (partition->pt_initialized) { in destroy_partition()
1732 * done before removing the partition from the partition list. in destroy_partition()
1735 drain_all_vps(partition); 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()
1747 (void)hv_call_unmap_vp_state_page(partition->pt_id, in destroy_partition()
1754 (void)hv_call_unmap_vp_state_page(partition->pt_id, in destroy_partition()
1761 (void)hv_call_unmap_vp_state_page(partition->pt_id, 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()
1779 remove_partition(partition); in destroy_partition()
1782 hlist_for_each_entry_safe(region, n, &partition->pt_mem_regions, in destroy_partition()
1786 if (mshv_partition_encrypted(partition)) { in destroy_partition()
1789 pt_err(partition, 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()
1805 mshv_free_routing_table(partition); in destroy_partition()
1806 kfree(partition); in destroy_partition()
1810 mshv_partition *mshv_partition_get(struct mshv_partition *partition) in mshv_partition_get() argument
1812 if (refcount_inc_not_zero(&partition->pt_ref_count)) in mshv_partition_get()
1813 return partition; in mshv_partition_get()
1832 mshv_partition_put(struct mshv_partition *partition) in mshv_partition_put() argument
1834 if (refcount_dec_and_test(&partition->pt_ref_count)) in mshv_partition_put()
1835 destroy_partition(partition); in mshv_partition_put()
1841 struct mshv_partition *partition = filp->private_data; in mshv_partition_release() local
1843 mshv_eventfd_release(partition); in mshv_partition_release()
1845 cleanup_srcu_struct(&partition->pt_irq_srcu); in mshv_partition_release()
1847 mshv_partition_put(partition); in mshv_partition_release()
1853 add_partition(struct mshv_partition *partition) in add_partition() argument
1857 hash_add_rcu(mshv_root.pt_htable, &partition->pt_hnode, in add_partition()
1858 partition->pt_id); in add_partition()
1872 struct mshv_partition *partition; in mshv_ioctl_create_partition() local
1902 partition = kzalloc(sizeof(*partition), GFP_KERNEL); in mshv_ioctl_create_partition()
1903 if (!partition) 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()
1923 mshv_eventfd_init(partition); 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()
1936 ret = add_partition(partition); in mshv_ioctl_create_partition()
1940 ret = mshv_init_async_handler(partition); in mshv_ioctl_create_partition()
1951 partition, O_RDWR); in mshv_ioctl_create_partition()
1964 remove_partition(partition); 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()
1970 kfree(partition); in mshv_ioctl_create_partition()