Date: Sun, 28 Aug 2016 14:03:25 +0000 (UTC) From: Bruce Evans <bde@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r304957 - head/sys/i386/i386 Message-ID: <201608281403.u7SE3POl003757@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bde Date: Sun Aug 28 14:03:25 2016 New Revision: 304957 URL: https://svnweb.freebsd.org/changeset/base/304957 Log: Fix vm86 initialization, part 1 of 2 and a half. vm86 uses the tss, but r273995 moved tss initialization to after where it may be first used, just because tss_esp0 now depends on later initializations and/or amd64 does it later. vm86 is first used for memory sizing in cases where the loader can't figure out the size or is not used. Its initialization is placed immediately before memory sizing to support this, and the tss was initialized a little earlier. Move everything in the tss initialization except for tss_esp0 back to almost where it was, immediately before vm86 initialization (the combined move is from before dblflt_tss initialization to after). Add only early initialization of tss_esp0, later reloading of the tss, and comments. The initial tss_esp0 no longer has space for the pcb since initially the size of the pcb is not known and no pcb is needed. (Later changes broke debugging at this point, so the nonexistent pcb cannot be used by debuggers, and at the time of 273995 when ddb was almost able to debug this problem it didn't need the pcb.) The iniitial tss_esp0 still has a magic 16 bytes reserved for vm86 although I think this is unused too. Modified: head/sys/i386/i386/machdep.c Modified: head/sys/i386/i386/machdep.c ============================================================================== --- head/sys/i386/i386/machdep.c Sun Aug 28 12:05:34 2016 (r304956) +++ head/sys/i386/i386/machdep.c Sun Aug 28 14:03:25 2016 (r304957) @@ -2636,6 +2636,16 @@ init386(first) dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); + /* Initialize the tss (except for the final esp0) early for vm86. */ + PCPU_SET(common_tss.tss_esp0, thread0.td_kstack + + thread0.td_kstack_pages * PAGE_SIZE - 16); + PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL)); + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + PCPU_SET(tss_gdt, &gdt[GPROC0_SEL].sd); + PCPU_SET(common_tssd, *PCPU_GET(tss_gdt)); + PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16); + ltr(gsel_tss); + vm86_initialize(); getmemsize(first); init_param2(physmem); @@ -2701,14 +2711,10 @@ init386(first) } #endif PCPU_SET(curpcb, thread0.td_pcb); - /* make an initial tss so cpu can get interrupt stack on syscall! */ + /* Move esp0 in the tss to its final place. */ /* Note: -16 is so we can grow the trapframe if we came from vm86 */ PCPU_SET(common_tss.tss_esp0, (vm_offset_t)thread0.td_pcb - 16); - PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL)); - gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); - PCPU_SET(tss_gdt, &gdt[GPROC0_SEL].sd); - PCPU_SET(common_tssd, *PCPU_GET(tss_gdt)); - PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16); + gdt[GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; /* clear busy bit */ ltr(gsel_tss); /* make a call gate to reenter kernel with */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608281403.u7SE3POl003757>