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

Merge tag 'hyperv-next-signed-20251006' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

Pull hyperv updates from Wei Liu:

- Unify guest entry code for KVM and MSHV (Sean Christopherson)

- Switch Hyper-V MSI domain to use msi_create_parent_irq_domain()
(Nam Cao)

- Add CONFIG_HYPERV_VMBUS and limit the semantics of CONFIG_HYPERV
(Mukesh Rathor)

- Add kexec/kdump support on Azure CVMs (Vitaly Kuznetsov)

- Deprecate hyperv_fb in favor of Hyper-V DRM driver (Prasanna
Kumar T S M)

- Miscellaneous enhancements, fixes and cleanups (Abhishek Tiwari,
Alok Tiwari, Nuno Das Neves, Wei Liu, Roman Kisel, Michael Kelley)

* tag 'hyperv-next-signed-20251006' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
hyperv: Remove the spurious null directive line
MAINTAINERS: Mark hyperv_fb driver Obsolete
fbdev/hyperv_fb: deprecate this in favor of Hyper-V DRM driver
Drivers: hv: Make CONFIG_HYPERV bool
Drivers: hv: Add CONFIG_HYPERV_VMBUS option
Drivers: hv: vmbus: Fix typos in vmbus_drv.c
Drivers: hv: vmbus: Fix sysfs output format for ring buffer index
Drivers: hv: vmbus: Clean up sscanf format specifier in target_cpu_store()
x86/hyperv: Switch to msi_create_parent_irq_domain()
mshv: Use common "entry virt" APIs to do work in root before running guest
entry: Rename "kvm" entry code assets to "virt" to genericize APIs
entry/kvm: KVM: Move KVM details related to signal/-EINTR into KVM proper
mshv: Handle NEED_RESCHED_LAZY before transferring to guest
x86/hyperv: Add kexec/kdump support on Azure CVMs
Drivers: hv: Simplify data structures for VMBus channel close message
Drivers: hv: util: Cosmetic changes for hv_utils_transport.c
mshv: Add support for a new parent partition configuration
clocksource: hyper-v: Skip unnecessary checks for the root partition
hyperv: Add missing field to hv_output_map_device_interrupt

