Merge tag 'hyperv-next-signed-20240320' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Mar 2024 17:01:02 +0000 (10:01 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Mar 2024 17:01:02 +0000 (10:01 -0700)
Pull hyperv updates from Wei Liu:

 - Use Hyper-V entropy to seed guest random number generator (Michael
   Kelley)

 - Convert to platform remove callback returning void for vmbus (Uwe
   Kleine-König)

 - Introduce hv_get_hypervisor_version function (Nuno Das Neves)

 - Rename some HV_REGISTER_* defines for consistency (Nuno Das Neves)

 - Change prefix of generic HV_REGISTER_* MSRs to HV_MSR_* (Nuno Das
   Neves)

 - Cosmetic changes for hv_spinlock.c (Purna Pavan Chandra Aekkaladevi)

 - Use per cpu initial stack for vtl context (Saurabh Sengar)

* tag 'hyperv-next-signed-20240320' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
  x86/hyperv: Use Hyper-V entropy to seed guest random number generator
  x86/hyperv: Cosmetic changes for hv_spinlock.c
  hyperv-tlfs: Rename some HV_REGISTER_* defines for consistency
  hv: vmbus: Convert to platform remove callback returning void
  mshyperv: Introduce hv_get_hypervisor_version function
  x86/hyperv: Use per cpu initial stack for vtl context
  hyperv-tlfs: Change prefix of generic HV_REGISTER_* MSRs to HV_MSR_*

1  2 
arch/x86/hyperv/hv_vtl.c
arch/x86/kernel/cpu/mshyperv.c
drivers/hv/vmbus_drv.c

diff --combined arch/x86/hyperv/hv_vtl.c
index edd2f35b2a5e100ce9662ceead612bc04c213f29,92bd5a55f0937064382d3377d4fd16b2d6500a25..5c7de79423b8a5e13feea450abea601cae9720d0
  #include <asm/i8259.h>
  #include <asm/mshyperv.h>
  #include <asm/realmode.h>
+ #include <../kernel/smpboot.h>
  
  extern struct boot_params boot_params;
  static struct real_mode_header hv_vtl_real_mode_header;
  
 +static bool __init hv_vtl_msi_ext_dest_id(void)
 +{
 +      return true;
 +}
 +
  void __init hv_vtl_init_platform(void)
  {
        pr_info("Linux runs in Hyper-V Virtual Trust Level\n");
@@@ -31,9 -27,8 +32,9 @@@
        x86_init.timers.timer_init = x86_init_noop;
  
        /* Avoid searching for BIOS MP tables */
 -      x86_init.mpparse.find_smp_config = x86_init_noop;
 -      x86_init.mpparse.get_smp_config = x86_init_uint_noop;
 +      x86_init.mpparse.find_mptable = x86_init_noop;
 +      x86_init.mpparse.early_parse_smp_cfg = x86_init_noop;
 +      x86_init.mpparse.parse_smp_cfg = x86_init_noop;
  
        x86_platform.get_wallclock = get_rtc_noop;
        x86_platform.set_wallclock = set_rtc_noop;
@@@ -44,8 -39,6 +45,8 @@@
        x86_platform.legacy.warm_reset = 0;
        x86_platform.legacy.reserve_bios_regions = 0;
        x86_platform.legacy.devices.pnpbios = 0;
 +
 +      x86_init.hyper.msi_ext_dest_id = hv_vtl_msi_ext_dest_id;
  }
  
  static inline u64 hv_vtl_system_desc_base(struct ldttss_desc *desc)
@@@ -65,7 -58,7 +66,7 @@@ static void hv_vtl_ap_entry(void
        ((secondary_startup_64_fn)secondary_startup_64)(&boot_params, &boot_params);
  }
  
- static int hv_vtl_bringup_vcpu(u32 target_vp_index, u64 eip_ignored)
+ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
  {
        u64 status;
        int ret = 0;
@@@ -79,7 -72,9 +80,9 @@@
        struct ldttss_desc *ldt;
        struct desc_struct *gdt;
  
-       u64 rsp = current->thread.sp;
+       struct task_struct *idle = idle_thread_get(cpu);
+       u64 rsp = (unsigned long)idle->thread.sp;
        u64 rip = (u64)&hv_vtl_ap_entry;
  
        native_store_gdt(&gdt_ptr);
@@@ -206,7 -201,15 +209,15 @@@ static int hv_vtl_apicid_to_vp_id(u32 a
  
  static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip)
  {
-       int vp_id;
+       int vp_id, cpu;
+       /* Find the logical CPU for the APIC ID */
+       for_each_present_cpu(cpu) {
+               if (arch_match_cpu_phys_id(cpu, apicid))
+                       break;
+       }
+       if (cpu >= nr_cpu_ids)
+               return -EINVAL;
  
        pr_debug("Bringing up CPU with APIC ID %d in VTL2...\n", apicid);
        vp_id = hv_vtl_apicid_to_vp_id(apicid);
                return -EINVAL;
        }
  
-       return hv_vtl_bringup_vcpu(vp_id, start_eip);
+       return hv_vtl_bringup_vcpu(vp_id, cpu, start_eip);
  }
  
  int __init hv_vtl_early_init(void)
index 303fef824167d9c57e8b6068eecd62f31f071638,faf438dce9db468edf3c1e5a5b195b0096a2c00a..e0fd57a8ba840431e1f48dd61c1bc0ffc9fc0d82
@@@ -45,70 -45,70 +45,70 @@@ bool hyperv_paravisor_present __ro_afte
  EXPORT_SYMBOL_GPL(hyperv_paravisor_present);
  
  #if IS_ENABLED(CONFIG_HYPERV)
- static inline unsigned int hv_get_nested_reg(unsigned int reg)
+ static inline unsigned int hv_get_nested_msr(unsigned int reg)
  {
-       if (hv_is_sint_reg(reg))
-               return reg - HV_REGISTER_SINT0 + HV_REGISTER_NESTED_SINT0;
+       if (hv_is_sint_msr(reg))
+               return reg - HV_X64_MSR_SINT0 + HV_X64_MSR_NESTED_SINT0;
  
        switch (reg) {
-       case HV_REGISTER_SIMP:
-               return HV_REGISTER_NESTED_SIMP;
-       case HV_REGISTER_SIEFP:
-               return HV_REGISTER_NESTED_SIEFP;
-       case HV_REGISTER_SVERSION:
-               return HV_REGISTER_NESTED_SVERSION;
-       case HV_REGISTER_SCONTROL:
-               return HV_REGISTER_NESTED_SCONTROL;
-       case HV_REGISTER_EOM:
-               return HV_REGISTER_NESTED_EOM;
+       case HV_X64_MSR_SIMP:
+               return HV_X64_MSR_NESTED_SIMP;
+       case HV_X64_MSR_SIEFP:
+               return HV_X64_MSR_NESTED_SIEFP;
+       case HV_X64_MSR_SVERSION:
+               return HV_X64_MSR_NESTED_SVERSION;
+       case HV_X64_MSR_SCONTROL:
+               return HV_X64_MSR_NESTED_SCONTROL;
+       case HV_X64_MSR_EOM:
+               return HV_X64_MSR_NESTED_EOM;
        default:
                return reg;
        }
  }
  
- u64 hv_get_non_nested_register(unsigned int reg)
+ u64 hv_get_non_nested_msr(unsigned int reg)
  {
        u64 value;
  
-       if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present)
+       if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present)
                hv_ivm_msr_read(reg, &value);
        else
                rdmsrl(reg, value);
        return value;
  }
