Skip site navigation (1)Skip section navigation (2)
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>