Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH

Introduce mshv_use_overlay_gpfn() to check if a page needs to be
allocated and passed to the hypervisor to map VP state pages. This is
only needed on L1VH, and only on some (newer) versions of the
hypervisor, hence the need to check vmm_capabilities.

Introduce functions hv_map/unmap_vp_state_page() to handle the
allocation and freeing.

Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>
Reviewed-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
Reviewed-by: Anirudh Rayabharam <anirudh@anirudhrb.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>

authored by

Jinank Jain and committed by
Wei Liu
19c515c2 fd612d97

+101 -50
+6 -5
drivers/hv/mshv_root.h
··· 279 279 /* Choose between pages and bytes */ 280 280 struct hv_vp_state_data state_data, u64 page_count, 281 281 struct page **pages, u32 num_bytes, u8 *bytes); 282 - int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 283 - union hv_input_vtl input_vtl, 284 - struct page **state_page); 285 - int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 286 - union hv_input_vtl input_vtl); 282 + int hv_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 283 + union hv_input_vtl input_vtl, 284 + struct page **state_page); 285 + int hv_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 286 + struct page *state_page, 287 + union hv_input_vtl input_vtl); 287 288 int hv_call_create_port(u64 port_partition_id, union hv_port_id port_id, 288 289 u64 connection_partition_id, struct hv_port_info *port_info, 289 290 u8 port_vtl, u8 min_connection_vtl, int node);
+58 -6
drivers/hv/mshv_root_hv_call.c
··· 526 526 return ret; 527 527 } 528 528 529 - int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 530 - union hv_input_vtl input_vtl, 531 - struct page **state_page) 529 + static int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 530 + union hv_input_vtl input_vtl, 531 + struct page **state_page) 532 532 { 533 533 struct hv_input_map_vp_state_page *input; 534 534 struct hv_output_map_vp_state_page *output; ··· 542 542 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 543 543 output = *this_cpu_ptr(hyperv_pcpu_output_arg); 544 544 545 + memset(input, 0, sizeof(*input)); 545 546 input->partition_id = partition_id; 546 547 input->vp_index = vp_index; 547 548 input->type = type; 548 549 input->input_vtl = input_vtl; 549 550 550 - status = hv_do_hypercall(HVCALL_MAP_VP_STATE_PAGE, input, output); 551 + if (*state_page) { 552 + input->flags.map_location_provided = 1; 553 + input->requested_map_location = 554 + page_to_pfn(*state_page); 555 + } 556 + 557 + status = hv_do_hypercall(HVCALL_MAP_VP_STATE_PAGE, input, 558 + output); 551 559 552 560 if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { 553 561 if (hv_result_success(status)) ··· 573 565 return ret; 574 566 } 575 567 576 - int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 577 - union hv_input_vtl input_vtl) 568 + static bool mshv_use_overlay_gpfn(void) 569 + { 570 + return hv_l1vh_partition() && 571 + mshv_root.vmm_caps.vmm_can_provide_overlay_gpfn; 572 + } 573 + 574 + int hv_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 575 + union hv_input_vtl input_vtl, 576 + struct page **state_page) 577 + { 578 + int ret = 0; 579 + struct page *allocated_page = NULL; 580 + 581 + if (mshv_use_overlay_gpfn()) { 582 + allocated_page = alloc_page(GFP_KERNEL); 583 + if (!allocated_page) 584 + return -ENOMEM; 585 + *state_page = allocated_page; 586 + } else { 587 + *state_page = NULL; 588 + } 589 + 590 + ret = hv_call_map_vp_state_page(partition_id, vp_index, type, input_vtl, 591 + state_page); 592 + 593 + if (ret && allocated_page) { 594 + __free_page(allocated_page); 595 + *state_page = NULL; 596 + } 597 + 598 + return ret; 599 + } 600 + 601 + static int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 602 + union hv_input_vtl input_vtl) 578 603 { 579 604 unsigned long flags; 580 605 u64 status; ··· 629 588 local_irq_restore(flags); 630 589 631 590 return hv_result_to_errno(status); 591 + } 592 + 593 + int hv_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 594 + struct page *state_page, union hv_input_vtl input_vtl) 595 + { 596 + int ret = hv_call_unmap_vp_state_page(partition_id, vp_index, type, input_vtl); 597 + 598 + if (mshv_use_overlay_gpfn() && state_page) 599 + __free_page(state_page); 600 + 601 + return ret; 632 602 } 633 603 634 604 int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code,
+37 -39
drivers/hv/mshv_root_main.c
··· 892 892 { 893 893 struct mshv_create_vp args; 894 894 struct mshv_vp *vp; 895 - struct page *intercept_message_page, *register_page, *ghcb_page; 895 + struct page *intercept_msg_page, *register_page, *ghcb_page; 896 896 void *stats_pages[2]; 897 897 long ret; 898 898 ··· 910 910 if (ret) 911 911 return ret; 912 912 913 - ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index, 914 - HV_VP_STATE_PAGE_INTERCEPT_MESSAGE, 915 - input_vtl_zero, 916 - &intercept_message_page); 913 + ret = hv_map_vp_state_page(partition->pt_id, args.vp_index, 914 + HV_VP_STATE_PAGE_INTERCEPT_MESSAGE, 915 + input_vtl_zero, &intercept_msg_page); 917 916 if (ret) 918 917 goto destroy_vp; 919 918 920 919 if (!mshv_partition_encrypted(partition)) { 921 - ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index, 922 - HV_VP_STATE_PAGE_REGISTERS, 923 - input_vtl_zero, 924 - &register_page); 920 + ret = hv_map_vp_state_page(partition->pt_id, args.vp_index, 921 + HV_VP_STATE_PAGE_REGISTERS, 922 + input_vtl_zero, &register_page); 925 923 if (ret) 926 924 goto unmap_intercept_message_page; 927 925 } 928 926 929 927 if (mshv_partition_encrypted(partition) && 930 928 is_ghcb_mapping_available()) { 931 - ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index, 932 - HV_VP_STATE_PAGE_GHCB, 933 - input_vtl_normal, 934 - &ghcb_page); 929 + ret = hv_map_vp_state_page(partition->pt_id, args.vp_index, 930 + HV_VP_STATE_PAGE_GHCB, 931 + input_vtl_normal, &ghcb_page); 935 932 if (ret) 936 933 goto unmap_register_page; 937 934 } ··· 959 962 atomic64_set(&vp->run.vp_signaled_count, 0); 960 963 961 964 vp->vp_index = args.vp_index; 962 - vp->vp_intercept_msg_page = page_to_virt(intercept_message_page); 965 + vp->vp_intercept_msg_page = page_to_virt(intercept_msg_page); 963 966 if (!mshv_partition_encrypted(partition)) 964 967 vp->vp_register_page = page_to_virt(register_page); 965 968 ··· 992 995 if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT) 993 996 mshv_vp_stats_unmap(partition->pt_id, args.vp_index); 994 997 unmap_ghcb_page: 995 - if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) { 996 - hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index, 997 - HV_VP_STATE_PAGE_GHCB, 998 - input_vtl_normal); 999 - } 998 + if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) 999 + hv_unmap_vp_state_page(partition->pt_id, args.vp_index, 1000 + HV_VP_STATE_PAGE_GHCB, ghcb_page, 1001 + input_vtl_normal); 1000 1002 unmap_register_page: 1001 - if (!mshv_partition_encrypted(partition)) { 1002 - hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index, 1003 - HV_VP_STATE_PAGE_REGISTERS, 1004 - input_vtl_zero); 1005 - } 1003 + if (!mshv_partition_encrypted(partition)) 1004 + hv_unmap_vp_state_page(partition->pt_id, args.vp_index, 1005 + HV_VP_STATE_PAGE_REGISTERS, 1006 + register_page, input_vtl_zero); 1006 1007 unmap_intercept_message_page: 1007 - hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index, 1008 - HV_VP_STATE_PAGE_INTERCEPT_MESSAGE, 1009 - input_vtl_zero); 1008 + hv_unmap_vp_state_page(partition->pt_id, args.vp_index, 1009 + HV_VP_STATE_PAGE_INTERCEPT_MESSAGE, 1010 + intercept_msg_page, input_vtl_zero); 1010 1011 destroy_vp: 1011 1012 hv_call_delete_vp(partition->pt_id, args.vp_index); 1012 1013 return ret; ··· 1745 1750 mshv_vp_stats_unmap(partition->pt_id, vp->vp_index); 1746 1751 1747 1752 if (vp->vp_register_page) { 1748 - (void)hv_call_unmap_vp_state_page(partition->pt_id, 1749 - vp->vp_index, 1750 - HV_VP_STATE_PAGE_REGISTERS, 1751 - input_vtl_zero); 1753 + (void)hv_unmap_vp_state_page(partition->pt_id, 1754 + vp->vp_index, 1755 + HV_VP_STATE_PAGE_REGISTERS, 1756 + virt_to_page(vp->vp_register_page), 1757 + input_vtl_zero); 1752 1758 vp->vp_register_page = NULL; 1753 1759 } 1754 1760 1755 - (void)hv_call_unmap_vp_state_page(partition->pt_id, 1756 - vp->vp_index, 1757 - HV_VP_STATE_PAGE_INTERCEPT_MESSAGE, 1758 - input_vtl_zero); 1761 + (void)hv_unmap_vp_state_page(partition->pt_id, 1762 + vp->vp_index, 1763 + HV_VP_STATE_PAGE_INTERCEPT_MESSAGE, 1764 + virt_to_page(vp->vp_intercept_msg_page), 1765 + input_vtl_zero); 1759 1766 vp->vp_intercept_msg_page = NULL; 1760 1767 1761 1768 if (vp->vp_ghcb_page) { 1762 - (void)hv_call_unmap_vp_state_page(partition->pt_id, 1763 - vp->vp_index, 1764 - HV_VP_STATE_PAGE_GHCB, 1765 - input_vtl_normal); 1769 + (void)hv_unmap_vp_state_page(partition->pt_id, 1770 + vp->vp_index, 1771 + HV_VP_STATE_PAGE_GHCB, 1772 + virt_to_page(vp->vp_ghcb_page), 1773 + input_vtl_normal); 1766 1774 vp->vp_ghcb_page = NULL; 1767 1775 } 1768 1776