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
This commit is contained in:
parent
73306a5435
commit
f444f744fa
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user