- EXPORT_SYMBOL_GPL(hv_get_non_nested_register);
+ EXPORT_SYMBOL_GPL(hv_get_non_nested_msr);
  
- void hv_set_non_nested_register(unsigned int reg, u64 value)
+ void hv_set_non_nested_msr(unsigned int reg, u64 value)
  {
-       if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present) {
+       if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present) {
                hv_ivm_msr_write(reg, value);
  
                /* Write proxy bit via wrmsl instruction */
-               if (hv_is_sint_reg(reg))
+               if (hv_is_sint_msr(reg))
                        wrmsrl(reg, value | 1 << 20);
        } else {
                wrmsrl(reg, value);
        }
  }
- EXPORT_SYMBOL_GPL(hv_set_non_nested_register);
+ EXPORT_SYMBOL_GPL(hv_set_non_nested_msr);
  
- u64 hv_get_register(unsigned int reg)
+ u64 hv_get_msr(unsigned int reg)
  {
        if (hv_nested)
-               reg = hv_get_nested_reg(reg);
+               reg = hv_get_nested_msr(reg);
  
-       return hv_get_non_nested_register(reg);
+       return hv_get_non_nested_msr(reg);
  }
- EXPORT_SYMBOL_GPL(hv_get_register);
+ EXPORT_SYMBOL_GPL(hv_get_msr);
  
