summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-09-08 09:55:51 +0000
committerkib <kib@FreeBSD.org>2008-09-08 09:55:51 +0000
commit73306a54357999dd00f201e861f8ee335a59a421 (patch)
treeff24d41fcb09678d0022d5b067619d619eef0193 /sys/amd64
parent396f47bf91101a8165d7d35ae724ad9da9774e33 (diff)
downloadFreeBSD-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.c15
-rw-r--r--sys/amd64/amd64/trap.c3
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];
OpenPOWER on IntegriCloud