1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2023, Microsoft Corporation. 4 * 5 * Hypercall helper functions used by the mshv_root module. 6 * 7 * Authors: Microsoft Linux virtualization team 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/mm.h> 12 #include <linux/export.h> 13 #include <asm/mshyperv.h> 14 15 #include "mshv_root.h" 16 17 /* Determined empirically */ 18 #define HV_INIT_PARTITION_DEPOSIT_PAGES 208 19 #define HV_MAP_GPA_DEPOSIT_PAGES 256 20 #define HV_UMAP_GPA_PAGES 512 21 22 #define HV_PAGE_COUNT_2M_ALIGNED(pg_count) (!((pg_count) & (0x200 - 1))) 23 24 #define HV_WITHDRAW_BATCH_SIZE (HV_HYP_PAGE_SIZE / sizeof(u64)) 25 #define HV_MAP_GPA_BATCH_SIZE \ 26 ((HV_HYP_PAGE_SIZE - sizeof(struct hv_input_map_gpa_pages)) \ 27 / sizeof(u64)) 28 #define HV_GET_VP_STATE_BATCH_SIZE \ 29 ((HV_HYP_PAGE_SIZE - sizeof(struct hv_input_get_vp_state)) \ 30 / sizeof(u64)) 31 #define HV_SET_VP_STATE_BATCH_SIZE \ 32 ((HV_HYP_PAGE_SIZE - sizeof(struct hv_input_set_vp_state)) \ 33 / sizeof(u64)) 34 #define HV_GET_GPA_ACCESS_STATES_BATCH_SIZE \ 35 ((HV_HYP_PAGE_SIZE - sizeof(union hv_gpa_page_access_state)) \ 36 / sizeof(union hv_gpa_page_access_state)) 37 #define HV_MODIFY_SPARSE_SPA_PAGE_HOST_ACCESS_MAX_PAGE_COUNT \ 38 ((HV_HYP_PAGE_SIZE - \ 39 sizeof(struct hv_input_modify_sparse_spa_page_host_access)) / \ 40 sizeof(u64)) 41 42 int hv_call_withdraw_memory(u64 count, int node, u64 partition_id) 43 { 44 struct hv_input_withdraw_memory *input_page; 45 struct hv_output_withdraw_memory *output_page; 46 struct page *page; 47 u16 completed; 48 u64 status, withdrawn = 0; 49 int i; 50 unsigned long flags; 51 52 page = alloc_page(GFP_KERNEL); 53 if (!page) 54 return -ENOMEM; 55 output_page = page_address(page); 56 57 while (withdrawn < count) { 58 local_irq_save(flags); 59 60 input_page = *this_cpu_ptr(hyperv_pcpu_input_arg); 61 62 memset(input_page, 0, sizeof(*input_page)); 63 input_page->partition_id = partition_id; 64 status = hv_do_rep_hypercall(HVCALL_WITHDRAW_MEMORY, 65 min(count - withdrawn, HV_WITHDRAW_BATCH_SIZE), 66 0, input_page, output_page); 67 68 local_irq_restore(flags); 69 70 completed = hv_repcomp(status); 71 72 for (i = 0; i < completed; i++) 73 __free_page(pfn_to_page(output_page->gpa_page_list[i])); 74 75 if (!hv_result_success(status)) { 76 if (hv_result(status) == HV_STATUS_NO_RESOURCES) 77 status = HV_STATUS_SUCCESS; 78 break; 79 } 80 81 withdrawn += completed; 82 } 83 free_page((unsigned long)output_page); 84 85 trace_mshv_hvcall_withdraw_memory(partition_id, withdrawn, status); 86 87 return hv_result_to_errno(status); 88 } 89 90 int hv_call_create_partition(u64 flags, 91 struct hv_partition_creation_properties creation_properties, 92 union hv_partition_isolation_properties isolation_properties, 93 u64 *partition_id) 94 { 95 struct hv_input_create_partition *input; 96 struct hv_output_create_partition *output; 97 u64 status; 98 int ret; 99 unsigned long irq_flags; 100 101 do { 102 local_irq_save(irq_flags); 103 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 104 output = *this_cpu_ptr(hyperv_pcpu_output_arg); 105 106 memset(input, 0, sizeof(*input)); 107 input->flags = flags; 108 input->compatibility_version = HV_COMPATIBILITY_21_H2; 109 110 memcpy(&input->partition_creation_properties, &creation_properties, 111 sizeof(creation_properties)); 112 113 memcpy(&input->isolation_properties, &isolation_properties, 114 sizeof(isolation_properties)); 115 116 status = hv_do_hypercall(HVCALL_CREATE_PARTITION, 117 input, output); 118 119 if (!hv_result_needs_memory(status)) { 120 if (hv_result_success(status)) 121 *partition_id = output->partition_id; 122 local_irq_restore(irq_flags); 123 ret = hv_result_to_errno(status); 124 break; 125 } 126 local_irq_restore(irq_flags); 127 ret = hv_deposit_memory(hv_current_partition_id, status); 128 } while (!ret); 129 130 trace_mshv_hvcall_create_partition(flags, ret ? ret : *partition_id); 131 132 return ret; 133 } 134 135 int hv_call_initialize_partition(u64 partition_id) 136 { 137 struct hv_input_initialize_partition input; 138 u64 status; 139 int ret; 140 141 input.partition_id = partition_id; 142 143 ret = hv_call_deposit_pages(NUMA_NO_NODE, partition_id, 144 HV_INIT_PARTITION_DEPOSIT_PAGES); 145 if (ret) 146 return ret; 147 148 do { 149 status = hv_do_fast_hypercall8(HVCALL_INITIALIZE_PARTITION, 150 *(u64 *)&input); 151 152 if (!hv_result_needs_memory(status)) { 153 ret = hv_result_to_errno(status); 154 break; 155 } 156 ret = hv_deposit_memory(partition_id, status); 157 } while (!ret); 158 159 trace_mshv_hvcall_initialize_partition(partition_id, status); 160 161 return ret; 162 } 163 164 int hv_call_finalize_partition(u64 partition_id) 165 { 166 struct hv_input_finalize_partition input; 167 u64 status; 168 169 input.partition_id = partition_id; 170 status = hv_do_fast_hypercall8(HVCALL_FINALIZE_PARTITION, 171 *(u64 *)&input); 172 173 trace_mshv_hvcall_finalize_partition(partition_id, status); 174 175 return hv_result_to_errno(status); 176 } 177 178 int hv_call_delete_partition(u64 partition_id) 179 { 180 struct hv_input_delete_partition input; 181 u64 status; 182 183 input.partition_id = partition_id; 184 status = hv_do_fast_hypercall8(HVCALL_DELETE_PARTITION, *(u64 *)&input); 185 186 trace_mshv_hvcall_delete_partition(partition_id, status); 187 188 return hv_result_to_errno(status); 189 } 190 191 /* Ask the hypervisor to map guest ram pages or the guest mmio space */ 192 static int hv_do_map_gpa_hcall(u64 partition_id, u64 gfn, u64 page_struct_count, 193 u32 flags, struct page **pages, u64 mmio_spa) 194 { 195 struct hv_input_map_gpa_pages *input_page; 196 u64 status, *pfnlist; 197 unsigned long irq_flags, large_shift = 0; 198 int ret = 0, done = 0; 199 u64 page_count = page_struct_count; 200 201 if (page_count == 0 || (pages && mmio_spa)) 202 return -EINVAL; 203 204 if (flags & HV_MAP_GPA_LARGE_PAGE) { 205 if (mmio_spa) 206 return -EINVAL; 207 208 if (!HV_PAGE_COUNT_2M_ALIGNED(page_count)) 209 return -EINVAL; 210 211 large_shift = HV_HYP_LARGE_PAGE_SHIFT - HV_HYP_PAGE_SHIFT; 212 page_count >>= large_shift; 213 } 214 215 while (done < page_count) { 216 ulong i, completed, remain = page_count - done; 217 int rep_count = min(remain, HV_MAP_GPA_BATCH_SIZE); 218 219 local_irq_save(irq_flags); 220 input_page = *this_cpu_ptr(hyperv_pcpu_input_arg); 221 222 input_page->target_partition_id = partition_id; 223 input_page->target_gpa_base = gfn + (done << large_shift); 224 input_page->map_flags = flags; 225 pfnlist = input_page->source_gpa_page_list; 226 227 for (i = 0; i < rep_count; i++) 228 if (flags & HV_MAP_GPA_NO_ACCESS) { 229 pfnlist[i] = 0; 230 } else if (pages) { 231 u64 index = (done + i) << large_shift; 232 233 if (index >= page_struct_count) { 234 ret = -EINVAL; 235 break; 236 } 237 pfnlist[i] = page_to_pfn(pages[index]); 238 } else { 239 pfnlist[i] = mmio_spa + done + i; 240 } 241 if (ret) 242 break; 243 244 status = hv_do_rep_hypercall(HVCALL_MAP_GPA_PAGES, rep_count, 0, 245 input_page, NULL); 246 local_irq_restore(irq_flags); 247 248 completed = hv_repcomp(status); 249 250 if (hv_result_needs_memory(status)) { 251 ret = hv_call_deposit_pages(NUMA_NO_NODE, partition_id, 252 HV_MAP_GPA_DEPOSIT_PAGES); 253 if (ret) 254 break; 255 256 } else if (!hv_result_success(status)) { 257 ret = hv_result_to_errno(status); 258 break; 259 } 260 261 done += completed; 262 } 263 264 if (ret && done) { 265 u32 unmap_flags = 0; 266 267 if (flags & HV_MAP_GPA_LARGE_PAGE) 268 unmap_flags |= HV_UNMAP_GPA_LARGE_PAGE; 269 hv_call_unmap_gpa_pages(partition_id, gfn, done, unmap_flags); 270 } 271 272 return ret; 273 } 274 275 /* Ask the hypervisor to map guest ram pages */ 276 int hv_call_map_gpa_pages(u64 partition_id, u64 gpa_target, u64 page_count, 277 u32 flags, struct page **pages) 278 { 279 return hv_do_map_gpa_hcall(partition_id, gpa_target, page_count, 280 flags, pages, 0); 281 } 282 283 /* Ask the hypervisor to map guest mmio space */ 284 int hv_call_map_mmio_pages(u64 partition_id, u64 gfn, u64 mmio_spa, u64 numpgs) 285 { 286 int i; 287 u32 flags = HV_MAP_GPA_READABLE | HV_MAP_GPA_WRITABLE | 288 HV_MAP_GPA_NOT_CACHED; 289 290 for (i = 0; i < numpgs; i++) 291 if (page_is_ram(mmio_spa + i)) 292 return -EINVAL; 293 294 return hv_do_map_gpa_hcall(partition_id, gfn, numpgs, flags, NULL, 295 mmio_spa); 296 } 297 298 int hv_call_unmap_gpa_pages(u64 partition_id, u64 gfn, u64 page_count_4k, 299 u32 flags) 300 { 301 struct hv_input_unmap_gpa_pages *input_page; 302 u64 status, page_count = page_count_4k; 303 unsigned long irq_flags, large_shift = 0; 304 int ret = 0, done = 0; 305 306 if (page_count == 0) 307 return -EINVAL; 308 309 if (flags & HV_UNMAP_GPA_LARGE_PAGE) { 310 if (!HV_PAGE_COUNT_2M_ALIGNED(page_count)) 311 return -EINVAL; 312 313 large_shift = HV_HYP_LARGE_PAGE_SHIFT - HV_HYP_PAGE_SHIFT; 314 page_count >>= large_shift; 315 } 316 317 while (done < page_count) { 318 ulong completed, remain = page_count - done; 319 int rep_count = min(remain, HV_UMAP_GPA_PAGES); 320 321 local_irq_save(irq_flags); 322 input_page = *this_cpu_ptr(hyperv_pcpu_input_arg); 323 324 input_page->target_partition_id = partition_id; 325 input_page->target_gpa_base = gfn + (done << large_shift); 326 input_page->unmap_flags = flags; 327 status = hv_do_rep_hypercall(HVCALL_UNMAP_GPA_PAGES, rep_count, 328 0, input_page, NULL); 329 local_irq_restore(irq_flags); 330 331 completed = hv_repcomp(status); 332 if (!hv_result_success(status)) { 333 ret = hv_result_to_errno(status); 334 break; 335 } 336 337 done += completed; 338 } 339 340 return ret; 341 } 342 343 int hv_call_get_gpa_access_states(u64 partition_id, u32 count, u64 gpa_base_pfn, 344 union hv_gpa_page_access_state_flags state_flags, 345 int *written_total, 346 union hv_gpa_page_access_state *states) 347 { 348 struct hv_input_get_gpa_pages_access_state *input_page; 349 union hv_gpa_page_access_state *output_page; 350 int completed = 0; 351 unsigned long remaining = count; 352 int rep_count, i; 353 u64 status = 0; 354 unsigned long flags; 355 356 *written_total = 0; 357 while (remaining) { 358 local_irq_save(flags); 359 input_page = *this_cpu_ptr(hyperv_pcpu_input_arg); 360 output_page = *this_cpu_ptr(hyperv_pcpu_output_arg); 361 362 input_page->partition_id = partition_id; 363 input_page->hv_gpa_page_number = gpa_base_pfn + *written_total; 364 input_page->flags = state_flags; 365 rep_count = min(remaining, HV_GET_GPA_ACCESS_STATES_BATCH_SIZE); 366 367 status = hv_do_rep_hypercall(HVCALL_GET_GPA_PAGES_ACCESS_STATES, rep_count, 368 0, input_page, output_page); 369 if (!hv_result_success(status)) { 370 local_irq_restore(flags); 371 break; 372 } 373 completed = hv_repcomp(status); 374 for (i = 0; i < completed; ++i) 375 states[i].as_uint8 = output_page[i].as_uint8; 376 377 local_irq_restore(flags); 378 states += completed; 379 *written_total += completed; 380 remaining -= completed; 381 } 382 383 return hv_result_to_errno(status); 384 } 385 386 int hv_call_assert_virtual_interrupt(u64 partition_id, u32 vector, 387 u64 dest_addr, 388 union hv_interrupt_control control) 389 { 390 struct hv_input_assert_virtual_interrupt *input; 391 unsigned long flags; 392 u64 status; 393 394 local_irq_save(flags); 395 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 396 memset(input, 0, sizeof(*input)); 397 input->partition_id = partition_id; 398 input->vector = vector; 399 /* 400 * NOTE: dest_addr only needs to be provided while asserting an 401 * interrupt on x86 platform 402 */ 403 #if IS_ENABLED(CONFIG_X86) 404 input->dest_addr = dest_addr; 405 #endif 406 input->control = control; 407 status = hv_do_hypercall(HVCALL_ASSERT_VIRTUAL_INTERRUPT, input, NULL); 408 local_irq_restore(flags); 409 410 return hv_result_to_errno(status); 411 } 412 413 int hv_call_delete_vp(u64 partition_id, u32 vp_index) 414 { 415 union hv_input_delete_vp input = {}; 416 u64 status; 417 418 input.partition_id = partition_id; 419 input.vp_index = vp_index; 420 421 status = hv_do_fast_hypercall16(HVCALL_DELETE_VP, 422 input.as_uint64[0], input.as_uint64[1]); 423 424 return hv_result_to_errno(status); 425 } 426 EXPORT_SYMBOL_GPL(hv_call_delete_vp); 427 428 int hv_call_get_vp_state(u32 vp_index, u64 partition_id, 429 struct hv_vp_state_data state_data, 430 /* Choose between pages and ret_output */ 431 u64 page_count, struct page **pages, 432 union hv_output_get_vp_state *ret_output) 433 { 434 struct hv_input_get_vp_state *input; 435 union hv_output_get_vp_state *output; 436 u64 status; 437 int i; 438 u64 control; 439 unsigned long flags; 440 int ret = 0; 441 442 if (page_count > HV_GET_VP_STATE_BATCH_SIZE) 443 return -EINVAL; 444 445 if (!page_count && !ret_output) 446 return -EINVAL; 447 448 do { 449 local_irq_save(flags); 450 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 451 output = *this_cpu_ptr(hyperv_pcpu_output_arg); 452 memset(input, 0, sizeof(*input)); 453 memset(output, 0, sizeof(*output)); 454 455 input->partition_id = partition_id; 456 input->vp_index = vp_index; 457 input->state_data = state_data; 458 for (i = 0; i < page_count; i++) 459 input->output_data_pfns[i] = page_to_pfn(pages[i]); 460 461 control = (HVCALL_GET_VP_STATE) | 462 (page_count << HV_HYPERCALL_VARHEAD_OFFSET); 463 464 status = hv_do_hypercall(control, input, output); 465 466 if (!hv_result_needs_memory(status)) { 467 if (hv_result_success(status) && ret_output) 468 memcpy(ret_output, output, sizeof(*output)); 469 470 local_irq_restore(flags); 471 ret = hv_result_to_errno(status); 472 break; 473 } 474 local_irq_restore(flags); 475 476 ret = hv_deposit_memory(partition_id, status); 477 } while (!ret); 478 479 return ret; 480 } 481 482 int hv_call_set_vp_state(u32 vp_index, u64 partition_id, 483 /* Choose between pages and bytes */ 484 struct hv_vp_state_data state_data, u64 page_count, 485 struct page **pages, u32 num_bytes, u8 *bytes) 486 { 487 struct hv_input_set_vp_state *input; 488 u64 status; 489 int i; 490 u64 control; 491 unsigned long flags; 492 int ret = 0; 493 u16 varhead_sz; 494 495 if (page_count > HV_SET_VP_STATE_BATCH_SIZE) 496 return -EINVAL; 497 if (sizeof(*input) + num_bytes > HV_HYP_PAGE_SIZE) 498 return -EINVAL; 499 500 if (num_bytes) 501 /* round up to 8 and divide by 8 */ 502 varhead_sz = (num_bytes + 7) >> 3; 503 else if (page_count) 504 varhead_sz = page_count; 505 else 506 return -EINVAL; 507 508 do { 509 local_irq_save(flags); 510 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 511 memset(input, 0, sizeof(*input)); 512 513 input->partition_id = partition_id; 514 input->vp_index = vp_index; 515 input->state_data = state_data; 516 if (num_bytes) { 517 memcpy((u8 *)input->data, bytes, num_bytes); 518 } else { 519 for (i = 0; i < page_count; i++) 520 input->data[i].pfns = page_to_pfn(pages[i]); 521 } 522 523 control = (HVCALL_SET_VP_STATE) | 524 (varhead_sz << HV_HYPERCALL_VARHEAD_OFFSET); 525 526 status = hv_do_hypercall(control, input, NULL); 527 528 if (!hv_result_needs_memory(status)) { 529 local_irq_restore(flags); 530 ret = hv_result_to_errno(status); 531 break; 532 } 533 local_irq_restore(flags); 534 535 ret = hv_deposit_memory(partition_id, status); 536 } while (!ret); 537 538 return ret; 539 } 540 541 static int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 542 union hv_input_vtl input_vtl, 543 struct page **state_page) 544 { 545 struct hv_input_map_vp_state_page *input; 546 struct hv_output_map_vp_state_page *output; 547 u64 status; 548 int ret; 549 unsigned long flags; 550 551 do { 552 local_irq_save(flags); 553 554 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 555 output = *this_cpu_ptr(hyperv_pcpu_output_arg); 556 557 memset(input, 0, sizeof(*input)); 558 input->partition_id = partition_id; 559 input->vp_index = vp_index; 560 input->type = type; 561 input->input_vtl = input_vtl; 562 563 if (*state_page) { 564 input->flags.map_location_provided = 1; 565 input->requested_map_location = 566 page_to_pfn(*state_page); 567 } 568 569 status = hv_do_hypercall(HVCALL_MAP_VP_STATE_PAGE, input, 570 output); 571 572 if (!hv_result_needs_memory(status)) { 573 if (hv_result_success(status)) 574 *state_page = pfn_to_page(output->map_location); 575 local_irq_restore(flags); 576 ret = hv_result_to_errno(status); 577 break; 578 } 579 580 local_irq_restore(flags); 581 582 ret = hv_deposit_memory(partition_id, status); 583 } while (!ret); 584 585 trace_mshv_hvcall_map_vp_state_page(partition_id, vp_index, 586 type, status); 587 588 return ret; 589 } 590 591 static bool mshv_use_overlay_gpfn(void) 592 { 593 return hv_l1vh_partition() && 594 mshv_root.vmm_caps.vmm_can_provide_overlay_gpfn; 595 } 596 597 int hv_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 598 union hv_input_vtl input_vtl, 599 struct page **state_page) 600 { 601 int ret = 0; 602 struct page *allocated_page = NULL; 603 604 if (mshv_use_overlay_gpfn()) { 605 allocated_page = alloc_page(GFP_KERNEL); 606 if (!allocated_page) 607 return -ENOMEM; 608 *state_page = allocated_page; 609 } else { 610 *state_page = NULL; 611 } 612 613 ret = hv_call_map_vp_state_page(partition_id, vp_index, type, input_vtl, 614 state_page); 615 616 if (ret && allocated_page) { 617 __free_page(allocated_page); 618 *state_page = NULL; 619 } 620 621 return ret; 622 } 623 624 static int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 625 union hv_input_vtl input_vtl) 626 { 627 unsigned long flags; 628 u64 status; 629 struct hv_input_unmap_vp_state_page *input; 630 631 local_irq_save(flags); 632 633 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 634 635 memset(input, 0, sizeof(*input)); 636 637 input->partition_id = partition_id; 638 input->vp_index = vp_index; 639 input->type = type; 640 input->input_vtl = input_vtl; 641 642 status = hv_do_hypercall(HVCALL_UNMAP_VP_STATE_PAGE, input, NULL); 643 644 local_irq_restore(flags); 645 646 return hv_result_to_errno(status); 647 } 648 649 int hv_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type, 650 struct page *state_page, union hv_input_vtl input_vtl) 651 { 652 int ret = hv_call_unmap_vp_state_page(partition_id, vp_index, type, input_vtl); 653 654 if (mshv_use_overlay_gpfn() && state_page) 655 __free_page(state_page); 656 657 return ret; 658 } 659 660 int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code, 661 u64 arg, void *property_value, 662 size_t property_value_sz) 663 { 664 u64 status; 665 unsigned long flags; 666 struct hv_input_get_partition_property_ex *input; 667 struct hv_output_get_partition_property_ex *output; 668 669 local_irq_save(flags); 670 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 671 output = *this_cpu_ptr(hyperv_pcpu_output_arg); 672 673 memset(input, 0, sizeof(*input)); 674 input->partition_id = partition_id; 675 input->property_code = property_code; 676 input->arg = arg; 677 status = hv_do_hypercall(HVCALL_GET_PARTITION_PROPERTY_EX, input, output); 678 679 if (!hv_result_success(status)) { 680 local_irq_restore(flags); 681 hv_status_debug(status, "\n"); 682 return hv_result_to_errno(status); 683 } 684 memcpy(property_value, &output->property_value, property_value_sz); 685 686 local_irq_restore(flags); 687 688 return 0; 689 } 690 691 int 692 hv_call_clear_virtual_interrupt(u64 partition_id) 693 { 694 int status; 695 696 status = hv_do_fast_hypercall8(HVCALL_CLEAR_VIRTUAL_INTERRUPT, 697 partition_id); 698 699 return hv_result_to_errno(status); 700 } 701 702 int 703 hv_call_create_port(u64 port_partition_id, union hv_port_id port_id, 704 u64 connection_partition_id, 705 struct hv_port_info *port_info, 706 u8 port_vtl, u8 min_connection_vtl, int node) 707 { 708 struct hv_input_create_port *input; 709 unsigned long flags; 710 int ret = 0; 711 int status; 712 713 do { 714 local_irq_save(flags); 715 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 716 memset(input, 0, sizeof(*input)); 717 718 input->port_partition_id = port_partition_id; 719 input->port_id = port_id; 720 input->connection_partition_id = connection_partition_id; 721 input->port_info = *port_info; 722 input->port_vtl = port_vtl; 723 input->min_connection_vtl = min_connection_vtl; 724 input->proximity_domain_info = hv_numa_node_to_pxm_info(node); 725 status = hv_do_hypercall(HVCALL_CREATE_PORT, input, NULL); 726 local_irq_restore(flags); 727 if (hv_result_success(status)) 728 break; 729 730 if (!hv_result_needs_memory(status)) { 731 ret = hv_result_to_errno(status); 732 break; 733 } 734 ret = hv_deposit_memory(port_partition_id, status); 735 } while (!ret); 736 737 return ret; 738 } 739 740 int 741 hv_call_delete_port(u64 port_partition_id, union hv_port_id port_id) 742 { 743 union hv_input_delete_port input = { 0 }; 744 int status; 745 746 input.port_partition_id = port_partition_id; 747 input.port_id = port_id; 748 status = hv_do_fast_hypercall16(HVCALL_DELETE_PORT, 749 input.as_uint64[0], 750 input.as_uint64[1]); 751 752 return hv_result_to_errno(status); 753 } 754 755 int 756 hv_call_connect_port(u64 port_partition_id, union hv_port_id port_id, 757 u64 connection_partition_id, 758 union hv_connection_id connection_id, 759 struct hv_connection_info *connection_info, 760 u8 connection_vtl, int node) 761 { 762 struct hv_input_connect_port *input; 763 unsigned long flags; 764 int ret = 0, status; 765 766 do { 767 local_irq_save(flags); 768 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 769 memset(input, 0, sizeof(*input)); 770 input->port_partition_id = port_partition_id; 771 input->port_id = port_id; 772 input->connection_partition_id = connection_partition_id; 773 input->connection_id = connection_id; 774 input->connection_info = *connection_info; 775 input->connection_vtl = connection_vtl; 776 input->proximity_domain_info = hv_numa_node_to_pxm_info(node); 777 status = hv_do_hypercall(HVCALL_CONNECT_PORT, input, NULL); 778 779 local_irq_restore(flags); 780 if (hv_result_success(status)) 781 break; 782 783 if (!hv_result_needs_memory(status)) { 784 ret = hv_result_to_errno(status); 785 break; 786 } 787 ret = hv_deposit_memory(connection_partition_id, status); 788 } while (!ret); 789 790 return ret; 791 } 792 793 int 794 hv_call_disconnect_port(u64 connection_partition_id, 795 union hv_connection_id connection_id) 796 { 797 union hv_input_disconnect_port input = { 0 }; 798 int status; 799 800 input.connection_partition_id = connection_partition_id; 801 input.connection_id = connection_id; 802 input.is_doorbell = 1; 803 status = hv_do_fast_hypercall16(HVCALL_DISCONNECT_PORT, 804 input.as_uint64[0], 805 input.as_uint64[1]); 806 807 return hv_result_to_errno(status); 808 } 809 810 int 811 hv_call_notify_port_ring_empty(u32 sint_index) 812 { 813 union hv_input_notify_port_ring_empty input = { 0 }; 814 int status; 815 816 input.sint_index = sint_index; 817 status = hv_do_fast_hypercall8(HVCALL_NOTIFY_PORT_RING_EMPTY, 818 input.as_uint64); 819 820 return hv_result_to_errno(status); 821 } 822 823 /* 824 * Equivalent of hv_call_map_stats_page() for cases when the caller provides 825 * the map location. 826 * 827 * NOTE: This is a newer hypercall that always supports SELF and PARENT stats 828 * areas, unlike hv_call_map_stats_page(). 829 */ 830 static int hv_call_map_stats_page2(enum hv_stats_object_type type, 831 const union hv_stats_object_identity *identity, 832 u64 map_location) 833 { 834 unsigned long flags; 835 struct hv_input_map_stats_page2 *input; 836 u64 status; 837 int ret; 838 839 if (!map_location || !mshv_use_overlay_gpfn()) 840 return -EINVAL; 841 842 do { 843 local_irq_save(flags); 844 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 845 846 memset(input, 0, sizeof(*input)); 847 input->type = type; 848 input->identity = *identity; 849 input->map_location = map_location; 850 851 status = hv_do_hypercall(HVCALL_MAP_STATS_PAGE2, input, NULL); 852 853 local_irq_restore(flags); 854 855 ret = hv_result_to_errno(status); 856 857 if (!ret) 858 break; 859 860 if (!hv_result_needs_memory(status)) { 861 hv_status_debug(status, "\n"); 862 break; 863 } 864 865 ret = hv_deposit_memory(hv_current_partition_id, status); 866 } while (!ret); 867 868 return ret; 869 } 870 871 static int 872 hv_stats_get_area_type(enum hv_stats_object_type type, 873 const union hv_stats_object_identity *identity) 874 { 875 switch (type) { 876 case HV_STATS_OBJECT_HYPERVISOR: 877 return identity->hv.stats_area_type; 878 case HV_STATS_OBJECT_LOGICAL_PROCESSOR: 879 return identity->lp.stats_area_type; 880 case HV_STATS_OBJECT_PARTITION: 881 return identity->partition.stats_area_type; 882 case HV_STATS_OBJECT_VP: 883 return identity->vp.stats_area_type; 884 } 885 886 return -EINVAL; 887 } 888 889 /* 890 * Map a stats page, where the page location is provided by the hypervisor. 891 * 892 * NOTE: The concept of separate SELF and PARENT stats areas does not exist on 893 * older hypervisor versions. All the available stats information can be found 894 * on the SELF page. When attempting to map the PARENT area on a hypervisor 895 * that doesn't support it, return "success" but with a NULL address. The 896 * caller should check for this case and instead fallback to the SELF area 897 * alone. 898 */ 899 static int 900 hv_call_map_stats_page(enum hv_stats_object_type type, 901 const union hv_stats_object_identity *identity, 902 struct hv_stats_page **addr) 903 { 904 unsigned long flags; 905 struct hv_input_map_stats_page *input; 906 struct hv_output_map_stats_page *output; 907 u64 status, pfn; 908 int ret = 0; 909 910 do { 911 local_irq_save(flags); 912 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 913 output = *this_cpu_ptr(hyperv_pcpu_output_arg); 914 915 memset(input, 0, sizeof(*input)); 916 input->type = type; 917 input->identity = *identity; 918 919 status = hv_do_hypercall(HVCALL_MAP_STATS_PAGE, input, output); 920 pfn = output->map_location; 921 922 local_irq_restore(flags); 923 924 if (!hv_result_needs_memory(status)) { 925 if (hv_result_success(status)) 926 break; 927 928 if (hv_stats_get_area_type(type, identity) == HV_STATS_AREA_PARENT && 929 hv_result(status) == HV_STATUS_INVALID_PARAMETER) { 930 *addr = NULL; 931 return 0; 932 } 933 934 hv_status_debug(status, "\n"); 935 return hv_result_to_errno(status); 936 } 937 938 ret = hv_deposit_memory(hv_current_partition_id, status); 939 if (ret) 940 return ret; 941 } while (!ret); 942 943 *addr = page_address(pfn_to_page(pfn)); 944 945 return ret; 946 } 947 948 int hv_map_stats_page(enum hv_stats_object_type type, 949 const union hv_stats_object_identity *identity, 950 struct hv_stats_page **addr) 951 { 952 int ret; 953 struct page *allocated_page = NULL; 954 955 if (!addr) 956 return -EINVAL; 957 958 if (mshv_use_overlay_gpfn()) { 959 allocated_page = alloc_page(GFP_KERNEL); 960 if (!allocated_page) 961 return -ENOMEM; 962 963 ret = hv_call_map_stats_page2(type, identity, 964 page_to_pfn(allocated_page)); 965 *addr = page_address(allocated_page); 966 } else { 967 ret = hv_call_map_stats_page(type, identity, addr); 968 } 969 970 if (ret && allocated_page) { 971 __free_page(allocated_page); 972 *addr = NULL; 973 } 974 975 return ret; 976 } 977 978 static int hv_call_unmap_stats_page(enum hv_stats_object_type type, 979 const union hv_stats_object_identity *identity) 980 { 981 unsigned long flags; 982 struct hv_input_unmap_stats_page *input; 983 u64 status; 984 985 local_irq_save(flags); 986 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 987 988 memset(input, 0, sizeof(*input)); 989 input->type = type; 990 input->identity = *identity; 991 992 status = hv_do_hypercall(HVCALL_UNMAP_STATS_PAGE, input, NULL); 993 local_irq_restore(flags); 994 995 return hv_result_to_errno(status); 996 } 997 998 int hv_unmap_stats_page(enum hv_stats_object_type type, 999 struct hv_stats_page *page_addr, 1000 const union hv_stats_object_identity *identity) 1001 { 1002 int ret; 1003 1004 ret = hv_call_unmap_stats_page(type, identity); 1005 1006 if (mshv_use_overlay_gpfn() && page_addr) 1007 __free_page(virt_to_page(page_addr)); 1008 1009 return ret; 1010 } 1011 1012 int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages, 1013 u64 page_struct_count, u32 host_access, 1014 u32 flags, u8 acquire) 1015 { 1016 struct hv_input_modify_sparse_spa_page_host_access *input_page; 1017 u64 status; 1018 int done = 0; 1019 unsigned long irq_flags, large_shift = 0; 1020 u64 page_count = page_struct_count; 1021 u16 code = acquire ? HVCALL_ACQUIRE_SPARSE_SPA_PAGE_HOST_ACCESS : 1022 HVCALL_RELEASE_SPARSE_SPA_PAGE_HOST_ACCESS; 1023 1024 if (page_count == 0) 1025 return -EINVAL; 1026 1027 if (flags & HV_MODIFY_SPA_PAGE_HOST_ACCESS_LARGE_PAGE) { 1028 if (!HV_PAGE_COUNT_2M_ALIGNED(page_count)) 1029 return -EINVAL; 1030 large_shift = HV_HYP_LARGE_PAGE_SHIFT - HV_HYP_PAGE_SHIFT; 1031 page_count >>= large_shift; 1032 } 1033 1034 while (done < page_count) { 1035 ulong i, completed, remain = page_count - done; 1036 int rep_count = min(remain, 1037 HV_MODIFY_SPARSE_SPA_PAGE_HOST_ACCESS_MAX_PAGE_COUNT); 1038 1039 local_irq_save(irq_flags); 1040 input_page = *this_cpu_ptr(hyperv_pcpu_input_arg); 1041 1042 memset(input_page, 0, sizeof(*input_page)); 1043 /* Only set the partition id if you are making the pages 1044 * exclusive 1045 */ 1046 if (flags & HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_EXCLUSIVE) 1047 input_page->partition_id = partition_id; 1048 input_page->flags = flags; 1049 input_page->host_access = host_access; 1050 1051 for (i = 0; i < rep_count; i++) { 1052 u64 index = (done + i) << large_shift; 1053 1054 if (index >= page_struct_count) 1055 return -EINVAL; 1056 1057 input_page->spa_page_list[i] = 1058 page_to_pfn(pages[index]); 1059 } 1060 1061 status = hv_do_rep_hypercall(code, rep_count, 0, input_page, 1062 NULL); 1063 local_irq_restore(irq_flags); 1064 1065 completed = hv_repcomp(status); 1066 1067 if (!hv_result_success(status)) 1068 return hv_result_to_errno(status); 1069 1070 done += completed; 1071 } 1072 1073 return 0; 1074 } 1075