- void hv_set_register(unsigned int reg, u64 value)
+ void hv_set_msr(unsigned int reg, u64 value)
  {
        if (hv_nested)
-               reg = hv_get_nested_reg(reg);
+               reg = hv_get_nested_msr(reg);
  
-       hv_set_non_nested_register(reg, value);
+       hv_set_non_nested_msr(reg, value);
  }
- EXPORT_SYMBOL_GPL(hv_set_register);
+ EXPORT_SYMBOL_GPL(hv_set_msr);
  
  static void (*vmbus_handler)(void);
  static void (*hv_stimer0_handler)(void);
@@@ -209,9 -209,7 +209,9 @@@ static void hv_machine_shutdown(void
        if (kexec_in_progress)
                hyperv_cleanup();
  }
 +#endif /* CONFIG_KEXEC_CORE */
  
 +#ifdef CONFIG_CRASH_DUMP
  static void hv_machine_crash_shutdown(struct pt_regs *regs)
  {
        if (hv_crash_handler)
        /* Disable the hypercall page when there is only 1 active CPU. */
        hyperv_cleanup();
  }
 -#endif /* CONFIG_KEXEC_CORE */
 +#endif /* CONFIG_CRASH_DUMP */
  #endif /* CONFIG_HYPERV */
  
  static uint32_t  __init ms_hyperv_platform(void)
@@@ -352,13 -350,24 +352,24 @@@ static void __init reduced_hw_init(void
        x86_init.irqs.pre_vector_init   = x86_init_noop;
  }
  
+ int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+ {
+       unsigned int hv_max_functions;
+       hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS);
+       if (hv_max_functions < HYPERV_CPUID_VERSION) {
+               pr_err("%s: Could not detect Hyper-V version\n", __func__);
+               return -ENODEV;
+       }
+       cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, &info->edx);
+       return 0;
+ }
  static void __init ms_hyperv_init_platform(void)
  {
        int hv_max_functions_eax;
-       int hv_host_info_eax;
-       int hv_host_info_ebx;
-       int hv_host_info_ecx;
-       int hv_host_info_edx;
  
  #ifdef CONFIG_PARAVIRT
        pv_info.name = "Hyper-V";
                pr_info("Hyper-V: running on a nested hypervisor\n");
        }
  
-       /*
-        * Extract host information.
-        */
-       if (hv_max_functions_eax >= HYPERV_CPUID_VERSION) {
-               hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION);
-               hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION);
-               hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION);
-               hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION);
-               pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
-                       hv_host_info_ebx >> 16, hv_host_info_ebx & 0xFFFF,
-                       hv_host_info_eax, hv_host_info_edx & 0xFFFFFF,
-                       hv_host_info_ecx, hv_host_info_edx >> 24);
-       }
        if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
            ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
                x86_platform.calibrate_tsc = hv_get_tsc_khz;
                                /* To be supported: more work is required.  */
                                ms_hyperv.features &= ~HV_MSR_REFERENCE_TSC_AVAILABLE;
  
