Skip to content

Commit a6428db

Browse files
committed
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 <[email protected]> Signed-off-by: Roman Kisel <[email protected]> Reviewed-by: Tom Lendacky <[email protected]>
1 parent fadeca1 commit a6428db

File tree

9 files changed

+26
-36
lines changed

9 files changed

+26
-36
lines changed

arch/x86/coco/sev/core.c

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

1100-
static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
1100+
static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip, unsigned int cpu)
11011101
{
11021102
struct sev_es_save_area *cur_vmsa, *vmsa;
11031103
struct ghcb_state state;
11041104
struct svsm_ca *caa;
11051105
unsigned long flags;
11061106
struct ghcb *ghcb;
11071107
u8 sipi_vector;
1108-
int cpu, ret;
1108+
int ret;
11091109
u64 cr4;
11101110

11111111
/*
@@ -1126,15 +1126,6 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
11261126

11271127
/* Override start_ip with known protected guest start IP */
11281128
start_ip = real_mode_header->sev_es_trampoline_start;
1129-
1130-
/* Find the logical CPU for the APIC ID */
1131-
for_each_present_cpu(cpu) {
1132-
if (arch_match_cpu_phys_id(cpu, apic_id))
1133-
break;
1134-
}
1135-
if (cpu >= nr_cpu_ids)
1136-
return -EINVAL;
1137-
11381129
cur_vmsa = per_cpu(sev_vmsa, cpu);
11391130

11401131
/*

arch/x86/hyperv/hv_vtl.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -371,17 +371,9 @@ int hv_vtl_apicid_to_vp_id(u32 apic_id)
371371
return ret;
372372
}
373373

374-
static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip)
374+
static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip, unsigned int cpu)
375375
{
376-
int vp_id, cpu;
377-
378-
/* Find the logical CPU for the APIC ID */
379-
for_each_present_cpu(cpu) {
380-
if (arch_match_cpu_phys_id(cpu, apicid))
381-
break;
382-
}
383-
if (cpu >= nr_cpu_ids)
384-
return -EINVAL;
376+
int vp_id;
385377

386378
pr_debug("Bringing up CPU with APIC ID %d in VTL2...\n", apicid);
387379
/*

arch/x86/hyperv/ivm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ enum es_result hv_set_savic_backing_page(u64 gfn)
333333
return ES_VMM_ERROR;
334334
}
335335

336-
int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip)
336+
int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip, unsigned int cpu)
337337
{
338338
struct sev_es_save_area *vmsa = (struct sev_es_save_area *)
339339
__get_free_page(GFP_KERNEL | __GFP_ZERO);

arch/x86/include/asm/apic.h

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

325325
/* wakeup_secondary_cpu */
326-
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip);
326+
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip, unsigned int cpu);
327327
/* wakeup secondary CPU using 64-bit wakeup point */
328-
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip);
328+
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip, unsigned int cpu);
329329

330330
void (*update_vector)(unsigned int cpu, unsigned int vector, bool set);
331331

@@ -345,8 +345,8 @@ struct apic_override {
345345
void (*send_IPI_self)(int vector);
346346
u64 (*icr_read)(void);
347347
void (*icr_write)(u32 low, u32 high);
348-
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip);
349-
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip);
348+
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip, unsigned int cpu);
349+
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip, unsigned int cpu);
350350
};
351351

352352
/*

arch/x86/include/asm/mshyperv.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,13 @@ int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
265265
#ifdef CONFIG_AMD_MEM_ENCRYPT
266266
bool hv_ghcb_negotiate_protocol(void);
267267
void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
268-
int hv_snp_boot_ap(u32 cpu, unsigned long start_ip);
268+
int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip, unsigned int cpu);
269269
enum es_result hv_set_savic_backing_page(u64 gfn);
270270
#else
271271
static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
272272
static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
273-
static inline int hv_snp_boot_ap(u32 cpu, unsigned long start_ip) { return 0; }
273+
static inline int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip,
274+
unsigned int cpu) { return 0; }
274275
#endif
275276

276277
#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
@@ -169,7 +169,7 @@ static int __init acpi_mp_setup_reset(u64 reset_vector)
169169
return 0;
170170
}
171171

172-
static int acpi_wakeup_cpu(u32 apicid, unsigned long start_ip)
172+
static int acpi_wakeup_cpu(u32 apicid, unsigned long start_ip, unsigned int cpu)
173173
{
174174
if (!acpi_mp_wake_mailbox_paddr) {
175175
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/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
@@ -728,7 +728,7 @@ static void send_init_sequence(u32 phys_apicid)
728728
/*
729729
* Wake up AP by INIT, INIT, STARTUP sequence.
730730
*/
731-
static int wakeup_secondary_cpu_via_init(u32 phys_apicid, unsigned long start_eip)
731+
static int wakeup_secondary_cpu_via_init(u32 phys_apicid, unsigned long start_eip, unsigned int cpu)
732732
{
733733
unsigned long send_status = 0, accept_status = 0;
734734
int num_starts, j, maxlvt;
@@ -875,7 +875,7 @@ int common_cpu_up(unsigned int cpu, struct task_struct *idle)
875875
* Returns zero if startup was successfully sent, else error code from
876876
* ->wakeup_secondary_cpu.
877877
*/
878-
static int do_boot_cpu(u32 apicid, int cpu, struct task_struct *idle)
878+
static int do_boot_cpu(u32 apicid, unsigned int cpu, struct task_struct *idle)
879879
{
880880
unsigned long start_ip = real_mode_header->trampoline_start;
881881
int ret;
@@ -929,11 +929,11 @@ static int do_boot_cpu(u32 apicid, int cpu, struct task_struct *idle)
929929
* - Use an INIT boot APIC message
930930
*/
931931
if (apic->wakeup_secondary_cpu_64)
932-
ret = apic->wakeup_secondary_cpu_64(apicid, start_ip);
932+
ret = apic->wakeup_secondary_cpu_64(apicid, start_ip, cpu);
933933
else if (apic->wakeup_secondary_cpu)
934-
ret = apic->wakeup_secondary_cpu(apicid, start_ip);
934+
ret = apic->wakeup_secondary_cpu(apicid, start_ip, cpu);
935935
else
936-
ret = wakeup_secondary_cpu_via_init(apicid, start_ip);
936+
ret = wakeup_secondary_cpu_via_init(apicid, start_ip, cpu);
937937

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

0 commit comments

Comments
 (0)