Skip to content

Commit

Permalink
lib,smp,setup: rewrite write_sp() as macro
Browse files Browse the repository at this point in the history
The write_sp() may not be inlined (esp. when compiled with -O0) and then
it is called to. After stack swap, the function cannot return.
Thus, this should be a macro to make things stay away from stack.

To further simplify things during AP initialization, allocate new stack
frames from BSP and use the new pointer value directly in AP's WRITE_SP.

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>
  • Loading branch information
wipawel committed Feb 9, 2021
1 parent 2516a58 commit c5ddf18
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 7 deletions.
2 changes: 1 addition & 1 deletion common/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ void __noreturn __text_init kernel_start(uint32_t multiboot_magic,
/* Setup final pagetables */
init_pagetables();
write_cr3(cr3.paddr);
write_sp(get_free_pages_top(PAGE_ORDER_2M, GFP_KERNEL));
WRITE_SP(get_free_pages_top(PAGE_ORDER_2M, GFP_KERNEL));
if (opt_debug)
dump_pagetables();

Expand Down
7 changes: 4 additions & 3 deletions include/lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,10 @@ static inline unsigned long read_cr8(void) {
return cr8;
}

static inline void write_sp(void *sp) {
asm volatile("mov %0, %%" STR(_ASM_SP)::"r"(sp) : "memory");
}
#define WRITE_SP(sp) \
do { \
asm volatile("mov %0, %%" STR(_ASM_SP)::"r"((sp)) : "memory"); \
} while (0)

static inline void lgdt(const gdt_ptr_t *gdt_ptr) {
asm volatile("lgdt %0" ::"m"(*gdt_ptr));
Expand Down
8 changes: 5 additions & 3 deletions smp/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ extern void ap_start(void);

static unsigned nr_cpus;

static unsigned ap_cpuid;
static bool ap_callin;
static __data_init unsigned ap_cpuid;
static __data_init bool ap_callin;
static __data_init void *ap_new_sp;
cr3_t __data_init ap_cr3;

void __noreturn __naked ap_startup(void) {
write_sp(get_free_pages_top(PAGE_ORDER_2M, GFP_KERNEL));
WRITE_SP(ap_new_sp);

init_traps(ap_cpuid);
init_apic(ap_cpuid, apic_get_mode());
Expand All @@ -69,6 +70,7 @@ static __text_init void boot_cpu(percpu_t *percpu) {
if (percpu->bsp)
return;

ap_new_sp = get_free_pages_top(PAGE_ORDER_2M, GFP_KERNEL);
ap_cpuid = percpu->cpu_id;
ap_callin = false;
smp_wmb();
Expand Down

0 comments on commit c5ddf18

Please sign in to comment.