-                               /* HV_REGISTER_CRASH_CTL is unsupported. */
+                               /* HV_MSR_CRASH_CTL is unsupported. */
                                ms_hyperv.misc_features &= ~HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE;
  
                                /* Don't trust Hyper-V's TLB-flushing hypercalls. */
        no_timer_check = 1;
  #endif
  
 -#if IS_ENABLED(CONFIG_HYPERV) && defined(CONFIG_KEXEC_CORE)
 +#if IS_ENABLED(CONFIG_HYPERV)
 +#if defined(CONFIG_KEXEC_CORE)
        machine_ops.shutdown = hv_machine_shutdown;
 +#endif
 +#if defined(CONFIG_CRASH_DUMP)
        machine_ops.crash_shutdown = hv_machine_crash_shutdown;
 +#endif
  #endif
        if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) {
                /*
         */
        x86_platform.apic_post_init = hyperv_init;
        hyperv_setup_mmu_ops();
 -      /* Setup the IDT for hypervisor callback */
 -      alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_hyperv_callback);
  
 -      /* Setup the IDT for reenlightenment notifications */
 +      /* Install system interrupt handler for hypervisor callback */
 +      sysvec_install(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback);
 +
 +      /* Install system interrupt handler for reenlightenment notifications */
        if (ms_hyperv.features & HV_ACCESS_REENLIGHTENMENT) {
 -              alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR,
 -                              asm_sysvec_hyperv_reenlightenment);
 +              sysvec_install(HYPERV_REENLIGHTENMENT_VECTOR, sysvec_hyperv_reenlightenment);
        }
  
 -      /* Setup the IDT for stimer0 */
 +      /* Install system interrupt handler for stimer0 */
        if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) {
 -              alloc_intr_gate(HYPERV_STIMER0_VECTOR,
 -                              asm_sysvec_hyperv_stimer0);
 +              sysvec_install(HYPERV_STIMER0_VECTOR, sysvec_hyperv_stimer0);
        }
  
  # ifdef CONFIG_SMP
@@@ -648,6 -639,7 +644,7 @@@ const __initconst struct hypervisor_x8
        .init.x2apic_available  = ms_hyperv_x2apic_available,
        .init.msi_ext_dest_id   = ms_hyperv_msi_ext_dest_id,
        .init.init_platform     = ms_hyperv_init_platform,
+       .init.guest_late_init   = ms_hyperv_late_init,
  #ifdef CONFIG_AMD_MEM_ENCRYPT
        .runtime.sev_es_hcall_prepare = hv_sev_es_hcall_prepare,
        .runtime.sev_es_hcall_finish = hv_sev_es_hcall_finish,
diff --combined drivers/hv/vmbus_drv.c
index 7f7965f3d187884d87a2a822c3479485e17cec62,e25223cee3abcd039114d160adc4cdf6666fa651..4cb17603a8289b259e64dc6a5be215cb1e1a8a57
@@@ -988,7 -988,7 +988,7 @@@ static const struct dev_pm_ops vmbus_p
  };
  
  /* The one and only one */
 -static struct bus_type  hv_bus = {
 +static const struct bus_type  hv_bus = {
        .name =         "vmbus",
        .match =                vmbus_match,
        .shutdown =             vmbus_shutdown,
@@@ -2359,10 -2359,9 +2359,9 @@@ static int vmbus_platform_driver_probe(
                return vmbus_acpi_add(pdev);
  }
  
- static int vmbus_platform_driver_remove(struct platform_device *pdev)
+ static void vmbus_platform_driver_remove(struct platform_device *pdev)
  {
        vmbus_mmio_remove();
-       return 0;
  }
  
  #ifdef CONFIG_PM_SLEEP
@@@ -2542,7 -2541,7 +2541,7 @@@ static const struct dev_pm_ops vmbus_bu
  
  static struct platform_driver vmbus_platform_driver = {
        .probe = vmbus_platform_driver_probe,
-       .remove = vmbus_platform_driver_remove,
+       .remove_new = vmbus_platform_driver_remove,
        .driver = {
                .name = "vmbus",
                .acpi_match_table = ACPI_PTR(vmbus_acpi_device_ids),