Skip to content

Commit 43cb39a

Browse files
romank-msftliuw
authored andcommitted
arch/x86: Provide the CPU number in the wakeup AP callback
When starting APs, confidential guests and paravisor guests need to know the CPU number, and the pattern of using the linear search has emerged in several places. With N processors that leads to the O(N^2) time complexity. Provide the CPU number in the AP wake up callback so that one can get the CPU number in constant time. Suggested-by: Michael Kelley <mhklinux@outlook.com> Signed-off-by: Roman Kisel <romank@linux.microsoft.com> Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Michael Kelley <mhklinux@outlook.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://lore.kernel.org/r/20250507182227.7421-3-romank@linux.microsoft.com Signed-off-by: Wei Liu <wei.liu@kernel.org> Message-ID: <20250507182227.7421-3-romank@linux.microsoft.com>
1 parent 86c4827 commit 43cb39a

File tree

10 files changed

+28
-49
lines changed

10 files changed

+28
-49
lines changed

arch/x86/coco/sev/core.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,15 +1177,15 @@ static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa, int apic_id)
11771177
free_page((unsigned long)vmsa);
11781178
}
11791179

1180-
static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
1180+
static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip, unsigned int cpu)
11811181
{
11821182
struct sev_es_save_area *cur_vmsa, *vmsa;
11831183
struct ghcb_state state;
11841184
struct svsm_ca *caa;
11851185
unsigned long flags;
11861186
struct ghcb *ghcb;
11871187
u8 sipi_vector;
1188-
int cpu, ret;
1188+
int ret;
11891189
u64 cr4;
11901190

11911191
/*
@@ -1206,15 +1206,6 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
12061206

12071207
/* Override start_ip with known protected guest start IP */
12081208
start_ip = real_mode_header->sev_es_trampoline_start;
1209-
1210-
/* Find the logical CPU for the APIC ID */
1211-
for_each_present_cpu(cpu) {
1212-
if (arch_match_cpu_phys_id(cpu, apic_id))
1213-
break;
1214-
}
1215-
if (cpu >= nr_cpu_ids)
1216-
return -EINVAL;
1217-
12181209
cur_vmsa = per_cpu(sev_vmsa, cpu);
12191210

12201211
/*

arch/x86/hyperv/hv_vtl.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,17 +211,9 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
211211
return ret;
212212
}
213213

214-
static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip)
214+
static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip, unsigned int cpu)
215215
{
216-
int vp_index, cpu;
217-
218-
/* Find the logical CPU for the APIC ID */
219-
for_each_present_cpu(cpu) {
220-
if (arch_match_cpu_phys_id(cpu, apicid))
221-
break;
222-
}
223-
if (cpu >= nr_cpu_ids)
224-
return -EINVAL;
216+
int vp_index;
225217

226218
pr_debug("Bringing up CPU with APIC ID %d in VTL2...\n", apicid);
227219
vp_index = hv_apicid_to_vp_index(apicid);

arch/x86/hyperv/ivm.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa)
289289
free_page((unsigned long)vmsa);
290290
}
291291

292-
int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip)
292+
int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip, unsigned int cpu)
293293
{
294294
struct sev_es_save_area *vmsa = (struct sev_es_save_area *)
295295
__get_free_page(GFP_KERNEL | __GFP_ZERO);
@@ -298,7 +298,7 @@ int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip)
298298
u64 ret, retry = 5;
299299
struct hv_enable_vp_vtl *start_vp_input;
300300
unsigned long flags;
301-
int cpu, vp_index;
301+
int vp_index;
302302

303303
if (!vmsa)
304304
return -ENOMEM;
@@ -308,17 +308,6 @@ int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip)
308308
if (vp_index < 0 || vp_index > ms_hyperv.max_vp_index)
309309
return -EINVAL;
310310

311-
/*
312-
* Find the Linux CPU number for addressing the per-CPU data, and it
313-
* might not be the same as APIC ID.
314-
*/
315-
for_each_present_cpu(cpu) {
316-
if (arch_match_cpu_phys_id(cpu, apic_id))
317-
break;
318-
}
319-
if (cpu >= nr_cpu_ids)
320-
return -EINVAL;
321-
322311
native_store_gdt(&gdtr);
323312

324313
vmsa->gdtr.base = gdtr.address;

arch/x86/include/asm/apic.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,9 @@ struct apic {
313313
u32 (*get_apic_id)(u32 id);
314314

315315
/* wakeup_secondary_cpu */
316-
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip);
316+
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip, unsigned int cpu);
317317
/* wakeup secondary CPU using 64-bit wakeup point */
318-
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip);
318+
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip, unsigned int cpu);
319319

320320
char *name;
321321
};
@@ -333,8 +333,8 @@ struct apic_override {
333333
void (*send_IPI_self)(int vector);
334334
u64 (*icr_read)(void);
335335
void (*icr_write)(u32 low, u32 high);
336-
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip);
337-
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip);
336+
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip, unsigned int cpu);
337+
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip, unsigned int cpu);
338338
};
339339

