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
This commit is contained in:
parent
cf8b104f04
commit
a7af4a3e7d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=354646
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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 cache line");
|
||||
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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -855,7 +855,7 @@ fasttrap_do_seg(fasttrap_tracepoint_t *tp, struct reg *rp, uintptr_t *addr)
|
||||
#ifdef __i386__
|
||||
desc = &gdt[ndx].sd;
|
||||
#else
|
||||
desc = &gdt[ndx];
|
||||
desc = PCPU_PTR(gdt)[ndx];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user