From a7ca32e3a3ec2d3c1947a06fbcde0f779b0b1fec Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Tue, 9 Oct 2018 20:22:48 -0400 Subject: [PATCH] Change mycpu() to use %gs. --- defs.h | 1 + main.c | 2 ++ proc.c | 16 ++++++++++++---- proc.h | 1 + vm.c | 7 +++++-- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/defs.h b/defs.h index 763eb75..3735f6f 100644 --- a/defs.h +++ b/defs.h @@ -110,6 +110,7 @@ int fork(void); int growproc(int); int kill(int); struct cpu* mycpu(void); +struct cpu* getmycpu(void); struct proc* myproc(); void pinit(void); void procdump(void); diff --git a/main.c b/main.c index a900e9d..3127b15 100644 --- a/main.c +++ b/main.c @@ -45,6 +45,8 @@ main(uint64 mbmagic, uint64 mbaddr) return 0; } +extern struct cpu* getmycpu(); + // Common CPU setup code. static void mpmain(void) diff --git a/proc.c b/proc.c index 55e435c..3c0acbd 100644 --- a/proc.c +++ b/proc.c @@ -37,16 +37,15 @@ cpuid() { // Must be called with interrupts disabled to avoid the caller being // rescheduled between reading lapicid and running through the loop. struct cpu* -mycpu(void) +getmycpu(void) { int apicid, i; if(readeflags()&FL_IF) - panic("mycpu called with interrupts enabled\n"); + panic("getmycpu called with interrupts enabled\n"); apicid = lapicid(); - // APIC IDs are not guaranteed to be contiguous. Maybe we should have - // a reverse map, or reserve a register to store &cpus[i]. + // APIC IDs are not guaranteed to be contiguous. for (i = 0; i < ncpu; ++i) { if (cpus[i].apicid == apicid) return &cpus[i]; @@ -54,6 +53,15 @@ mycpu(void) panic("unknown apicid\n"); } +// Return this core's cpu struct using %gs. %gs points this core's struct +// cpu. Offet 24 in struct cpu is cpu. +struct cpu* +mycpu(void) { + struct cpu *c; + asm volatile("mov %%gs:24, %0" : "=r" (c)); + return c; +} + // Disable interrupts so that we are not rescheduled // while reading proc from the cpu structure struct proc* diff --git a/proc.h b/proc.h index 9261766..0b01b75 100644 --- a/proc.h +++ b/proc.h @@ -3,6 +3,7 @@ struct cpu { uint64 syscallno; // Temporary used by sysentry uint64 usp; // Temporary used by sysentry struct proc *proc; // The process running on this cpu or null + struct cpu *cpu; // XXX uchar apicid; // Local APIC ID struct context *scheduler; // swtch() here to enter scheduler struct taskstate ts; // Used by x86 to find stack for interrupt diff --git a/vm.c b/vm.c index ebb6749..c0276a1 100644 --- a/vm.c +++ b/vm.c @@ -39,7 +39,8 @@ seginit(void) struct cpu *c; struct desctr dtr; - c = mycpu(); + c = getmycpu(); + memmove(c->gdt, bootgdt, sizeof bootgdt); dtr.limit = sizeof(c->gdt)-1; dtr.base = (uint64) c->gdt; @@ -54,10 +55,12 @@ seginit(void) writemsr(MSR_LSTAR, (uint64)&sysentry); writemsr(MSR_SFMASK, FL_TF | FL_IF); - // Initialize cpu-local storage. + // Initialize cpu-local storage so that each core can easily + // find its struct cpu using %gs. writegs(SEG_KDATA); writemsr(MSR_GS_BASE, (uint64)c); writemsr(MSR_GS_KERNBASE, (uint64)c); + c->cpu = c; } // Return the address of the PTE in page table pgdir