summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/amd64/machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64/amd64/machdep.c')
-rw-r--r--sys/arch/amd64/amd64/machdep.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 82fa97b..528326a 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -95,20 +95,36 @@ try_mitigate_spectre(void)
struct cpu_info *
this_cpu(void)
{
- return (void *)amd64_read_gs_base();
+ struct cpu_info *ci;
+
+ /*
+ * This might look crazy but we are just leveraging the "m"
+ * constraint to calculate the offset of the self field within
+ * cpu_info. The self field points to the cpu_info structure
+ * itself allowing us to access cpu_info through %gs.
+ */
+ __ASMV("mov %%gs:%1, %0"
+ : "=r" (ci)
+ : "m" (*&((struct cpu_info *)0)->self)
+ : "memory");
+
+ return ci;
}
void
cpu_startup(struct cpu_info *ci)
{
+ ci->self = ci;
gdt_load(&bsp_gdtr);
idt_load();
setup_vectors();
amd64_write_gs_base((uintptr_t)ci);
- init_tss(ci);
+ __ASMV("swapgs"); /* Get kernel GS */
+ init_tss(ci);
try_mitigate_spectre();
+
__ASMV("sti"); /* Unmask interrupts */
lapic_init();
}