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

x86/hyperv: Use per cpu initial stack for vtl context

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>

authored by

Saurabh Sengar and committed by
Wei Liu
2b4b90e0 0e3f7d12

+16 -4
+15 -4
arch/x86/hyperv/hv_vtl.c
··· 12 12 #include <asm/i8259.h> 13 13 #include <asm/mshyperv.h> 14 14 #include <asm/realmode.h> 15 + #include <../kernel/smpboot.h> 15 16 16 17 extern struct boot_params boot_params; 17 18 static struct real_mode_header hv_vtl_real_mode_header; ··· 58 57 ((secondary_startup_64_fn)secondary_startup_64)(&boot_params, &boot_params); 59 58 } 60 59 61 - static int hv_vtl_bringup_vcpu(u32 target_vp_index, u64 eip_ignored) 60 + static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) 62 61 { 63 62 u64 status; 64 63 int ret = 0; ··· 72 71 struct ldttss_desc *ldt; 73 72 struct desc_struct *gdt; 74 73 75 - u64 rsp = current->thread.sp; 74 + struct task_struct *idle = idle_thread_get(cpu); 75 + u64 rsp = (unsigned long)idle->thread.sp; 76 + 76 77 u64 rip = (u64)&hv_vtl_ap_entry; 77 78 78 79 native_store_gdt(&gdt_ptr); ··· 201 198 202 199 static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip) 203 200 { 204 - int vp_id; 201 + int vp_id, cpu; 202 + 203 + /* Find the logical CPU for the APIC ID */ 204 + for_each_present_cpu(cpu) { 205 + if (arch_match_cpu_phys_id(cpu, apicid)) 206 + break; 207 + } 208 + if (cpu >= nr_cpu_ids) 209 + return -EINVAL; 205 210 206 211 pr_debug("Bringing up CPU with APIC ID %d in VTL2...\n", apicid); 207 212 vp_id = hv_vtl_apicid_to_vp_id(apicid); ··· 223 212 return -EINVAL; 224 213 } 225 214 226 - return hv_vtl_bringup_vcpu(vp_id, start_eip); 215 + return hv_vtl_bringup_vcpu(vp_id, cpu, start_eip); 227 216 } 228 217 229 218 int __init hv_vtl_early_init(void)
+1
drivers/hv/Kconfig
··· 16 16 config HYPERV_VTL_MODE 17 17 bool "Enable Linux to boot in VTL context" 18 18 depends on X86_64 && HYPERV 19 + depends on SMP 19 20 default n 20 21 help 21 22 Virtual Secure Mode (VSM) is a set of hypervisor capabilities and