]> git.itanic.dy.fi Git - linux-stable/commitdiff
x86/hyperv: Use per cpu initial stack for vtl context
authorSaurabh Sengar <ssengar@linux.microsoft.com>
Sun, 3 Mar 2024 08:01:36 +0000 (00:01 -0800)
committerSasha Levin <sashal@kernel.org>
Tue, 26 Mar 2024 22:17:30 +0000 (18:17 -0400)
[ Upstream commit 2b4b90e053a29057fb05ba81acce26bddce8d404 ]

Currently, the secondary CPUs in Hyper-V VTL context lack support for
parallel startup. Therefore, relying on the single initial_stack fetched
from the current task structure suffices for all vCPUs.

However, common initial_stack risks stack corruption when parallel startup
is enabled. In order to facilitate parallel startup, use the initial_stack
from the per CPU idle thread instead of the current task.

Fixes: 3be1bc2fe9d2 ("x86/hyperv: VTL support for Hyper-V")
Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/r/1709452896-13342-1-git-send-email-ssengar@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Message-ID: <1709452896-13342-1-git-send-email-ssengar@linux.microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/x86/hyperv/hv_vtl.c
drivers/hv/Kconfig

index cf1b78cb2d0431ae7095d1c8769c1e140c4357a7..c8062975a531651105567c1c4be38597b4440ae2 100644 (file)
@@ -12,6 +12,7 @@
 #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;
@@ -64,7 +65,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;
@@ -78,7 +79,9 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, u64 eip_ignored)
        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);
@@ -205,7 +208,15 @@ static int hv_vtl_apicid_to_vp_id(u32 apic_id)
 
 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);
@@ -219,7 +230,7 @@ static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip)
                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 00242107d62e02ccca5b033ae12e5e2538df7696..862c47b191afe85b7aaf18fde71d46c8ec4c852b 100644 (file)
@@ -16,6 +16,7 @@ config HYPERV
 config HYPERV_VTL_MODE
        bool "Enable Linux to boot in VTL context"
        depends on X86_64 && HYPERV
+       depends on SMP
        default n
        help
          Virtual Secure Mode (VSM) is a set of hypervisor capabilities and