Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Nov 2019 15:51:47 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354646 - in head/sys: amd64/amd64 amd64/include amd64/vmm cddl/contrib/opensolaris/uts/intel/dtrace
Message-ID:  <201911121551.xACFplgQ008943@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Tue Nov 12 15:51:47 2019
New Revision: 354646
URL: https://svnweb.freebsd.org/changeset/base/354646

Log:
  amd64: move GDT into PCPU area.
  
  Reviewed by:	jhb, markj
  Tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week
  Differential revision:	https://reviews.freebsd.org/D22302

Modified:
  head/sys/amd64/amd64/machdep.c
  head/sys/amd64/amd64/mp_machdep.c
  head/sys/amd64/amd64/pmap.c
  head/sys/amd64/amd64/trap.c
  head/sys/amd64/include/pcpu.h
  head/sys/amd64/include/segments.h
  head/sys/amd64/vmm/vmm_host.h
  head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c

Modified: head/sys/amd64/amd64/machdep.c
==============================================================================
--- head/sys/amd64/amd64/machdep.c	Tue Nov 12 15:50:30 2019	(r354645)
+++ head/sys/amd64/amd64/machdep.c	Tue Nov 12 15:51:47 2019	(r354646)
@@ -658,8 +658,6 @@ cpu_setregs(void)
 /*
  * Initialize segments & interrupt table
  */
-
-struct user_segment_descriptor gdt[NGDT * MAXCPU];/* global descriptor tables */
 static struct gate_descriptor idt0[NIDT];
 struct gate_descriptor *idt = &idt0[0];	/* interrupt descriptor table */
 
