diff options
author | kib <kib@FreeBSD.org> | 2008-09-08 09:59:05 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-09-08 09:59:05 +0000 |
commit | f444f744fafc9bc80a33a896317d5b48cbaf83da (patch) | |
tree | a308fa38f71a058e176d9756194177e9afdf880e | |
parent | 73306a54357999dd00f201e861f8ee335a59a421 (diff) | |
download | FreeBSD-src-f444f744fafc9bc80a33a896317d5b48cbaf83da.zip FreeBSD-src-f444f744fafc9bc80a33a896317d5b48cbaf83da.tar.gz |
The pcb_gs32p should be per-cpu, not per-thread pointer. This is
location in GDT where the segment descriptor from pcb_gs32sd is
copied, and the location is in GDT local to CPU.
Noted and reviewed by: peter
MFC after: 1 week
-rw-r--r-- | sys/amd64/amd64/cpu_switch.S | 4 | ||||
-rw-r--r-- | sys/amd64/amd64/genassym.c | 2 | ||||
-rw-r--r-- | sys/amd64/amd64/machdep.c | 1 | ||||
-rw-r--r-- | sys/amd64/amd64/mp_machdep.c | 1 | ||||
-rw-r--r-- | sys/amd64/include/pcb.h | 1 | ||||
-rw-r--r-- | sys/amd64/include/pcpu.h | 3 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_machdep.c | 4 |
7 files changed, 8 insertions, 8 deletions
diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S index a0b11f8..99d6716 100644 --- a/sys/amd64/amd64/cpu_switch.S +++ b/sys/amd64/amd64/cpu_switch.S @@ -266,7 +266,7 @@ store_seg: movl %es,PCB_ES(%r8) movl %fs,PCB_FS(%r8) jmp done_store_seg -2: movq PCB_GS32P(%r8),%rax +2: movq PCPU(GS32P),%rax movq (%rax),%rax movq %rax,PCB_GS32SD(%r8) jmp 1b @@ -283,7 +283,7 @@ load_seg: movl PCB_FS(%r8),%fs jmp done_load_seg /* Restore userland %gs while preserving kernel gsbase */ -2: movq PCB_GS32P(%r8),%rax +2: movq PCPU(GS32P),%rax movq PCB_GS32SD(%r8),%rcx movq %rcx,(%rax) jmp 1b diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index fec0380..f749dd6 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -147,7 +147,6 @@ ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags)); ASSYM(PCB_SAVEFPU, offsetof(struct pcb, pcb_save)); ASSYM(PCB_SAVEFPU_SIZE, sizeof(struct savefpu)); ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault)); -ASSYM(PCB_GS32P, offsetof(struct pcb, pcb_gs32p)); ASSYM(PCB_GS32SD, offsetof(struct pcb, pcb_gs32sd)); ASSYM(PCB_SIZE, sizeof(struct pcb)); @@ -199,6 +198,7 @@ ASSYM(PC_SCRATCH_RSP, offsetof(struct pcpu, pc_scratch_rsp)); ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap)); ASSYM(PC_TSSP, offsetof(struct pcpu, pc_tssp)); ASSYM(PC_RSP0, offsetof(struct pcpu, pc_rsp0)); +ASSYM(PC_GS32P, offsetof(struct pcpu, pc_gs32p)); ASSYM(LA_VER, offsetof(struct LAPIC, version)); ASSYM(LA_TPR, offsetof(struct LAPIC, tpr)); diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 2280ee9..988b039 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1347,6 +1347,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) PCPU_SET(curthread, &thread0); PCPU_SET(curpcb, thread0.td_pcb); PCPU_SET(tssp, &common_tss[0]); + PCPU_SET(gs32p, &gdt[GUGS32_SEL]); /* * Initialize mutexes. diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 5dc3228..2de63e3 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -470,6 +470,7 @@ init_secondary(void) pc->pc_curthread = 0; pc->pc_tssp = &common_tss[cpu]; pc->pc_rsp0 = 0; + pc->pc_gs32p = &gdt[NGDT * cpu + GUGS32_SEL]; wrmsr(MSR_FSBASE, 0); /* User value */ wrmsr(MSR_GSBASE, (u_int64_t)pc); diff --git a/sys/amd64/include/pcb.h b/sys/amd64/include/pcb.h index 647d5c9..43b59e5 100644 --- a/sys/amd64/include/pcb.h +++ b/sys/amd64/include/pcb.h @@ -77,7 +77,6 @@ struct pcb { caddr_t pcb_onfault; /* copyin/out fault recovery */ /* 32-bit segment descriptor */ - struct user_segment_descriptor *pcb_gs32p; struct user_segment_descriptor pcb_gs32sd; }; diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h index fe811c5..e9faf28 100644 --- a/sys/amd64/include/pcpu.h +++ b/sys/amd64/include/pcpu.h @@ -48,7 +48,8 @@ register_t pc_rsp0; \ register_t pc_scratch_rsp; /* User %rsp in syscall */ \ u_int pc_apic_id; \ - u_int pc_acpi_id /* ACPI CPU id */ + u_int pc_acpi_id; /* ACPI CPU id */ \ + struct user_segment_descriptor *pc_gs32p #ifdef _KERNEL diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c index ceba561..aecf869 100644 --- a/sys/amd64/linux32/linux32_machdep.c +++ b/sys/amd64/linux32/linux32_machdep.c @@ -694,7 +694,6 @@ linux_clone(struct thread *td, struct linux_clone_args *args) #endif td2->td_pcb->pcb_gsbase = (register_t)info.base_addr; td2->td_pcb->pcb_gs32sd = sd; - td2->td_pcb->pcb_gs32p = &gdt[GUGS32_SEL]; td2->td_pcb->pcb_gs = GSEL(GUGS32_SEL, SEL_UPL); td2->td_pcb->pcb_flags |= PCB_GS32BIT | PCB_32BIT; } @@ -1352,8 +1351,7 @@ linux_set_thread_area(struct thread *td, critical_enter(); td->td_pcb->pcb_gsbase = (register_t)info.base_addr; - td->td_pcb->pcb_gs32sd = gdt[GUGS32_SEL] = sd; - td->td_pcb->pcb_gs32p = &gdt[GUGS32_SEL]; + td->td_pcb->pcb_gs32sd = *PCPU_GET(gs32p) = sd; td->td_pcb->pcb_flags |= PCB_32BIT | PCB_GS32BIT; wrmsr(MSR_KGSBASE, td->td_pcb->pcb_gsbase); critical_exit(); |