diff options
author | kib <kib@FreeBSD.org> | 2008-09-08 09:55:51 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-09-08 09:55:51 +0000 |
commit | 73306a54357999dd00f201e861f8ee335a59a421 (patch) | |
tree | ff24d41fcb09678d0022d5b067619d619eef0193 /sys/amd64 | |
parent | 396f47bf91101a8165d7d35ae724ad9da9774e33 (diff) | |
download | FreeBSD-src-73306a54357999dd00f201e861f8ee335a59a421.zip FreeBSD-src-73306a54357999dd00f201e861f8ee335a59a421.tar.gz |
Provide private per-CPU GDTs on amd64. This is required at least for the
linux CB_GS32BIT to work.
Noted by: nox
Reviewed by: peter
MFC after: 1 week
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/mp_machdep.c | 15 | ||||
-rw-r--r-- | sys/amd64/amd64/trap.c | 3 |
2 files changed, 13 insertions, 5 deletions
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 304deaa..5dc3228 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -436,7 +436,8 @@ init_secondary(void) { struct pcpu *pc; u_int64_t msr, cr0; - int cpu, gsel_tss; + int cpu, gsel_tss, x; + struct region_descriptor ap_gdt; /* Set by the startup code for us to use */ cpu = bootAP; @@ -447,11 +448,17 @@ init_secondary(void) common_tss[cpu].tss_iobase = sizeof(struct amd64tss); common_tss[cpu].tss_ist1 = (long)&doublefault_stack[PAGE_SIZE]; + /* Prepare private GDT */ gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpu]; ssdtosyssd(&gdt_segs[GPROC0_SEL], - (struct system_segment_descriptor *)&gdt[GPROC0_SEL]); - - lgdt(&r_gdt); /* does magic intra-segment return */ + (struct system_segment_descriptor *)&gdt[NGDT * cpu + GPROC0_SEL]); + for (x = 0; x < NGDT; x++) { + if (x != GPROC0_SEL && x != (GPROC0_SEL + 1)) + ssdtosd(&gdt_segs[x], &gdt[NGDT * cpu + x]); + } + ap_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + ap_gdt.rd_base = (long) &gdt[NGDT * cpu]; + lgdt(&ap_gdt); /* does magic intra-segment return */ /* Get per-cpu data */ pc = &__pcpu[cpu]; diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 00e596f..8d710cd 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -692,7 +692,8 @@ trap_fatal(frame, eva) code = frame->tf_err; type = frame->tf_trapno; - sdtossd(&gdt[IDXSEL(frame->tf_cs & 0xffff)], &softseg); + sdtossd(&gdt[NGDT * PCPU_GET(cpuid) + IDXSEL(frame->tf_cs & 0xffff)], + &softseg); if (type <= MAX_TRAP_MSG) msg = trap_msg[type]; |