@@ -1546,8 +1544,10 @@ amd64_conf_fast_syscall(void)
 void
 amd64_bsp_pcpu_init1(struct pcpu *pc)
 {
+	struct user_segment_descriptor *gdt;
 
 	PCPU_SET(prvspace, pc);
+	gdt = *PCPU_PTR(gdt);
 	PCPU_SET(curthread, &thread0);
 	PCPU_SET(tssp, PCPU_PTR(common_tss));
 	PCPU_SET(tss, (struct system_segment_descriptor *)&gdt[GPROC0_SEL]);
@@ -1610,6 +1610,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
 	struct xstate_hdr *xhdr;
 	u_int64_t rsp0;
 	char *env;
+	struct user_segment_descriptor *gdt;
 	struct region_descriptor r_gdt;
 	size_t kstack0_sz;
 	int late_console;
@@ -1667,6 +1668,8 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
 	pmap_thread_init_invl_gen(&thread0);
 
 	pc = &temp_bsp_pcpu;
+	pcpu_init(pc, 0, sizeof(struct pcpu));
+	gdt = &temp_bsp_pcpu.pc_gdt[0];
 
 	/*
 	 * make gdt memory segments
@@ -1681,14 +1684,13 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
 	    (struct system_segment_descriptor *)&gdt[GPROC0_SEL]);
 
 	r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
-	r_gdt.rd_base =  (long) gdt;
+	r_gdt.rd_base = (long)gdt;
 	lgdt(&r_gdt);
 
 	wrmsr(MSR_FSBASE, 0);		/* User value */
 	wrmsr(MSR_GSBASE, (u_int64_t)pc);
 	wrmsr(MSR_KGSBASE, 0);		/* User value while in the kernel */
 
-	pcpu_init(pc, 0, sizeof(struct pcpu));
 	dpcpu_init((void *)(physfree + KERNBASE), 0);
 	physfree += DPCPU_SIZE;
 	amd64_bsp_pcpu_init1(pc);

Modified: head/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- head/sys/amd64/amd64/mp_machdep.c	Tue Nov 12 15:50:30 2019	(r354645)
+++ head/sys/amd64/amd64/mp_machdep.c	Tue Nov 12 15:51:47 2019	(r354646)
@@ -275,9 +275,10 @@ init_secondary(void)
 {
 	struct pcpu *pc;
 	struct nmi_pcpu *np;
+	struct user_segment_descriptor *gdt;
+	struct region_descriptor ap_gdt;
 	u_int64_t cr0;
 	int cpu, gsel_tss, x;
-	struct region_descriptor ap_gdt;
 
 	/* Set by the startup code for us to use */
 	cpu = bootAP;
@@ -298,12 +299,11 @@ init_secondary(void)
 	pc->pc_rsp0 = 0;
 	pc->pc_pti_rsp0 = (((vm_offset_t)&pc->pc_pti_stack +
 	    PC_PTI_STACK_SZ * sizeof(uint64_t)) & ~0xful);
-	pc->pc_tss = (struct system_segment_descriptor *)&gdt[NGDT * cpu +
-	    GPROC0_SEL];
-	pc->pc_fs32p = &gdt[NGDT * cpu + GUFS32_SEL];
-	pc->pc_gs32p = &gdt[NGDT * cpu + GUGS32_SEL];
-	pc->pc_ldt = (struct system_segment_descriptor *)&gdt[NGDT * cpu +
-	    GUSERLDT_SEL];
+	gdt = pc->pc_gdt;
+	pc->pc_tss = (struct system_segment_descriptor *)&gdt[GPROC0_SEL];
+	pc->pc_fs32p = &gdt[GUFS32_SEL];
+	pc->pc_gs32p = &gdt[GUGS32_SEL];
+	pc->pc_ldt = (struct system_segment_descriptor *)&gdt[GUSERLDT_SEL];
 	/* See comment in pmap_bootstrap(). */
 	pc->pc_pcid_next = PMAP_PCID_KERN + 2;
 	pc->pc_pcid_gen = 1;
@@ -331,14 +331,14 @@ init_secondary(void)
 	/* Prepare private GDT */
 	gdt_segs[GPROC0_SEL].ssd_base = (long)&pc->pc_common_tss;
 	for (x = 0; x < NGDT; x++) {
-		if (x != GPROC0_SEL && x != (GPROC0_SEL + 1) &&
-		    x != GUSERLDT_SEL && x != (GUSERLDT_SEL + 1))
-			ssdtosd(&gdt_segs[x], &gdt[NGDT * cpu + x]);
+		if (x != GPROC0_SEL && x != GPROC0_SEL + 1 &&
+		    x != GUSERLDT_SEL && x != GUSERLDT_SEL + 1)
+			ssdtosd(&gdt_segs[x], &gdt[x]);
 	}
 	ssdtosyssd(&gdt_segs[GPROC0_SEL],
-	    (struct system_segment_descriptor *)&gdt[NGDT * cpu + GPROC0_SEL]);
+	    (struct system_segment_descriptor *)&gdt[GPROC0_SEL]);
 	ap_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
-	ap_gdt.rd_base = (u_long)&gdt[NGDT * cpu];
+	ap_gdt.rd_base = (u_long)gdt;
 	lgdt(&ap_gdt);			/* does magic intra-segment return */
 
 	/* Save the per-cpu pointer for use by the NMI handler. */

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c	Tue Nov 12 15:50:30 2019	(r354645)
+++ head/sys/amd64/amd64/pmap.c	Tue Nov 12 15:51:47 2019	(r354646)
@@ -1669,6 +1669,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
 {
 	vm_offset_t va;
 	pt_entry_t *pte, *pcpu_pte;
+	struct region_descriptor r_gdt;
 	uint64_t cr4, pcpu_phys;
 	u_long res;
 	int i;
@@ -1760,14 +1761,25 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
 		pcpu_pte[i] = (pcpu_phys + ptoa(i)) | X86_PG_V | X86_PG_RW |
 		    pg_g | pg_nx | X86_PG_M | X86_PG_A;
 	}
+
+	/*
+	 * Re-initialize PCPU area for BSP after switching.
+	 * Make hardware use gdt and common_tss from the new PCPU.
+	 */
 	STAILQ_INIT(&cpuhead);
 	wrmsr(MSR_GSBASE, (uint64_t)&__pcpu[0]);
 	pcpu_init(&__pcpu[0], 0, sizeof(struct pcpu));
 	amd64_bsp_pcpu_init1(&__pcpu[0]);
 	amd64_bsp_ist_init(&__pcpu[0]);
+	memcpy(__pcpu[0].pc_gdt, temp_bsp_pcpu.pc_gdt, NGDT *
+	    sizeof(struct user_segment_descriptor));
 	gdt_segs[GPROC0_SEL].ssd_base = (uintptr_t)&__pcpu[0].pc_common_tss;
 	ssdtosyssd(&gdt_segs[GPROC0_SEL],
-	    (struct system_segment_descriptor *)&gdt[GPROC0_SEL]);
+	    (struct system_segment_descriptor *)&__pcpu[0].pc_gdt[GPROC0_SEL]);
+	r_gdt.rd_limit = NGDT * sizeof(struct user_segment_descriptor) - 1;
+	r_gdt.rd_base = (long)__pcpu[0].pc_gdt;
+	lgdt(&r_gdt);
+	wrmsr(MSR_GSBASE, (uint64_t)&__pcpu[0]);
 	ltr(GSEL(GPROC0_SEL, SEL_KPL));
 	__pcpu[0].pc_dynamic = temp_bsp_pcpu.pc_dynamic;
 	__pcpu[0].pc_acpi_id = temp_bsp_pcpu.pc_acpi_id;