340340
/*

arch/x86/include/asm/mshyperv.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,12 @@ int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
268268
#ifdef CONFIG_AMD_MEM_ENCRYPT
269269
bool hv_ghcb_negotiate_protocol(void);
270270
void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
271-
int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip);
271+
int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip, unsigned int cpu);
272272
#else
273273
static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
274274
static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
275-
static inline int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip) { return 0; }
275+
static inline int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip,
276+
unsigned int cpu) { return 0; }
276277
#endif
277278

278279
#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)

arch/x86/kernel/acpi/madt_wakeup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ static int __init acpi_mp_setup_reset(u64 reset_vector)
126126
return 0;
127127
}
128128

129-
static int acpi_wakeup_cpu(u32 apicid, unsigned long start_ip)
129+
static int acpi_wakeup_cpu(u32 apicid, unsigned long start_ip, unsigned int cpu)
130130
{
131131
if (!acpi_mp_wake_mailbox_paddr) {
132132
pr_warn_once("No MADT mailbox: cannot bringup secondary CPUs. Booting with kexec?\n");

arch/x86/kernel/apic/apic_noop.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ static void noop_send_IPI_allbutself(int vector) { }
2727
static void noop_send_IPI_all(int vector) { }
2828
static void noop_send_IPI_self(int vector) { }
2929
static void noop_apic_icr_write(u32 low, u32 id) { }
30-
static int noop_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip) { return -1; }
30+
31+
static int noop_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip,
32+
unsigned int cpu)
33+
{
34+
return -1;
35+
}
36+
3137
static u64 noop_apic_icr_read(void) { return 0; }
3238
static u32 noop_get_apic_id(u32 apicid) { return 0; }
3339
static void noop_apic_eoi(void) { }

arch/x86/kernel/apic/apic_numachip.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static void numachip2_apic_icr_write(int apicid, unsigned int val)
5656
numachip2_write32_lcsr(NUMACHIP2_APIC_ICR, (apicid << 12) | val);
5757
}
5858

59-
static int numachip_wakeup_secondary(u32 phys_apicid, unsigned long start_rip)
59+
static int numachip_wakeup_secondary(u32 phys_apicid, unsigned long start_rip, unsigned int cpu)
6060
{
6161
numachip_apic_icr_write(phys_apicid, APIC_DM_INIT);
6262
numachip_apic_icr_write(phys_apicid, APIC_DM_STARTUP |

arch/x86/kernel/apic/x2apic_uv_x.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ static __init void build_uv_gr_table(void)
667667
}
668668
}
669669

670-
static int uv_wakeup_secondary(u32 phys_apicid, unsigned long start_rip)
670+
static int uv_wakeup_secondary(u32 phys_apicid, unsigned long start_rip, unsigned int cpu)
671671
{
672672
unsigned long val;
673673
int pnode;

arch/x86/kernel/smpboot.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ static void send_init_sequence(u32 phys_apicid)
695695
/*
696696
* Wake up AP by INIT, INIT, STARTUP sequence.
697697
*/
698-
static int wakeup_secondary_cpu_via_init(u32 phys_apicid, unsigned long start_eip)
698+
static int wakeup_secondary_cpu_via_init(u32 phys_apicid, unsigned long start_eip, unsigned int cpu)
699699
{
700700
unsigned long send_status = 0, accept_status = 0;
701701
int num_starts, j, maxlvt;
@@ -842,7 +842,7 @@ int common_cpu_up(unsigned int cpu, struct task_struct *idle)
842842
* Returns zero if startup was successfully sent, else error code from
843843
* ->wakeup_secondary_cpu.
844844
*/
845-
static int do_boot_cpu(u32 apicid, int cpu, struct task_struct *idle)
845+
static int do_boot_cpu(u32 apicid, unsigned int cpu, struct task_struct *idle)
846846
{
847847
unsigned long start_ip = real_mode_header->trampoline_start;
848848
int ret;
@@ -896,11 +896,11 @@ static int do_boot_cpu(u32 apicid, int cpu, struct task_struct *idle)
896896
* - Use an INIT boot APIC message
897897
*/
898898
if (apic->wakeup_secondary_cpu_64)
899-
ret = apic->wakeup_secondary_cpu_64(apicid, start_ip);
899+
ret = apic->wakeup_secondary_cpu_64(apicid, start_ip, cpu);
900900
else if (apic->wakeup_secondary_cpu)
901-
ret = apic->wakeup_secondary_cpu(apicid, start_ip);
901+
ret = apic->wakeup_secondary_cpu(apicid, start_ip, cpu);
902902
else
903-
ret = wakeup_secondary_cpu_via_init(apicid, start_ip);
903+
ret = wakeup_secondary_cpu_via_init(apicid, start_ip, cpu);
904904

905905
/* If the wakeup mechanism failed, cleanup the warm reset vector */
906906
if (ret)

0 commit comments

Comments
 (0)