+449 -193
+11 -2
MAINTAINERS
··· 10390 10390 S: Maintained 10391 10391 T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core/entry 10392 10392 F: include/linux/entry-common.h 10393 - F: include/linux/entry-kvm.h 10393 + F: include/linux/entry-virt.h 10394 10394 F: include/linux/irq-entry-common.h 10395 10395 F: kernel/entry/ 10396 10396 ··· 11604 11604 F: drivers/pci/controller/pci-hyperv.c 11605 11605 F: drivers/scsi/storvsc_drv.c 11606 11606 F: drivers/uio/uio_hv_generic.c 11607 - F: drivers/video/fbdev/hyperv_fb.c 11608 11607 F: include/asm-generic/mshyperv.h 11609 11608 F: include/clocksource/hyperv_timer.h 11610 11609 F: include/hyperv/hvgdk.h ··· 11616 11617 F: include/uapi/linux/hyperv.h 11617 11618 F: net/vmw_vsock/hyperv_transport.c 11618 11619 F: tools/hv/ 11620 + 11621 + HYPER-V FRAMEBUFFER DRIVER 11622 + M: "K. Y. Srinivasan" <kys@microsoft.com> 11623 + M: Haiyang Zhang <haiyangz@microsoft.com> 11624 + M: Wei Liu <wei.liu@kernel.org> 11625 + M: Dexuan Cui <decui@microsoft.com> 11626 + L: linux-hyperv@vger.kernel.org 11627 + S: Obsolete 11628 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git 11629 + F: drivers/video/fbdev/hyperv_fb.c 11619 11630 11620 11631 HYPERBUS SUPPORT 11621 11632 M: Vignesh Raghavendra <vigneshr@ti.com>
+1 -1
arch/arm64/kvm/Kconfig
··· 25 25 select HAVE_KVM_CPU_RELAX_INTERCEPT 26 26 select KVM_MMIO 27 27 select KVM_GENERIC_DIRTYLOG_READ_PROTECT 28 - select KVM_XFER_TO_GUEST_WORK 28 + select VIRT_XFER_TO_GUEST_WORK 29 29 select KVM_VFIO 30 30 select HAVE_KVM_DIRTY_RING_ACQ_REL 31 31 select NEED_KVM_DIRTY_RING_WITH_BITMAP
+1 -2
arch/arm64/kvm/arm.c
··· 6 6 7 7 #include <linux/bug.h> 8 8 #include <linux/cpu_pm.h> 9 - #include <linux/entry-kvm.h> 10 9 #include <linux/errno.h> 11 10 #include <linux/err.h> 12 11 #include <linux/kvm_host.h> ··· 1182 1183 /* 1183 1184 * Check conditions before entering the guest 1184 1185 */ 1185 - ret = xfer_to_guest_mode_handle_work(vcpu); 1186 + ret = kvm_xfer_to_guest_mode_handle_work(vcpu); 1186 1187 if (!ret) 1187 1188 ret = 1; 1188 1189
+1 -1
arch/loongarch/kvm/Kconfig
··· 31 31 select KVM_GENERIC_HARDWARE_ENABLING 32 32 select KVM_GENERIC_MMU_NOTIFIER 33 33 select KVM_MMIO 34 - select KVM_XFER_TO_GUEST_WORK 34 + select VIRT_XFER_TO_GUEST_WORK 35 35 select SCHED_INFO 36 36 select GUEST_PERF_EVENTS if PERF_EVENTS 37 37 help
+1 -2
arch/loongarch/kvm/vcpu.c
··· 4 4 */ 5 5 6 6 #include <linux/kvm_host.h> 7 - #include <linux/entry-kvm.h> 8 7 #include <asm/fpu.h> 9 8 #include <asm/lbt.h> 10 9 #include <asm/loongarch.h> ··· 250 251 /* 251 252 * Check conditions before entering the guest 252 253 */ 253 - ret = xfer_to_guest_mode_handle_work(vcpu); 254 + ret = kvm_xfer_to_guest_mode_handle_work(vcpu); 254 255 if (ret < 0) 255 256 return ret; 256 257
+1 -1
arch/riscv/kvm/Kconfig
··· 30 30 select KVM_GENERIC_DIRTYLOG_READ_PROTECT 31 31 select KVM_GENERIC_HARDWARE_ENABLING 32 32 select KVM_MMIO 33 - select KVM_XFER_TO_GUEST_WORK 33 + select VIRT_XFER_TO_GUEST_WORK 34 34 select KVM_GENERIC_MMU_NOTIFIER 35 35 select SCHED_INFO 36 36 select GUEST_PERF_EVENTS if PERF_EVENTS
+1 -2
arch/riscv/kvm/vcpu.c
··· 7 7 */ 8 8 9 9 #include <linux/bitops.h> 10 - #include <linux/entry-kvm.h> 11 10 #include <linux/errno.h> 12 11 #include <linux/err.h> 13 12 #include <linux/kdebug.h> ··· 910 911 run->exit_reason = KVM_EXIT_UNKNOWN; 911 912 while (ret > 0) { 912 913 /* Check conditions before entering the guest */ 913 - ret = xfer_to_guest_mode_handle_work(vcpu); 914 + ret = kvm_xfer_to_guest_mode_handle_work(vcpu); 914 915 if (ret) 915 916 continue; 916 917 ret = 1;
+76 -35
arch/x86/hyperv/irqdomain.c
··· 11 11 #include <linux/pci.h> 12 12 #include <linux/irq.h> 13 13 #include <linux/export.h> 14 + #include <linux/irqchip/irq-msi-lib.h> 14 15 #include <asm/mshyperv.h> 15 16 16 17 static int hv_map_interrupt(union hv_device_id device_id, bool level, ··· 290 289 (void)hv_unmap_msi_interrupt(dev, &old_entry); 291 290 } 292 291 293 - static void hv_msi_free_irq(struct irq_domain *domain, 294 - struct msi_domain_info *info, unsigned int virq) 295 - { 296 - struct irq_data *irqd = irq_get_irq_data(virq); 297 - struct msi_desc *desc; 298 - 299 - if (!irqd) 300 - return; 301 - 302 - desc = irq_data_get_msi_desc(irqd); 303 - if (!desc || !desc->irq || WARN_ON_ONCE(!dev_is_pci(desc->dev))) 304 - return; 305 - 306 - hv_teardown_msi_irq(to_pci_dev(desc->dev), irqd); 307 - } 308 - 309 292 /* 310 293 * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, 311 294 * which implement the MSI or MSI-X Capability Structure. 312 295 */ 313 296 static struct irq_chip hv_pci_msi_controller = { 314 297 .name = "HV-PCI-MSI", 315 - .irq_unmask = pci_msi_unmask_irq, 316 - .irq_mask = pci_msi_mask_irq, 317 298 .irq_ack = irq_chip_ack_parent, 318 - .irq_retrigger = irq_chip_retrigger_hierarchy, 319 299 .irq_compose_msi_msg = hv_irq_compose_msi_msg, 320 - .irq_set_affinity = msi_domain_set_affinity, 321 - .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED, 300 + .irq_set_affinity = irq_chip_set_affinity_parent, 322 301 }; 323 302 324 - static struct msi_domain_ops pci_msi_domain_ops = { 325 - .msi_free = hv_msi_free_irq, 326 - .msi_prepare = pci_msi_prepare, 303 + static bool hv_init_dev_msi_info(struct device *dev, struct irq_domain *domain, 304 + struct irq_domain *real_parent, struct msi_domain_info *info) 305 + { 306 + struct irq_chip *chip = info->chip; 307 + 308 + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info)) 309 + return false; 310 + 311 + chip->flags |= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED; 312 + 313 + info->ops->msi_prepare = pci_msi_prepare; 314 + 315 + return true; 316 + } 317 + 318 + #define HV_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | MSI_FLAG_PCI_MSIX) 319 + #define HV_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS) 320 + 321 + static struct msi_parent_ops hv_msi_parent_ops = { 322 + .supported_flags = HV_MSI_FLAGS_SUPPORTED, 323 + .required_flags = HV_MSI_FLAGS_REQUIRED, 324 + .bus_select_token = DOMAIN_BUS_NEXUS, 325 + .bus_select_mask = MATCH_PCI_MSI, 326 + .chip_flags = MSI_CHIP_FLAG_SET_ACK, 327 + .prefix = "HV-", 328 + .init_dev_msi_info = hv_init_dev_msi_info, 327 329 }; 328 330 329 - static struct msi_domain_info hv_pci_msi_domain_info = { 330 - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 331 - MSI_FLAG_PCI_MSIX, 332 - .ops = &pci_msi_domain_ops, 333 - .chip = &hv_pci_msi_controller, 334 - .handler = handle_edge_irq, 335 - .handler_name = "edge", 331 + static int hv_msi_domain_alloc(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs, 332 + void *arg) 333 + { 334 + /* 335 + * TODO: The allocation bits of hv_irq_compose_msi_msg(), i.e. everything except 336 + * entry_to_msi_msg() should be in here. 337 + */ 338 + 339 + int ret; 340 + 341 + ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, arg); 342 + if (ret) 343 + return ret; 344 + 345 + for (int i = 0; i < nr_irqs; ++i) { 346 + irq_domain_set_info(d, virq + i, 0, &hv_pci_msi_controller, NULL, 347 + handle_edge_irq, NULL, "edge"); 348 + } 349 + return 0; 350 + } 351 + 352 + static void hv_msi_domain_free(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs) 353 + { 354 + for (int i = 0; i < nr_irqs; ++i) { 355 + struct irq_data *irqd = irq_domain_get_irq_data(d, virq); 356 + struct msi_desc *desc; 357 + 358 + desc = irq_data_get_msi_desc(irqd); 359 + if (!desc || !desc->irq || WARN_ON_ONCE(!dev_is_pci(desc->dev))) 360 + continue; 361 + 362 + hv_teardown_msi_irq(to_pci_dev(desc->dev), irqd); 363 + } 364 + irq_domain_free_irqs_top(d, virq, nr_irqs); 365 + } 366 + 367 + static const struct irq_domain_ops hv_msi_domain_ops = { 368 + .select = msi_lib_irq_domain_select, 369 + .alloc = hv_msi_domain_alloc, 370 + .free = hv_msi_domain_free, 336 371 }; 337 372 338 373 struct irq_domain * __init hv_create_pci_msi_domain(void) 339 374 { 340 375 struct irq_domain *d = NULL; 341 - struct fwnode_handle *fn; 342 376 343 - fn = irq_domain_alloc_named_fwnode("HV-PCI-MSI"); 344 - if (fn) 345 - d = pci_msi_create_irq_domain(fn, &hv_pci_msi_domain_info, x86_vector_domain); 377 + struct irq_domain_info info = { 378 + .fwnode = irq_domain_alloc_named_fwnode("HV-PCI-MSI"), 379 + .ops = &hv_msi_domain_ops, 380 + .parent = x86_vector_domain, 381 + }; 382 + 383 + if (info.fwnode) 384 + d = msi_create_parent_irq_domain(&info, &hv_msi_parent_ops); 346 385 347 386 /* No point in going further if we can't get an irq domain */ 348 387 BUG_ON(!d);
+210 -1
arch/x86/hyperv/ivm.c
··· 463 463 } 464 464 465 465 /* 466 + * Keep track of the PFN regions which were shared with the host. The access 467 + * must be revoked upon kexec/kdump (see hv_ivm_clear_host_access()). 468 + */ 469 + struct hv_enc_pfn_region { 470 + struct list_head list; 471 + u64 pfn; 472 + int count; 473 + }; 474 + 475 + static LIST_HEAD(hv_list_enc); 476 + static DEFINE_RAW_SPINLOCK(hv_list_enc_lock); 477 + 478 + static int hv_list_enc_add(const u64 *pfn_list, int count) 479 + { 480 + struct hv_enc_pfn_region *ent; 481 + unsigned long flags; 482 + u64 pfn; 483 + int i; 484 + 485 + for (i = 0; i < count; i++) { 486 + pfn = pfn_list[i]; 487 + 488 + raw_spin_lock_irqsave(&hv_list_enc_lock, flags); 489 + /* Check if the PFN already exists in some region first */ 490 + list_for_each_entry(ent, &hv_list_enc, list) { 491 + if ((ent->pfn <= pfn) && (ent->pfn + ent->count - 1 >= pfn)) 492 + /* Nothing to do - pfn is already in the list */ 493 + goto unlock_done; 494 + } 495 + 496 + /* 497 + * Check if the PFN is adjacent to an existing region. Growing 498 + * a region can make it adjacent to another one but merging is 499 + * not (yet) implemented for simplicity. A PFN cannot be added 500 + * to two regions to keep the logic in hv_list_enc_remove() 501 + * correct. 502 + */ 503 + list_for_each_entry(ent, &hv_list_enc, list) { 504 + if (ent->pfn + ent->count == pfn) { 505 + /* Grow existing region up */ 506 + ent->count++; 507 + goto unlock_done; 508 + } else if (pfn + 1 == ent->pfn) { 509 + /* Grow existing region down */ 510 + ent->pfn--; 511 + ent->count++; 512 + goto unlock_done; 513 + } 514 + } 515 + raw_spin_unlock_irqrestore(&hv_list_enc_lock, flags); 516 + 517 + /* No adjacent region found -- create a new one */ 518 + ent = kzalloc(sizeof(struct hv_enc_pfn_region), GFP_KERNEL); 519 + if (!ent) 520 + return -ENOMEM; 521 + 522 + ent->pfn = pfn; 523 + ent->count = 1; 524 + 525 + raw_spin_lock_irqsave(&hv_list_enc_lock, flags); 526 + list_add(&ent->list, &hv_list_enc); 527 + 528 + unlock_done: 529 + raw_spin_unlock_irqrestore(&hv_list_enc_lock, flags); 530 + } 531 + 532 + return 0; 533 + } 534 + 535 + static int hv_list_enc_remove(const u64 *pfn_list, int count) 536 + { 537 + struct hv_enc_pfn_region *ent, *t; 538 + struct hv_enc_pfn_region new_region; 539 + unsigned long flags; 540 + u64 pfn; 541 + int i; 542 + 543 + for (i = 0; i < count; i++) { 544 + pfn = pfn_list[i]; 545 + 546 + raw_spin_lock_irqsave(&hv_list_enc_lock, flags); 547 + list_for_each_entry_safe(ent, t, &hv_list_enc, list) { 548 + if (pfn == ent->pfn + ent->count - 1) { 549 + /* Removing tail pfn */ 550 + ent->count--; 551 + if (!ent->count) { 552 + list_del(&ent->list); 553 + kfree(ent); 554 + } 555 + goto unlock_done; 556 + } else if (pfn == ent->pfn) { 557 + /* Removing head pfn */ 558 + ent->count--; 559 + ent->pfn++; 560 + if (!ent->count) { 561 + list_del(&ent->list); 562 + kfree(ent); 563 + } 564 + goto unlock_done; 565 + } else if (pfn > ent->pfn && pfn < ent->pfn + ent->count - 1) { 566 + /* 567 + * Removing a pfn in the middle. Cut off the tail 568 + * of the existing region and create a template for 569 + * the new one. 570 + */ 571 + new_region.pfn = pfn + 1; 572 + new_region.count = ent->count - (pfn - ent->pfn + 1); 573 + ent->count = pfn - ent->pfn; 574 + goto unlock_split; 575 + } 576 + 577 + } 578 + unlock_done: 579 + raw_spin_unlock_irqrestore(&hv_list_enc_lock, flags); 580 + continue; 581 + 582 + unlock_split: 583 + raw_spin_unlock_irqrestore(&hv_list_enc_lock, flags); 584 + 585 + ent = kzalloc(sizeof(struct hv_enc_pfn_region), GFP_KERNEL); 586 + if (!ent) 587 + return -ENOMEM; 588 + 589 + ent->pfn = new_region.pfn; 590 + ent->count = new_region.count; 591 + 592 + raw_spin_lock_irqsave(&hv_list_enc_lock, flags); 593 + list_add(&ent->list, &hv_list_enc); 594 + raw_spin_unlock_irqrestore(&hv_list_enc_lock, flags); 595 + } 596 + 597 + return 0; 598 + } 599 + 600 + /* Stop new private<->shared conversions */ 601 + static void hv_vtom_kexec_begin(void) 602 + { 603 + if (!IS_ENABLED(CONFIG_KEXEC_CORE)) 604 + return; 605 + 606 + /* 607 + * Crash kernel reaches here with interrupts disabled: can't wait for 608 + * conversions to finish. 609 + * 610 + * If race happened, just report and proceed. 611 + */ 612 + if (!set_memory_enc_stop_conversion()) 613 + pr_warn("Failed to stop shared<->private conversions\n"); 614 + } 615 + 616 + static void hv_vtom_kexec_finish(void) 617 + { 618 + struct hv_gpa_range_for_visibility *input; 619 + struct hv_enc_pfn_region *ent; 620 + unsigned long flags; 621 + u64 hv_status; 622 + int cur, i; 623 + 624 + local_irq_save(flags); 625 + input = *this_cpu_ptr(hyperv_pcpu_input_arg); 626 + 627 + if (unlikely(!input)) 628 + goto out; 629 + 630 + list_for_each_entry(ent, &hv_list_enc, list) { 631 + for (i = 0, cur = 0; i < ent->count; i++) { 632 + input->gpa_page_list[cur] = ent->pfn + i; 633 + cur++; 634 + 635 + if (cur == HV_MAX_MODIFY_GPA_REP_COUNT || i == ent->count - 1) { 636 + input->partition_id = HV_PARTITION_ID_SELF; 637 + input->host_visibility = VMBUS_PAGE_NOT_VISIBLE; 638 + input->reserved0 = 0; 639 + input->reserved1 = 0; 640 + hv_status = hv_do_rep_hypercall( 641 + HVCALL_MODIFY_SPARSE_GPA_PAGE_HOST_VISIBILITY, 642 + cur, 0, input, NULL); 643 + WARN_ON_ONCE(!hv_result_success(hv_status)); 644 + cur = 0; 645 + } 646 + } 647 + 648 + } 649 + 650 + out: 651 + local_irq_restore(flags); 652 + } 653 + 654 + /* 466 655 * hv_mark_gpa_visibility - Set pages visible to host via hvcall. 467 656 * 468 657 * In Isolation VM, all guest memory is encrypted from host and guest ··· 664 475 struct hv_gpa_range_for_visibility *input; 665 476 u64 hv_status; 666 477 unsigned long flags; 478 + int ret; 667 479 668 480 /* no-op if partition isolation is not enabled */ 669 481 if (!hv_is_isolation_supported()) ··· 675 485 HV_MAX_MODIFY_GPA_REP_COUNT); 676 486 return -EINVAL; 677 487 } 488 + 489 + if (visibility == VMBUS_PAGE_NOT_VISIBLE) 490 + ret = hv_list_enc_remove(pfn, count); 491 + else 492 + ret = hv_list_enc_add(pfn, count); 493 + if (ret) 494 + return ret; 678 495 679 496 local_irq_save(flags); 680 497 input = *this_cpu_ptr(hyperv_pcpu_input_arg); ··· 703 506 704 507 if (hv_result_success(hv_status)) 705 508 return 0; 509 + 510 + if (visibility == VMBUS_PAGE_NOT_VISIBLE) 511 + ret = hv_list_enc_add(pfn, count); 706 512 else 707 - return -EFAULT; 513 + ret = hv_list_enc_remove(pfn, count); 514 + /* 515 + * There's no good way to recover from -ENOMEM here, the accounting is 516 + * wrong either way. 517 + */ 518 + WARN_ON_ONCE(ret); 519 + 520 + return -EFAULT; 708 521 } 709 522 710 523 /* ··· 876 669 x86_platform.guest.enc_tlb_flush_required = hv_vtom_tlb_flush_required; 877 670 x86_platform.guest.enc_status_change_prepare = hv_vtom_clear_present; 878 671 x86_platform.guest.enc_status_change_finish = hv_vtom_set_host_visibility; 672 + x86_platform.guest.enc_kexec_begin = hv_vtom_kexec_begin; 673 + x86_platform.guest.enc_kexec_finish = hv_vtom_kexec_finish; 879 674 880 675 /* Set WB as the default cache mode. */ 881 676 guest_force_mtrr_state(NULL, 0, MTRR_TYPE_WRBACK);
+10 -1
arch/x86/kernel/cpu/mshyperv.c
··· 565 565 machine_ops.crash_shutdown = hv_machine_crash_shutdown; 566 566 #endif 567 567 #endif 568 + /* 569 + * HV_ACCESS_TSC_INVARIANT is always zero for the root partition. Root 570 + * partition doesn't need to write to synthetic MSR to enable invariant 571 + * TSC feature. It sees what the hardware provides. 572 + */ 568 573 if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { 569 574 /* 570 575 * Writing to synthetic MSR 0x40000118 updates/changes the ··· 641 636 * TSC should be marked as unstable only after Hyper-V 642 637 * clocksource has been initialized. This ensures that the 643 638 * stability of the sched_clock is not altered. 639 + * 640 + * HV_ACCESS_TSC_INVARIANT is always zero for the root partition. No 641 + * need to check for it. 644 642 */ 645 - if (!(ms_hyperv.features & HV_ACCESS_TSC_INVARIANT)) 643 + if (!hv_root_partition() && 644 + !(ms_hyperv.features & HV_ACCESS_TSC_INVARIANT)) 646 645 mark_tsc_unstable("running on Hyper-V"); 647 646 648 647 hardlockup_detector_disable();
+1 -1
arch/x86/kvm/Kconfig
··· 40 40 select HAVE_KVM_MSI 41 41 select HAVE_KVM_CPU_RELAX_INTERCEPT 42 42 select HAVE_KVM_NO_POLL 43 - select KVM_XFER_TO_GUEST_WORK 43 + select VIRT_XFER_TO_GUEST_WORK 44 44 select KVM_GENERIC_DIRTYLOG_READ_PROTECT 45 45 select KVM_VFIO 46 46 select HAVE_KVM_PM_NOTIFIER if PM
-1
arch/x86/kvm/vmx/vmx.c
··· 28 28 #include <linux/slab.h> 29 29 #include <linux/tboot.h> 30 30 #include <linux/trace_events.h> 31 - #include <linux/entry-kvm.h> 32 31 33 32 #include <asm/apic.h> 34 33 #include <asm/asm.h>
+1 -2
arch/x86/kvm/x86.c
··· 59 59 #include <linux/sched/stat.h> 60 60 #include <linux/sched/isolation.h> 61 61 #include <linux/mem_encrypt.h> 62 - #include <linux/entry-kvm.h> 63 62 #include <linux/suspend.h> 64 63 #include <linux/smp.h> 65 64 ··· 11634 11635 11635 11636 if (__xfer_to_guest_mode_work_pending()) { 11636 11637 kvm_vcpu_srcu_read_unlock(vcpu); 11637 - r = xfer_to_guest_mode_handle_work(vcpu); 11638 + r = kvm_xfer_to_guest_mode_handle_work(vcpu); 11638 11639 kvm_vcpu_srcu_read_lock(vcpu); 11639 11640 if (r) 11640 11641 return r;
+1 -1
drivers/Makefile
··· 161 161 162 162 # Virtualization drivers 163 163 obj-$(CONFIG_VIRT_DRIVERS) += virt/ 164 - obj-$(subst m,y,$(CONFIG_HYPERV)) += hv/ 164 + obj-$(CONFIG_HYPERV) += hv/ 165 165 166 166 obj-$(CONFIG_PM_DEVFREQ) += devfreq/ 167 167 obj-$(CONFIG_EXTCON) += extcon/
+9 -1
drivers/clocksource/hyperv_timer.c
··· 549 549 union hv_reference_tsc_msr tsc_msr; 550 550 551 551 /* 552 + * When running as a guest partition: 553 + * 552 554 * If Hyper-V offers TSC_INVARIANT, then the virtualized TSC correctly 553 555 * handles frequency and offset changes due to live migration, 554 556 * pause/resume, and other VM management operations. So lower the 555 557 * Hyper-V Reference TSC rating, causing the generic TSC to be used. 556 558 * TSC_INVARIANT is not offered on ARM64, so the Hyper-V Reference 557 559 * TSC will be preferred over the virtualized ARM64 arch counter. 560 + * 561 + * When running as the root partition: 562 + * 563 + * There is no HV_ACCESS_TSC_INVARIANT feature. Always lower the rating 564 + * of the Hyper-V Reference TSC. 558 565 */ 559 - if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { 566 + if ((ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) || 567 + hv_root_partition()) { 560 568 hyperv_cs_tsc.rating = 250; 561 569 hyperv_cs_msr.rating = 245; 562 570 }
+1 -1
drivers/gpu/drm/Kconfig
··· 400 400 401 401 config DRM_HYPERV 402 402 tristate "DRM Support for Hyper-V synthetic video device" 403 - depends on DRM && PCI && HYPERV 403 + depends on DRM && PCI && HYPERV_VMBUS 404 404 select DRM_CLIENT_SELECTION 405 405 select DRM_KMS_HELPER 406 406 select DRM_GEM_SHMEM_HELPER
+1 -1
drivers/hid/Kconfig
··· 1171 1171 1172 1172 config HID_HYPERV_MOUSE 1173 1173 tristate "Microsoft Hyper-V mouse driver" 1174 - depends on HYPERV 1174 + depends on HYPERV_VMBUS 1175 1175 help 1176 1176 Select this option to enable the Hyper-V mouse driver. 1177 1177
+12 -3
drivers/hv/Kconfig
··· 3 3 menu "Microsoft Hyper-V guest support" 4 4 5 5 config HYPERV 6 - tristate "Microsoft Hyper-V client drivers" 6 + bool "Microsoft Hyper-V core hypervisor support" 7 7 depends on (X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \ 8 8 || (ARM64 && !CPU_BIG_ENDIAN) 9 9 select PARAVIRT 10 10 select X86_HV_CALLBACK_VECTOR if X86 11 11 select OF_EARLY_FLATTREE if OF 12 12 select SYSFB if EFI && !HYPERV_VTL_MODE 13 + select IRQ_MSI_LIB if X86 13 14 help 14 15 Select this option to run Linux as a Hyper-V client operating 15 16 system. ··· 45 44 46 45 config HYPERV_UTILS 47 46 tristate "Microsoft Hyper-V Utilities driver" 48 - depends on HYPERV && CONNECTOR && NLS 47 + depends on HYPERV_VMBUS && CONNECTOR && NLS 49 48 depends on PTP_1588_CLOCK_OPTIONAL 50 49 help 51 50 Select this option to enable the Hyper-V Utilities. 52 51 53 52 config HYPERV_BALLOON 54 53 tristate "Microsoft Hyper-V Balloon driver" 55 - depends on HYPERV 54 + depends on HYPERV_VMBUS 56 55 select PAGE_REPORTING 57 56 help 58 57 Select this option to enable Hyper-V Balloon driver. 58 + 59 + config HYPERV_VMBUS 60 + tristate "Microsoft Hyper-V VMBus driver" 61 + depends on HYPERV 62 + default HYPERV 63 + help 64 + Select this option to enable Hyper-V Vmbus driver. 59 65 60 66 config MSHV_ROOT 61 67 tristate "Microsoft Hyper-V root partition support" ··· 74 66 # no particular order, making it impossible to reassemble larger pages 75 67 depends on PAGE_SIZE_4KB 76 68 select EVENTFD 69 + select VIRT_XFER_TO_GUEST_WORK 77 70 default n 78 71 help 79 72 Select this option to enable support for booting and running as root
+2 -2
drivers/hv/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 - obj-$(CONFIG_HYPERV) += hv_vmbus.o 2 + obj-$(CONFIG_HYPERV_VMBUS) += hv_vmbus.o 3 3 obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o 4 4 obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o 5 5 obj-$(CONFIG_MSHV_ROOT) += mshv_root.o ··· 16 16 mshv_root_hv_call.o mshv_portid_table.o 17 17 18 18 # Code that must be built-in 19 - obj-$(subst m,y,$(CONFIG_HYPERV)) += hv_common.o 19 + obj-$(CONFIG_HYPERV) += hv_common.o 20 20 obj-$(subst m,y,$(CONFIG_MSHV_ROOT)) += hv_proc.o mshv_common.o
+1 -1
drivers/hv/channel.c
··· 925 925 926 926 /* Send a closing message */ 927 927 928 - msg = &channel->close_msg.msg; 928 + msg = &channel->close_msg; 929 929 930 930 msg->header.msgtype = CHANNELMSG_CLOSECHANNEL; 931 931 msg->child_relid = channel->offermsg.child_relid;
+13 -9
drivers/hv/hv_common.c
··· 257 257 258 258 static inline bool hv_output_page_exists(void) 259 259 { 260 - return hv_root_partition() || IS_ENABLED(CONFIG_HYPERV_VTL_MODE); 260 + return hv_parent_partition() || IS_ENABLED(CONFIG_HYPERV_VTL_MODE); 261 261 } 262 262 263 263 void __init hv_get_partition_id(void) ··· 377 377 BUG_ON(!hyperv_pcpu_output_arg); 378 378 } 379 379 380 - if (hv_root_partition()) { 380 + if (hv_parent_partition()) { 381 381 hv_synic_eventring_tail = alloc_percpu(u8 *); 382 382 BUG_ON(!hv_synic_eventring_tail); 383 383 } ··· 531 531 if (msr_vp_index > hv_max_vp_index) 532 532 hv_max_vp_index = msr_vp_index; 533 533 534 - if (hv_root_partition()) { 534 + if (hv_parent_partition()) { 535 535 synic_eventring_tail = (u8 **)this_cpu_ptr(hv_synic_eventring_tail); 536 536 *synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT, 537 537 sizeof(u8), flags); ··· 558 558 * originally allocated memory is reused in hv_common_cpu_init(). 559 559 */ 560 560 561 - if (hv_root_partition()) { 561 + if (hv_parent_partition()) { 562 562 synic_eventring_tail = this_cpu_ptr(hv_synic_eventring_tail); 563 563 kfree(*synic_eventring_tail); 564 564 *synic_eventring_tail = NULL; ··· 729 729 * the root partition setting if also a Confidential VM. 730 730 */ 731 731 if ((ms_hyperv.priv_high & HV_CREATE_PARTITIONS) && 732 - (ms_hyperv.priv_high & HV_CPU_MANAGEMENT) && 733 732 !(ms_hyperv.priv_high & HV_ISOLATION)) { 734 - pr_info("Hyper-V: running as root partition\n"); 735 - if (IS_ENABLED(CONFIG_MSHV_ROOT)) 736 - hv_curr_partition_type = HV_PARTITION_TYPE_ROOT; 737 - else 733 + 734 + if (!IS_ENABLED(CONFIG_MSHV_ROOT)) { 738 735 pr_crit("Hyper-V: CONFIG_MSHV_ROOT not enabled!\n"); 736 + } else if (ms_hyperv.priv_high & HV_CPU_MANAGEMENT) { 737 + pr_info("Hyper-V: running as root partition\n"); 738 + hv_curr_partition_type = HV_PARTITION_TYPE_ROOT; 739 + } else { 740 + pr_info("Hyper-V: running as L1VH partition\n"); 741 + hv_curr_partition_type = HV_PARTITION_TYPE_L1VH; 742 + } 739 743 } 740 744 } 741 745
+5 -5
drivers/hv/hv_utils_transport.c
··· 129 129 * device gets released. 130 130 */ 131 131 hvt->mode = HVUTIL_TRANSPORT_CHARDEV; 132 - } 133 - else if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) { 132 + } else if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) { 134 133 /* 135 134 * We're switching from netlink communication to using char 136 135 * device. Issue the reset first. ··· 194 195 } 195 196 spin_unlock(&hvt_list_lock); 196 197 if (!hvt_found) { 197 - pr_warn("hvt_cn_callback: spurious message received!\n"); 198 + pr_warn("%s: spurious message received!\n", __func__); 198 199 return; 199 200 } 200 201 ··· 209 210 if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) 210 211 hvt_found->on_msg(msg->data, msg->len); 211 212 else 212 - pr_warn("hvt_cn_callback: unexpected netlink message!\n"); 213 + pr_warn("%s: unexpected netlink message!\n", __func__); 213 214 mutex_unlock(&hvt->lock); 214 215 } 215 216 ··· 259 260 hvt->outmsg_len = len; 260 261 hvt->on_read = on_read_cb; 261 262 wake_up_interruptible(&hvt->outmsg_q); 262 - } else 263 + } else { 263 264 ret = -ENOMEM; 265 + } 264 266 out_unlock: 265 267 mutex_unlock(&hvt->lock); 266 268 return ret;
-2
drivers/hv/mshv.h
··· 25 25 int hv_call_get_partition_property(u64 partition_id, u64 property_code, 26 26 u64 *property_value); 27 27 28 - int mshv_do_pre_guest_mode_work(ulong th_flags); 29 - 30 28 #endif /* _MSHV_H */
-22
drivers/hv/mshv_common.c
··· 138 138 return 0; 139 139 } 140 140 EXPORT_SYMBOL_GPL(hv_call_get_partition_property); 141 - 142 - /* 143 - * Handle any pre-processing before going into the guest mode on this cpu, most 144 - * notably call schedule(). Must be invoked with both preemption and 145 - * interrupts enabled. 146 - * 147 - * Returns: 0 on success, -errno on error. 148 - */ 149 - int mshv_do_pre_guest_mode_work(ulong th_flags) 150 - { 151 - if (th_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) 152 - return -EINTR; 153 - 154 - if (th_flags & _TIF_NEED_RESCHED) 155 - schedule(); 156 - 157 - if (th_flags & _TIF_NOTIFY_RESUME) 158 - resume_user_mode_work(NULL); 159 - 160 - return 0; 161 - } 162 - EXPORT_SYMBOL_GPL(mshv_do_pre_guest_mode_work);
+19 -38
drivers/hv/mshv_root_main.c
··· 8 8 * Authors: Microsoft Linux virtualization team 9 9 */ 10 10 11 + #include <linux/entry-virt.h> 11 12 #include <linux/kernel.h> 12 13 #include <linux/module.h> 13 14 #include <linux/fs.h> ··· 37 36 MODULE_AUTHOR("Microsoft"); 38 37 MODULE_LICENSE("GPL"); 39 38 MODULE_DESCRIPTION("Microsoft Hyper-V root partition VMM interface /dev/mshv"); 40 - 41 - /* TODO move this to mshyperv.h when needed outside driver */ 42 - static inline bool hv_parent_partition(void) 43 - { 44 - return hv_root_partition(); 45 - } 46 39 47 40 /* TODO move this to another file when debugfs code is added */ 48 41 enum hv_stats_vp_counters { /* HV_THREAD_COUNTER */ ··· 482 487 return 0; 483 488 } 484 489 485 - static int mshv_pre_guest_mode_work(struct mshv_vp *vp) 486 - { 487 - const ulong work_flags = _TIF_NOTIFY_SIGNAL | _TIF_SIGPENDING | 488 - _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME; 489 - ulong th_flags; 490 - 491 - th_flags = read_thread_flags(); 492 - while (th_flags & work_flags) { 493 - int ret; 494 - 495 - /* nb: following will call schedule */ 496 - ret = mshv_do_pre_guest_mode_work(th_flags); 497 - 498 - if (ret) 499 - return ret; 500 - 501 - th_flags = read_thread_flags(); 502 - } 503 - 504 - return 0; 505 - } 506 - 507 490 /* Must be called with interrupts enabled */ 508 491 static long mshv_run_vp_with_root_scheduler(struct mshv_vp *vp) 509 492 { ··· 502 529 u32 flags = 0; 503 530 struct hv_output_dispatch_vp output; 504 531 505 - ret = mshv_pre_guest_mode_work(vp); 506 - if (ret) 507 - break; 532 + if (__xfer_to_guest_mode_work_pending()) { 533 + ret = xfer_to_guest_mode_handle_work(); 534 + if (ret) 535 + break; 536 + } 508 537 509 538 if (vp->run.flags.intercept_suspend) 510 539 flags |= HV_DISPATCH_VP_FLAG_CLEAR_INTERCEPT_SUSPEND; ··· 2049 2074 /* Retrieve and stash the supported scheduler type */ 2050 2075 static int __init mshv_retrieve_scheduler_type(struct device *dev) 2051 2076 { 2052 - int ret; 2077 + int ret = 0; 2053 2078 2054 - ret = hv_retrieve_scheduler_type(&hv_scheduler_type); 2079 + if (hv_l1vh_partition()) 2080 + hv_scheduler_type = HV_SCHEDULER_TYPE_CORE_SMT; 2081 + else 2082 + ret = hv_retrieve_scheduler_type(&hv_scheduler_type); 2083 + 2055 2084 if (ret) 2056 2085 return ret; 2057 2086 ··· 2182 2203 { 2183 2204 int err; 2184 2205 2185 - if (mshv_retrieve_scheduler_type(dev)) 2186 - return -ENODEV; 2187 - 2188 2206 err = root_scheduler_init(dev); 2189 2207 if (err) 2190 2208 return err; ··· 2203 2227 struct device *dev; 2204 2228 union hv_hypervisor_version_info version_info; 2205 2229 2206 - if (!hv_root_partition() || is_kdump_kernel()) 2230 + if (!hv_parent_partition() || is_kdump_kernel()) 2207 2231 return -ENODEV; 2208 2232 2209 2233 if (hv_get_hypervisor_version(&version_info)) ··· 2240 2264 2241 2265 mshv_cpuhp_online = ret; 2242 2266 2243 - ret = mshv_root_partition_init(dev); 2267 + ret = mshv_retrieve_scheduler_type(dev); 2268 + if (ret) 2269 + goto remove_cpu_state; 2270 + 2271 + if (hv_root_partition()) 2272 + ret = mshv_root_partition_init(dev); 2244 2273 if (ret) 2245 2274 goto remove_cpu_state; 2246 2275
+5 -5
drivers/hv/vmbus_drv.c
··· 322 322 &outbound); 323 323 if (ret < 0) 324 324 return ret; 325 - return sysfs_emit(buf, "%d\n", outbound.current_read_index); 325 + return sysfs_emit(buf, "%u\n", outbound.current_read_index); 326 326 } 327 327 static DEVICE_ATTR_RO(out_read_index); 328 328 ··· 341 341 &outbound); 342 342 if (ret < 0) 343 343 return ret; 344 - return sysfs_emit(buf, "%d\n", outbound.current_write_index); 344 + return sysfs_emit(buf, "%u\n", outbound.current_write_index); 345 345 } 346 346 static DEVICE_ATTR_RO(out_write_index); 347 347 ··· 1742 1742 u32 target_cpu; 1743 1743 ssize_t ret; 1744 1744 1745 - if (sscanf(buf, "%uu", &target_cpu) != 1) 1745 + if (sscanf(buf, "%u", &target_cpu) != 1) 1746 1746 return -EIO; 1747 1747 1748 1748 cpus_read_lock(); ··· 1947 1947 * is running. 1948 1948 * For example, HV_NIC device is used either by uio_hv_generic or hv_netvsc at any given point of 1949 1949 * time, and "ring" sysfs is needed only when uio_hv_generic is bound to that device. To avoid 1950 - * exposing the ring buffer by default, this function is reponsible to enable visibility of 1950 + * exposing the ring buffer by default, this function is responsible to enable visibility of 1951 1951 * ring for userspace to use. 1952 1952 * Note: Race conditions can happen with userspace and it is not encouraged to create new 1953 1953 * use-cases for this. This was added to maintain backward compatibility, while solving ··· 2110 2110 ret = vmbus_add_channel_kobj(child_device_obj, 2111 2111 child_device_obj->channel); 2112 2112 if (ret) { 2113 - pr_err("Unable to register primary channeln"); 2113 + pr_err("Unable to register primary channel\n"); 2114 2114 goto err_kset_unregister; 2115 2115 } 2116 2116 hv_debug_add_dev_dir(child_device_obj);
+2 -2
drivers/input/serio/Kconfig
··· 276 276 277 277 config HYPERV_KEYBOARD 278 278 tristate "Microsoft Synthetic Keyboard driver" 279 - depends on HYPERV 280 - default HYPERV 279 + depends on HYPERV_VMBUS 280 + default HYPERV_VMBUS 281 281 help 282 282 Select this option to enable the Hyper-V Keyboard driver. 283 283
+1 -1
drivers/net/hyperv/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 config HYPERV_NET 3 3 tristate "Microsoft Hyper-V virtual network driver" 4 - depends on HYPERV 4 + depends on HYPERV_VMBUS 5 5 select UCS2_STRING 6 6 select NLS 7 7 help
+1 -1
drivers/pci/Kconfig
··· 221 221 222 222 config PCI_HYPERV 223 223 tristate "Hyper-V PCI Frontend" 224 - depends on ((X86 && X86_64) || ARM64) && HYPERV && PCI_MSI && SYSFS 224 + depends on ((X86 && X86_64) || ARM64) && HYPERV_VMBUS && PCI_MSI && SYSFS 225 225 select PCI_HYPERV_INTERFACE 226 226 select IRQ_MSI_LIB 227 227 help
+1 -1
drivers/scsi/Kconfig
··· 589 589 590 590 config HYPERV_STORAGE 591 591 tristate "Microsoft Hyper-V virtual storage driver" 592 - depends on SCSI && HYPERV 592 + depends on SCSI && HYPERV_VMBUS 593 593 depends on m || SCSI_FC_ATTRS != m 594 594 default HYPERV 595 595 help
+1 -1
drivers/uio/Kconfig
··· 140 140 141 141 config UIO_HV_GENERIC 142 142 tristate "Generic driver for Hyper-V VMBus" 143 - depends on HYPERV 143 + depends on HYPERV_VMBUS 144 144 help 145 145 Generic driver that you can bind, dynamically, to any 146 146 Hyper-V VMBus device. It is useful to provide direct access
+5 -2
drivers/video/fbdev/Kconfig
··· 1773 1773 a bridge adapter. 1774 1774 1775 1775 config FB_HYPERV 1776 - tristate "Microsoft Hyper-V Synthetic Video support" 1777 - depends on FB && HYPERV 1776 + tristate "Microsoft Hyper-V Synthetic Video support (DEPRECATED)" 1777 + depends on FB && HYPERV_VMBUS 1778 1778 select DMA_CMA if HAVE_DMA_CONTIGUOUS && CMA 1779 1779 select FB_IOMEM_HELPERS_DEFERRED 1780 1780 help 1781 1781 This framebuffer driver supports Microsoft Hyper-V Synthetic Video. 1782 + 1783 + This driver is deprecated, please use the Hyper-V DRM driver at 1784 + drivers/gpu/drm/hyperv (CONFIG_DRM_HYPERV) instead. 1782 1785 1783 1786 config FB_SIMPLE 1784 1787 tristate "Simple framebuffer support"
+2
drivers/video/fbdev/hyperv_fb.c
··· 1357 1357 { 1358 1358 int ret; 1359 1359 1360 + pr_warn("Deprecated: use Hyper-V DRM driver instead\n"); 1361 + 1360 1362 if (fb_modesetting_disabled("hyper_fb")) 1361 1363 return -ENODEV; 1362 1364
+16 -3
include/asm-generic/mshyperv.h
··· 31 31 enum hv_partition_type { 32 32 HV_PARTITION_TYPE_GUEST, 33 33 HV_PARTITION_TYPE_ROOT, 34 + HV_PARTITION_TYPE_L1VH, 34 35 }; 35 36 36 37 struct ms_hyperv_info { ··· 163 162 return guest_id; 164 163 } 165 164 165 + #if IS_ENABLED(CONFIG_HYPERV_VMBUS) 166 166 /* Free the message slot and signal end-of-message if required */ 167 167 static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type) 168 168 { ··· 199 197 } 200 198 } 201 199 200 + extern int vmbus_interrupt; 201 + extern int vmbus_irq; 202 + #endif /* CONFIG_HYPERV_VMBUS */ 203 + 202 204 int hv_get_hypervisor_version(union hv_hypervisor_version_info *info); 203 205 204 206 void hv_setup_vmbus_handler(void (*handler)(void)); ··· 215 209 void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs)); 216 210 void hv_remove_crash_handler(void); 217 211 void hv_setup_mshv_handler(void (*handler)(void)); 218 - 219 - extern int vmbus_interrupt; 220 - extern int vmbus_irq; 221 212 222 213 #if IS_ENABLED(CONFIG_HYPERV) 223 214 /* ··· 357 354 { 358 355 return hv_curr_partition_type == HV_PARTITION_TYPE_ROOT; 359 356 } 357 + static inline bool hv_l1vh_partition(void) 358 + { 359 + return hv_curr_partition_type == HV_PARTITION_TYPE_L1VH; 360 + } 361 + static inline bool hv_parent_partition(void) 362 + { 363 + return hv_root_partition() || hv_l1vh_partition(); 364 + } 360 365 int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages); 361 366 int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id); 362 367 int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags); 363 368 364 369 #else /* CONFIG_MSHV_ROOT */ 365 370 static inline bool hv_root_partition(void) { return false; } 371 + static inline bool hv_l1vh_partition(void) { return false; } 372 + static inline bool hv_parent_partition(void) { return false; } 366 373 static inline int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages) 367 374 { 368 375 return -EOPNOTSUPP;
-2
include/hyperv/hvgdk_mini.h
··· 597 597 #define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17) 598 598 #define HV_SYNIC_SINT_VECTOR_MASK (0xFF) 599 599 600 - # 601 - 602 600 /* Hyper-V defined statically assigned SINTs */ 603 601 #define HV_SYNIC_INTERCEPTION_SINT_INDEX 0x00000000 604 602 #define HV_SYNIC_IOMMU_FAULT_SINT_INDEX 0x00000001
+1
include/hyperv/hvhdk_mini.h
··· 301 301 /* HV_OUTPUT_MAP_DEVICE_INTERRUPT */ 302 302 struct hv_output_map_device_interrupt { 303 303 struct hv_interrupt_entry interrupt_entry; 304 + u64 ext_status_deprecated[5]; 304 305 } __packed; 305 306 306 307 /* HV_INPUT_UNMAP_DEVICE_INTERRUPT */
+7 -12
include/linux/entry-kvm.h include/linux/entry-virt.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef __LINUX_ENTRYKVM_H 3 - #define __LINUX_ENTRYKVM_H 2 + #ifndef __LINUX_ENTRYVIRT_H 3 + #define __LINUX_ENTRYVIRT_H 4 4 5 5 #include <linux/static_call_types.h> 6 6 #include <linux/resume_user_mode.h> ··· 10 10 #include <linux/tick.h> 11 11 12 12 /* Transfer to guest mode work */ 13 - #ifdef CONFIG_KVM_XFER_TO_GUEST_WORK 13 + #ifdef CONFIG_VIRT_XFER_TO_GUEST_WORK 14 14 15 15 #ifndef ARCH_XFER_TO_GUEST_MODE_WORK 16 16 # define ARCH_XFER_TO_GUEST_MODE_WORK (0) ··· 21 21 _TIF_NOTIFY_SIGNAL | _TIF_NOTIFY_RESUME | \ 22 22 ARCH_XFER_TO_GUEST_MODE_WORK) 23 23 24 - struct kvm_vcpu; 25 - 26 24 /** 27 25 * arch_xfer_to_guest_mode_handle_work - Architecture specific xfer to guest 28 26 * mode work handling function. ··· 30 32 * Invoked from xfer_to_guest_mode_handle_work(). Defaults to NOOP. Can be 31 33 * replaced by architecture specific code. 32 34 */ 33 - static inline int arch_xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu, 34 - unsigned long ti_work); 35 + static inline int arch_xfer_to_guest_mode_handle_work(unsigned long ti_work); 35 36 36 37 #ifndef arch_xfer_to_guest_mode_work 37 - static inline int arch_xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu, 38 - unsigned long ti_work) 38 + static inline int arch_xfer_to_guest_mode_handle_work(unsigned long ti_work) 39 39 { 40 40 return 0; 41 41 } ··· 42 46 /** 43 47 * xfer_to_guest_mode_handle_work - Check and handle pending work which needs 44 48 * to be handled before going to guest mode 45 - * @vcpu: Pointer to current's VCPU data 46 49 * 47 50 * Returns: 0 or an error code 48 51 */ 49 - int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu); 52 + int xfer_to_guest_mode_handle_work(void); 50 53 51 54 /** 52 55 * xfer_to_guest_mode_prepare - Perform last minute preparation work that ··· 90 95 lockdep_assert_irqs_disabled(); 91 96 return __xfer_to_guest_mode_work_pending(); 92 97 } 93 - #endif /* CONFIG_KVM_XFER_TO_GUEST_WORK */ 98 + #endif /* CONFIG_VIRT_XFER_TO_GUEST_WORK */ 94 99 95 100 #endif
+1 -6
include/linux/hyperv.h
··· 707 707 unsigned char msg[]; 708 708 }; 709 709 710 - struct vmbus_close_msg { 711 - struct vmbus_channel_msginfo info; 712 - struct vmbus_channel_close_channel msg; 713 - }; 714 - 715 710 enum vmbus_device_type { 716 711 HV_IDE = 0, 717 712 HV_SCSI, ··· 795 800 struct hv_ring_buffer_info outbound; /* send to parent */ 796 801 struct hv_ring_buffer_info inbound; /* receive from parent */ 797 802 798 - struct vmbus_close_msg close_msg; 803 + struct vmbus_channel_close_channel close_msg; 799 804 800 805 /* Statistics */ 801 806 u64 interrupts; /* Host to Guest interrupts */
+14 -3
include/linux/kvm_host.h
··· 2 2 #ifndef __KVM_HOST_H 3 3 #define __KVM_HOST_H 4 4 5 - 5 + #include <linux/entry-virt.h> 6 6 #include <linux/types.h> 7 7 #include <linux/hardirq.h> 8 8 #include <linux/list.h> ··· 2450 2450 } 2451 2451 #endif /* CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE */ 2452 2452 2453 - #ifdef CONFIG_KVM_XFER_TO_GUEST_WORK 2453 + #ifdef CONFIG_VIRT_XFER_TO_GUEST_WORK 2454 2454 static inline void kvm_handle_signal_exit(struct kvm_vcpu *vcpu) 2455 2455 { 2456 2456 vcpu->run->exit_reason = KVM_EXIT_INTR; 2457 2457 vcpu->stat.signal_exits++; 2458 2458 } 2459 - #endif /* CONFIG_KVM_XFER_TO_GUEST_WORK */ 2459 + 2460 + static inline int kvm_xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu) 2461 + { 2462 + int r = xfer_to_guest_mode_handle_work(); 2463 + 2464 + if (r) { 2465 + WARN_ON_ONCE(r != -EINTR); 2466 + kvm_handle_signal_exit(vcpu); 2467 + } 2468 + return r; 2469 + } 2470 + #endif /* CONFIG_VIRT_XFER_TO_GUEST_WORK */ 2460 2471 2461 2472 /* 2462 2473 * If more than one page is being (un)accounted, @virt must be the address of
+1 -1
include/linux/rcupdate.h
··· 129 129 static inline void rcu_sysrq_end(void) { } 130 130 #endif /* #else #ifdef CONFIG_RCU_STALL_COMMON */ 131 131 132 - #if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_KVM_XFER_TO_GUEST_WORK)) 132 + #if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_VIRT_XFER_TO_GUEST_WORK)) 133 133 void rcu_irq_work_resched(void); 134 134 #else 135 135 static __always_inline void rcu_irq_work_resched(void) { }
+1 -1
kernel/entry/Makefile
··· 14 14 15 15 obj-$(CONFIG_GENERIC_IRQ_ENTRY) += common.o 16 16 obj-$(CONFIG_GENERIC_SYSCALL) += syscall-common.o syscall_user_dispatch.o 17 - obj-$(CONFIG_KVM_XFER_TO_GUEST_WORK) += kvm.o 17 + obj-$(CONFIG_VIRT_XFER_TO_GUEST_WORK) += virt.o
+6 -9
kernel/entry/kvm.c kernel/entry/virt.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 - #include <linux/entry-kvm.h> 4 - #include <linux/kvm_host.h> 3 + #include <linux/entry-virt.h> 5 4 6 - static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work) 5 + static int xfer_to_guest_mode_work(unsigned long ti_work) 7 6 { 8 7 do { 9 8 int ret; 10 9 11 - if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) { 12 - kvm_handle_signal_exit(vcpu); 10 + if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) 13 11 return -EINTR; 14 - } 15 12 16 13 if (ti_work & (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY)) 17 14 schedule(); ··· 16 19 if (ti_work & _TIF_NOTIFY_RESUME) 17 20 resume_user_mode_work(NULL); 18 21 19 - ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work); 22 + ret = arch_xfer_to_guest_mode_handle_work(ti_work); 20 23 if (ret) 21 24 return ret; 22 25 ··· 25 28 return 0; 26 29 } 27 30 28 - int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu) 31 + int xfer_to_guest_mode_handle_work(void) 29 32 { 30 33 unsigned long ti_work; 31 34 ··· 41 44 if (!(ti_work & XFER_TO_GUEST_MODE_WORK)) 42 45 return 0; 43 46 44 - return xfer_to_guest_mode_work(vcpu, ti_work); 47 + return xfer_to_guest_mode_work(ti_work); 45 48 } 46 49 EXPORT_SYMBOL_GPL(xfer_to_guest_mode_handle_work);
+3 -3
kernel/rcu/tree.c
··· 573 573 } 574 574 EXPORT_SYMBOL_GPL(rcutorture_format_gp_seqs); 575 575 576 - #if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_KVM_XFER_TO_GUEST_WORK)) 576 + #if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_VIRT_XFER_TO_GUEST_WORK)) 577 577 /* 578 578 * An empty function that will trigger a reschedule on 579 579 * IRQ tail once IRQs get re-enabled on userspace/guest resume. ··· 602 602 if (IS_ENABLED(CONFIG_GENERIC_ENTRY) && !(current->flags & PF_VCPU)) 603 603 return; 604 604 605 - if (IS_ENABLED(CONFIG_KVM_XFER_TO_GUEST_WORK) && (current->flags & PF_VCPU)) 605 + if (IS_ENABLED(CONFIG_VIRT_XFER_TO_GUEST_WORK) && (current->flags & PF_VCPU)) 606 606 return; 607 607 608 608 instrumentation_begin(); ··· 611 611 } 612 612 instrumentation_end(); 613 613 } 614 - #endif /* #if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_KVM_XFER_TO_GUEST_WORK)) */ 614 + #endif /* #if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_VIRT_XFER_TO_GUEST_WORK)) */ 615 615 616 616 #ifdef CONFIG_PROVE_RCU 617 617 /**
+1 -1
net/vmw_vsock/Kconfig
··· 72 72 73 73 config HYPERV_VSOCKETS 74 74 tristate "Hyper-V transport for Virtual Sockets" 75 - depends on VSOCKETS && HYPERV 75 + depends on VSOCKETS && HYPERV_VMBUS 76 76 help 77 77 This module implements a Hyper-V transport for Virtual Sockets. 78 78
+1 -1
virt/kvm/Kconfig
··· 87 87 config HAVE_KVM_NO_POLL 88 88 bool 89 89 90 - config KVM_XFER_TO_GUEST_WORK 90 + config VIRT_XFER_TO_GUEST_WORK 91 91 bool 92 92 93 93 config HAVE_KVM_PM_NOTIFIER