@@ -9722,8 +9734,6 @@ pmap_pti_init(void)
 	}
 	pmap_pti_add_kva_locked((vm_offset_t)&__pcpu[0],
 	    (vm_offset_t)&__pcpu[0] + sizeof(__pcpu[0]) * MAXCPU, false);
-	pmap_pti_add_kva_locked((vm_offset_t)gdt, (vm_offset_t)gdt +
-	    sizeof(struct user_segment_descriptor) * NGDT * MAXCPU, false);
 	pmap_pti_add_kva_locked((vm_offset_t)idt, (vm_offset_t)idt +
 	    sizeof(struct gate_descriptor) * NIDT, false);
 	CPU_FOREACH(i) {

Modified: head/sys/amd64/amd64/trap.c
==============================================================================
--- head/sys/amd64/amd64/trap.c	Tue Nov 12 15:50:30 2019	(r354645)
+++ head/sys/amd64/amd64/trap.c	Tue Nov 12 15:51:47 2019	(r354646)
@@ -861,14 +861,15 @@ trap_fatal(frame, eva)
 	int code, ss;
 	u_int type;
 	struct soft_segment_descriptor softseg;
+	struct user_segment_descriptor *gdt;
 #ifdef KDB
 	bool handled;
 #endif
 
 	code = frame->tf_err;
 	type = frame->tf_trapno;
-	sdtossd(&gdt[NGDT * PCPU_GET(cpuid) + IDXSEL(frame->tf_cs & 0xffff)],
-	    &softseg);
+	gdt = *PCPU_PTR(gdt);
+	sdtossd(&gdt[IDXSEL(frame->tf_cs & 0xffff)], &softseg);
 
 	printf("\n\nFatal trap %d: %s while in %s mode\n", type,
 	    type < nitems(trap_msg) ? trap_msg[type] : UNKNOWN,

Modified: head/sys/amd64/include/pcpu.h
==============================================================================
--- head/sys/amd64/include/pcpu.h	Tue Nov 12 15:50:30 2019	(r354645)
+++ head/sys/amd64/include/pcpu.h	Tue Nov 12 15:51:47 2019	(r354646)
@@ -35,6 +35,7 @@
 #error "sys/cdefs.h is a prerequisite for this file"
 #endif
 
+#include <machine/segments.h>
 #include <machine/tss.h>
 
 #define	PC_PTI_STACK_SZ	16
@@ -92,7 +93,8 @@ _Static_assert(sizeof(struct monitorbuf) == 128, "2x c
 	uint8_t	pc_mds_tmp[64];						\
 	u_int 	pc_ipi_bitmap;						\
 	struct amd64tss pc_common_tss;					\
-	char	__pad[3068]		/* pad to UMA_PCPU_ALLOC_SIZE */
+	struct user_segment_descriptor pc_gdt[NGDT];			\
+	char	__pad[2956]		/* pad to UMA_PCPU_ALLOC_SIZE */
 
 #define	PC_DBREG_CMD_NONE	0
 #define	PC_DBREG_CMD_LOAD	1

Modified: head/sys/amd64/include/segments.h
==============================================================================
--- head/sys/amd64/include/segments.h	Tue Nov 12 15:50:30 2019	(r354645)
+++ head/sys/amd64/include/segments.h	Tue Nov 12 15:51:47 2019	(r354646)
@@ -89,7 +89,6 @@ struct region_descriptor {
 } __packed;
 
 #ifdef _KERNEL
-extern struct user_segment_descriptor gdt[];
 extern struct soft_segment_descriptor gdt_segs[];
 extern struct gate_descriptor *idt;
 extern struct region_descriptor r_idt;

Modified: head/sys/amd64/vmm/vmm_host.h
==============================================================================
--- head/sys/amd64/vmm/vmm_host.h	Tue Nov 12 15:50:30 2019	(r354645)
+++ head/sys/amd64/vmm/vmm_host.h	Tue Nov 12 15:51:47 2019	(r354646)
@@ -69,7 +69,7 @@ static __inline uint64_t
 vmm_get_host_gdtrbase(void)
 {
 
-	return ((uint64_t)&gdt[NGDT * curcpu]);
+	return ((uint64_t)*PCPU_PTR(gdt));
 }
 
 static __inline uint64_t

Modified: head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c	Tue Nov 12 15:50:30 2019	(r354645)
+++ head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c	Tue Nov 12 15:51:47 2019	(r354646)
@@ -855,7 +855,7 @@ fasttrap_do_seg(fasttrap_tracepoint_t *tp, struct reg 
 #ifdef __i386__
 		desc = &gdt[ndx].sd;
 #else
-		desc = &gdt[ndx];
+		desc = PCPU_PTR(gdt)[ndx];
 #endif
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911121551.xACFplgQ008943>