diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2018-03-22 19:30:20 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2018-03-22 19:30:20 +0000 |
commit | 5daa18171355d61be45fde9ab05a8ee7f6f53aa1 (patch) | |
tree | 1f57f797ed77a1c7c07f3a7f2ebf9e5b993aec90 | |
parent | 2dd9151fd7b66c8bb8b2f397d5bcad4fb1943f72 (diff) |
iBackout the preparations for fixing Meltdown on i386. The task was
only halfway done and the current state does not help anybody. For
OpenBSD 6.3 release go back to the original code before 2018/03/13.
This gives us a stable release and the changes will come back later.
discussed with guenther@ deraadt@ hshoexer@
26 files changed, 305 insertions, 195 deletions
diff --git a/sys/arch/i386/i386/acpi_machdep.c b/sys/arch/i386/i386/acpi_machdep.c index e1d7f869e5d..b2e25d417a9 100644 --- a/sys/arch/i386/i386/acpi_machdep.c +++ b/sys/arch/i386/i386/acpi_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_machdep.c,v 1.63 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: acpi_machdep.c,v 1.64 2018/03/22 19:30:18 bluhm Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * @@ -448,7 +448,7 @@ acpi_resume_mp(void) p = ci->ci_schedstate.spc_idleproc; pcb = &p->p_addr->u_pcb; - tf = (struct trapframe *)pcb->pcb_kstack - 1; + tf = (struct trapframe *)pcb->pcb_tss.tss_esp0 - 1; sf = (struct switchframe *)tf - 1; sf->sf_esi = (int)sched_idle; sf->sf_ebx = (int)ci; diff --git a/sys/arch/i386/i386/amd64errata.c b/sys/arch/i386/i386/amd64errata.c index e4491001f2d..9c9ba132af6 100644 --- a/sys/arch/i386/i386/amd64errata.c +++ b/sys/arch/i386/i386/amd64errata.c @@ -1,4 +1,4 @@ -/* $OpenBSD: amd64errata.c,v 1.9 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: amd64errata.c,v 1.10 2018/03/22 19:30:18 bluhm Exp $ */ /* $NetBSD: errata.c,v 1.6 2007/02/05 21:05:45 ad Exp $ */ /*- @@ -332,7 +332,7 @@ amd64_errata(struct cpu_info *ci) #ifdef ERRATA_DEBUG printf("%s: testing for erratum %d\n", - ci->ci_dev->dv_xname, e->e_num); + ci->ci_dev.dv_xname, e->e_num); #endif /* @@ -363,7 +363,7 @@ amd64_errata(struct cpu_info *ci) int first = 1; /* Print out found and corrected */ - printf("%s: AMD %s", ci->ci_dev->dv_xname, + printf("%s: AMD %s", ci->ci_dev.dv_xname, (corrected == 1) ? "erratum" : "errata"); for (e = errata; e < ex; e++) { if (e->e_reported == 2) { @@ -381,7 +381,7 @@ amd64_errata(struct cpu_info *ci) int first = 1; /* Print out found but not corrected */ - printf("%s: AMD %s", ci->ci_dev->dv_xname, + printf("%s: AMD %s", ci->ci_dev.dv_xname, (found == 1) ? "erratum" : "errata"); for (e = errata; e < ex; e++) { if (e->e_reported == 1) { diff --git a/sys/arch/i386/i386/cpu.c b/sys/arch/i386/i386/cpu.c index 9a65141960a..07937b4b1be 100644 --- a/sys/arch/i386/i386/cpu.c +++ b/sys/arch/i386/i386/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.86 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: cpu.c,v 1.87 2018/03/22 19:30:18 bluhm Exp $ */ /* $NetBSD: cpu.c,v 1.1.2.7 2000/06/26 02:04:05 sommerfeld Exp $ */ /*- @@ -113,14 +113,12 @@ #include <i386/isa/nvram.h> #include <dev/isa/isareg.h> -struct cpu_softc; - int cpu_match(struct device *, void *, void *); void cpu_attach(struct device *, struct device *, void *); int cpu_activate(struct device *, int); void patinit(struct cpu_info *ci); void cpu_idle_mwait_cycle(void); -void cpu_init_mwait(struct cpu_softc *); +void cpu_init_mwait(struct device *); #if NVMM > 0 void cpu_init_vmm(struct cpu_info *ci); #endif /* NVMM > 0 */ @@ -142,6 +140,9 @@ struct cpu_functions mp_cpu_funcs = struct cpu_info cpu_info_primary; struct cpu_info *cpu_info_list = &cpu_info_primary; +void cpu_init_tss(struct i386tss *, void *, void *); +void cpu_set_tss_gates(struct cpu_info *); + #ifdef MULTIPROCESSOR /* * Array of CPU info structures. Must be statically-allocated because @@ -166,13 +167,8 @@ cpu_init_first(void) } #endif -struct cpu_softc { - struct device sc_dev; - struct cpu_info *sc_info; -}; - struct cfattach cpu_ca = { - sizeof(struct cpu_softc), cpu_match, cpu_attach, NULL, cpu_activate + sizeof(struct cpu_info), cpu_match, cpu_attach, NULL, cpu_activate }; struct cfdriver cpu_cd = { @@ -222,18 +218,16 @@ cpu_match(struct device *parent, void *match, void *aux) void cpu_attach(struct device *parent, struct device *self, void *aux) { - struct cpu_softc *sc = (void *)self; + struct cpu_info *ci = (struct cpu_info *)self; struct cpu_attach_args *caa = (struct cpu_attach_args *)aux; - struct cpu_info *ci; #ifdef MULTIPROCESSOR - int cpunum = sc->sc_dev.dv_unit; + int cpunum = ci->ci_dev.dv_unit; vaddr_t kstack; struct pcb *pcb; #endif if (caa->cpu_role == CPU_ROLE_AP) { - ci = malloc(sizeof(*ci), M_DEVBUF, M_WAITOK|M_ZERO); #ifdef MULTIPROCESSOR if (cpu_info[cpunum] != NULL) panic("cpu at apic id %d already attached?", cpunum); @@ -245,14 +239,13 @@ cpu_attach(struct device *parent, struct device *self, void *aux) if (caa->cpu_apicid != lapic_cpu_number()) { panic("%s: running cpu is at apic %d" " instead of at expected %d", - sc->sc_dev.dv_xname, lapic_cpu_number(), caa->cpu_apicid); + self->dv_xname, lapic_cpu_number(), caa->cpu_apicid); } #endif + bcopy(self, &ci->ci_dev, sizeof *self); } ci->ci_self = ci; - sc->sc_info = ci; - ci->ci_dev = self; ci->ci_apicid = caa->cpu_apicid; ci->ci_acpi_proc_id = caa->cpu_acpi_proc_id; #ifdef MULTIPROCESSOR @@ -276,14 +269,17 @@ cpu_attach(struct device *parent, struct device *self, void *aux) " primary"); } printf("%s: unable to allocate idle stack\n", - sc->sc_dev.dv_xname); + ci->ci_dev.dv_xname); return; } pcb = ci->ci_idle_pcb = (struct pcb *)kstack; memset(pcb, 0, USPACE); - pcb->pcb_kstack = kstack + USPACE - 16 - sizeof (struct trapframe); - pcb->pcb_esp = pcb->pcb_ebp = pcb->pcb_kstack; + pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + pcb->pcb_tss.tss_esp0 = kstack + USPACE - 16 - + sizeof (struct trapframe); + pcb->pcb_tss.tss_esp = kstack + USPACE - 16 - + sizeof (struct trapframe); pcb->pcb_pmap = pmap_kernel(); pcb->pcb_cr3 = pcb->pcb_pmap->pm_pdirpa; #endif @@ -302,7 +298,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux) mem_range_attach(); #endif cpu_init(ci); - cpu_init_mwait(sc); + cpu_init_mwait(&ci->ci_dev); break; case CPU_ROLE_BP: @@ -324,7 +320,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux) #if NIOAPIC > 0 ioapic_bsp_id = caa->cpu_apicid; #endif - cpu_init_mwait(sc); + cpu_init_mwait(&ci->ci_dev); break; case CPU_ROLE_AP: @@ -351,9 +347,9 @@ cpu_attach(struct device *parent, struct device *self, void *aux) #ifdef MULTIPROCESSOR if (mp_verbose) { printf("%s: kstack at 0x%lx for %d bytes\n", - ci->ci_dev->dv_xname, kstack, USPACE); + ci->ci_dev.dv_xname, kstack, USPACE); printf("%s: idle pcb at %p, idle sp at 0x%x\n", - ci->ci_dev->dv_xname, pcb, pcb->pcb_esp); + ci->ci_dev.dv_xname, pcb, pcb->pcb_esp); } #endif @@ -584,7 +580,7 @@ cpu_boot_secondary(struct cpu_info *ci) struct pmap *kpm = pmap_kernel(); if (mp_verbose) - printf("%s: starting", ci->ci_dev->dv_xname); + printf("%s: starting", ci->ci_dev.dv_xname); /* XXX move elsewhere, not per CPU. */ mp_pdirpa = kpm->pm_pdirpa; @@ -603,7 +599,7 @@ cpu_boot_secondary(struct cpu_info *ci) delay(10); } if (!(ci->ci_flags & CPUF_RUNNING)) { - printf("%s failed to become ready\n", ci->ci_dev->dv_xname); + printf("%s failed to become ready\n", ci->ci_dev.dv_xname); #ifdef DDB db_enter(); #endif @@ -648,7 +644,7 @@ cpu_hatch(void *v) enable_intr(); if (mp_verbose) printf("%s: CPU at apid %ld running\n", - ci->ci_dev->dv_xname, ci->ci_cpuid); + ci->ci_dev.dv_xname, ci->ci_cpuid); nanouptime(&ci->ci_schedstate.spc_runtime); splx(s); @@ -678,6 +674,69 @@ cpu_copy_trampoline(void) #endif +#ifdef notyet +void +cpu_init_tss(struct i386tss *tss, void *stack, void *func) +{ + memset(tss, 0, sizeof *tss); + tss->tss_esp0 = tss->tss_esp = (int)((char *)stack + USPACE - 16); + tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + tss->__tss_cs = GSEL(GCODE_SEL, SEL_KPL); + tss->tss_fs = GSEL(GCPU_SEL, SEL_KPL); + tss->tss_gs = tss->__tss_es = tss->__tss_ds = + tss->__tss_ss = GSEL(GDATA_SEL, SEL_KPL); + tss->tss_cr3 = pmap_kernel()->pm_pdirpa; + tss->tss_esp = (int)((char *)stack + USPACE - 16); + tss->tss_ldt = 0; + tss->__tss_eflags = PSL_MBO | PSL_NT; /* XXX not needed? */ + tss->__tss_eip = (int)func; +} + +/* XXX */ +#define IDTVEC(name) __CONCAT(X, name) +typedef void (vector)(void); +extern vector IDTVEC(tss_trap08); +#ifdef DDB +extern vector Xintrddbipi; +extern int ddb_vec; +#endif + +void +cpu_set_tss_gates(struct cpu_info *ci) +{ + struct segment_descriptor sd; + + ci->ci_doubleflt_stack = (char *)uvm_km_alloc(kernel_map, USPACE); + cpu_init_tss(&ci->ci_doubleflt_tss, ci->ci_doubleflt_stack, + IDTVEC(tss_trap08)); + setsegment(&sd, &ci->ci_doubleflt_tss, sizeof(struct i386tss) - 1, + SDT_SYS386TSS, SEL_KPL, 0, 0); + ci->ci_gdt[GTRAPTSS_SEL].sd = sd; + setgate(&idt[8], NULL, 0, SDT_SYSTASKGT, SEL_KPL, + GSEL(GTRAPTSS_SEL, SEL_KPL)); + +#if defined(DDB) && defined(MULTIPROCESSOR) + /* + * Set up separate handler for the DDB IPI, so that it doesn't + * stomp on a possibly corrupted stack. + * + * XXX overwriting the gate set in db_machine_init. + * Should rearrange the code so that it's set only once. + */ + ci->ci_ddbipi_stack = (char *)uvm_km_alloc(kernel_map, USPACE); + cpu_init_tss(&ci->ci_ddbipi_tss, ci->ci_ddbipi_stack, + Xintrddbipi); + + setsegment(&sd, &ci->ci_ddbipi_tss, sizeof(struct i386tss) - 1, + SDT_SYS386TSS, SEL_KPL, 0, 0); + ci->ci_gdt[GIPITSS_SEL].sd = sd; + + setgate(&idt[ddb_vec], NULL, 0, SDT_SYSTASKGT, SEL_KPL, + GSEL(GIPITSS_SEL, SEL_KPL)); +#endif +} +#endif + #ifdef MULTIPROCESSOR int mp_cpu_start(struct cpu_info *ci) @@ -776,7 +835,7 @@ cpu_idle_mwait_cycle(void) } void -cpu_init_mwait(struct cpu_softc *sc) +cpu_init_mwait(struct device *dv) { unsigned int smallest, largest, extensions, c_substates; @@ -788,8 +847,7 @@ cpu_init_mwait(struct cpu_softc *sc) smallest &= 0xffff; largest &= 0xffff; - printf("%s: mwait min=%u, max=%u", sc->sc_dev.dv_xname, - smallest, largest); + printf("%s: mwait min=%u, max=%u", dv->dv_xname, smallest, largest); if (extensions & 0x1) { if (cpu_mwait_states > 0) { c_substates = cpu_mwait_states; diff --git a/sys/arch/i386/i386/db_interface.c b/sys/arch/i386/i386/db_interface.c index 5791d6a69e6..1ae1f3f6f05 100644 --- a/sys/arch/i386/i386/db_interface.c +++ b/sys/arch/i386/i386/db_interface.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_interface.c,v 1.38 2018/03/20 15:45:32 mpi Exp $ */ +/* $OpenBSD: db_interface.c,v 1.39 2018/03/22 19:30:18 bluhm Exp $ */ /* $NetBSD: db_interface.c,v 1.22 1996/05/03 19:42:00 christos Exp $ */ /* @@ -229,7 +229,7 @@ db_cpuinfo_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) for (i = 0; i < MAXCPUS; i++) { if (cpu_info[i] != NULL) { db_printf("%c%4d: ", (i == cpu_number()) ? '*' : ' ', - cpu_info[i]->ci_dev->dv_unit); + cpu_info[i]->ci_dev.dv_unit); switch(cpu_info[i]->ci_ddb_paused) { case CI_DDB_RUNNING: db_printf("running\n"); diff --git a/sys/arch/i386/i386/est.c b/sys/arch/i386/i386/est.c index 3cdecde815c..77f332e72f8 100644 --- a/sys/arch/i386/i386/est.c +++ b/sys/arch/i386/i386/est.c @@ -1,4 +1,4 @@ -/* $OpenBSD: est.c,v 1.50 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: est.c,v 1.51 2018/03/22 19:30:18 bluhm Exp $ */ /* * Copyright (c) 2003 Michael Eriksson. * All rights reserved. @@ -1049,7 +1049,7 @@ est_acpi_pss_changed(struct acpicpu_pss *pss, int npss) void est_init(struct cpu_info *ci, int vendor) { - const char *cpu_device = ci->ci_dev->dv_xname; + const char *cpu_device = ci->ci_dev.dv_xname; int i, low, high; u_int64_t msr; u_int16_t idhi, idlo, cur; diff --git a/sys/arch/i386/i386/gdt.c b/sys/arch/i386/i386/gdt.c index 9a71a9a646a..163490520f4 100644 --- a/sys/arch/i386/i386/gdt.c +++ b/sys/arch/i386/i386/gdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gdt.c,v 1.38 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: gdt.c,v 1.39 2018/03/22 19:30:18 bluhm Exp $ */ /* $NetBSD: gdt.c,v 1.28 2002/12/14 09:38:50 junyoung Exp $ */ /*- @@ -38,7 +38,7 @@ * * The bootstrap GDT area will hold the initial requirement of NGDT * descriptors. The normal GDT will have a statically sized virtual memory - * area of size GDT_SIZE. + * area of size MAXGDTSIZ. * * Every CPU in a system has its own copy of the GDT. The only real difference * between the two are currently that there is a cpu-specific segment holding @@ -82,7 +82,7 @@ setgdt(int sel, void *base, size_t limit, int type, int dpl, int def32, CPU_INFO_ITERATOR cii; struct cpu_info *ci; - KASSERT(sel < NGDT); + KASSERT(sel < MAXGDTSIZ); setsegment(sd, base, limit, type, dpl, def32, gran); CPU_INFO_FOREACH(cii, ci) @@ -100,11 +100,11 @@ gdt_init(void) vaddr_t va; struct cpu_info *ci = &cpu_info_primary; - gdt_next = GBIOS32_SEL; + gdt_next = NGDT; gdt_free = GNULL_SEL; - gdt = (union descriptor *)uvm_km_valloc(kernel_map, GDT_SIZE); - for (va = (vaddr_t)gdt; va < (vaddr_t)gdt + GDT_SIZE; + gdt = (union descriptor *)uvm_km_valloc(kernel_map, MAXGDTSIZ); + for (va = (vaddr_t)gdt; va < (vaddr_t)gdt + MAXGDTSIZ; va += PAGE_SIZE) { pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO); if (pg == NULL) @@ -130,26 +130,21 @@ gdt_alloc_cpu(struct cpu_info *ci) struct vm_page *pg; vaddr_t va; - ci->ci_gdt = (union descriptor *)uvm_km_valloc(kernel_map, - GDT_SIZE + sizeof(*ci->ci_tss)); - ci->ci_tss = (void *)ci->ci_gdt + GDT_SIZE; + ci->ci_gdt = (union descriptor *)uvm_km_valloc(kernel_map, MAXGDTSIZ); uvm_map_pageable(kernel_map, (vaddr_t)ci->ci_gdt, - (vaddr_t)ci->ci_gdt + GDT_SIZE + sizeof(*ci->ci_tss), - FALSE, FALSE); - for (va = (vaddr_t)ci->ci_gdt; - va < (vaddr_t)ci->ci_gdt + GDT_SIZE + sizeof(*ci->ci_tss); + (vaddr_t)ci->ci_gdt + MAXGDTSIZ, FALSE, FALSE); + for (va = (vaddr_t)ci->ci_gdt; va < (vaddr_t)ci->ci_gdt + MAXGDTSIZ; va += PAGE_SIZE) { pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO); if (pg == NULL) - panic("gdt_alloc_cpu: no pages"); + panic("gdt_init: no pages"); pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg), PROT_READ | PROT_WRITE); } - bzero(ci->ci_gdt, GDT_SIZE); - bcopy(gdt, ci->ci_gdt, GDT_SIZE); + bzero(ci->ci_gdt, MAXGDTSIZ); + bcopy(gdt, ci->ci_gdt, MAXGDTSIZ); setsegment(&ci->ci_gdt[GCPU_SEL].sd, ci, sizeof(struct cpu_info)-1, SDT_MEMRWA, SEL_KPL, 0, 0); - bzero(ci->ci_tss, sizeof(*ci->ci_tss)); } #endif /* MULTIPROCESSOR */ @@ -163,20 +158,14 @@ gdt_init_cpu(struct cpu_info *ci) { struct region_descriptor region; - setsegment(&ci->ci_gdt[GTSS_SEL].sd, ci->ci_tss, - sizeof(*ci->ci_tss)-1, SDT_SYS386TSS, SEL_KPL, 0, 0); - - setregion(®ion, ci->ci_gdt, GDT_SIZE - 1); + setregion(®ion, ci->ci_gdt, MAXGDTSIZ - 1); lgdt(®ion); - - ltr(GSEL(GTSS_SEL, SEL_KPL)); - lldt(0); } /* * Allocate a GDT slot as follows: * 1) If there are entries on the free list, use those. - * 2) If there are fewer than NGDT entries in use, there are free slots + * 2) If there are fewer than MAXGDTSIZ entries in use, there are free slots * near the end that we can sweep through. */ int @@ -190,7 +179,7 @@ gdt_get_slot(void) slot = gdt_free; gdt_free = gdt[slot].gd.gd_selector; } else { - if (gdt_next >= NGDT) + if (gdt_next >= MAXGDTSIZ) panic("gdt_get_slot: out of GDT descriptors"); slot = gdt_next++; } @@ -198,3 +187,37 @@ gdt_get_slot(void) gdt_unlock(); return (slot); } + +/* + * Deallocate a GDT slot, putting it on the free list. + */ +void +gdt_put_slot(int slot) +{ + + gdt_lock(); + + gdt[slot].gd.gd_type = SDT_SYSNULL; + gdt[slot].gd.gd_selector = gdt_free; + gdt_free = slot; + + gdt_unlock(); +} + +int +tss_alloc(struct pcb *pcb) +{ + int slot; + + slot = gdt_get_slot(); + setgdt(slot, &pcb->pcb_tss, sizeof(struct pcb) - 1, + SDT_SYS386TSS, SEL_KPL, 0, 0); + return GSEL(slot, SEL_KPL); +} + +void +tss_free(int sel) +{ + + gdt_put_slot(IDXSEL(sel)); +} diff --git a/sys/arch/i386/i386/genassym.cf b/sys/arch/i386/i386/genassym.cf index 7fe77cf7cea..75db6c6c7f9 100644 --- a/sys/arch/i386/i386/genassym.cf +++ b/sys/arch/i386/i386/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.43 2018/03/13 13:51:05 bluhm Exp $ +# $OpenBSD: genassym.cf,v 1.44 2018/03/22 19:30:18 bluhm Exp $ # # Copyright (c) 1982, 1990 The Regents of the University of California. # All rights reserved. @@ -92,7 +92,6 @@ struct pcb member pcb_cr3 member pcb_ebp member pcb_esp -member pcb_kstack member pcb_cr0 member pcb_onfault member pcb_fpcpu @@ -139,17 +138,20 @@ endif define IP_SRC offsetof(struct ip, ip_src) define IP_DST offsetof(struct ip, ip_dst) +define P_MD_TSS_SEL offsetof(struct proc, p_md.md_tss_sel) + define CPU_INFO_SELF offsetof(struct cpu_info, ci_self) define CPU_INFO_APICID offsetof(struct cpu_info, ci_apicid) define CPU_INFO_CURPROC offsetof(struct cpu_info, ci_curproc) define CPU_INFO_CURPCB offsetof(struct cpu_info, ci_curpcb) +define CPU_INFO_NAME offsetof(struct cpu_info, ci_dev.dv_xname) define CPU_INFO_IDLE_PCB offsetof(struct cpu_info, ci_idle_pcb) +define CPU_INFO_IDLE_TSS_SEL offsetof(struct cpu_info, ci_idle_tss_sel) define CPU_INFO_LEVEL offsetof(struct cpu_info, ci_level) define CPU_INFO_VENDOR offsetof(struct cpu_info, ci_vendor[0]) define CPU_INFO_SIGNATURE offsetof(struct cpu_info, ci_signature) define CPU_INFO_RESCHED offsetof(struct cpu_info, ci_want_resched) define CPU_INFO_GDT offsetof(struct cpu_info, ci_gdt) -define CPU_INFO_TSS offsetof(struct cpu_info, ci_tss) define CPU_INFO_IPENDING offsetof(struct cpu_info, ci_ipending) define CPU_INFO_IMASK offsetof(struct cpu_info, ci_imask) define CPU_INFO_IUNMASK offsetof(struct cpu_info, ci_iunmask) @@ -164,8 +166,5 @@ define CPU_INFO_CURPMAP offsetof(struct cpu_info, ci_curpmap) struct pmap member pm_pdirpa -struct i386tss -member tss_esp0 - define SIZEOF_CPU_INFO sizeof(struct cpu_info) diff --git a/sys/arch/i386/i386/k1x-pstate.c b/sys/arch/i386/i386/k1x-pstate.c index c3c7a509401..215d76af6fd 100644 --- a/sys/arch/i386/i386/k1x-pstate.c +++ b/sys/arch/i386/i386/k1x-pstate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: k1x-pstate.c,v 1.10 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: k1x-pstate.c,v 1.11 2018/03/22 19:30:18 bluhm Exp $ */ /* * Copyright (c) 2011 Bryan Steele <brynet@gmail.com> * @@ -187,7 +187,7 @@ k1x_init(struct cpu_info *ci) #endif if (cstate->n_states) { printf("%s: %d MHz: speeds:", - ci->ci_dev->dv_xname, cpuspeed); + ci->ci_dev.dv_xname, cpuspeed); for (i = cstate->n_states; i > 0; i--) { state = &cstate->state_table[i-1]; printf(" %d", state->freq); diff --git a/sys/arch/i386/i386/kvm86.c b/sys/arch/i386/i386/kvm86.c index ab1ead55af6..054c6da578e 100644 --- a/sys/arch/i386/i386/kvm86.c +++ b/sys/arch/i386/i386/kvm86.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kvm86.c,v 1.13 2018/03/20 16:39:10 bluhm Exp $ */ +/* $OpenBSD: kvm86.c,v 1.14 2018/03/22 19:30:18 bluhm Exp $ */ /* $NetBSD: kvm86.c,v 1.10 2005/12/26 19:23:59 perry Exp $ */ /* * Copyright (c) 2002 @@ -35,7 +35,7 @@ #include <uvm/uvm_extern.h> -#include <machine/tss.h> +#include <machine/pcb.h> #include <machine/pte.h> #include <machine/pmap.h> #include <machine/kvm86.h> @@ -54,7 +54,7 @@ struct kvm86_data { struct segment_descriptor sd; - struct i386tss tss; + struct pcb pcb; u_long iomap[0x10000/32]; }; @@ -82,7 +82,7 @@ kvm86_init(void) size_t vmdsize; char *buf; struct kvm86_data *vmd; - struct i386tss *tss; + struct pcb *pcb; paddr_t pa; int i; @@ -93,23 +93,25 @@ kvm86_init(void) /* first page is stack */ vmd = (struct kvm86_data *)(buf + PAGE_SIZE); - tss = &vmd->tss; + pcb = &vmd->pcb; /* - * derive TSS from proc0 + * derive pcb and TSS from proc0 * we want to access all IO ports, so we need a full-size - * permission bitmap + * permission bitmap + * XXX do we really need the pcb or just the TSS? */ - memcpy(tss, cpu_info_primary.ci_tss, sizeof(struct i386tss)); - tss->tss_esp0 = (int)vmd; - tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + memcpy(pcb, &proc0.p_addr->u_pcb, sizeof(struct pcb)); + pcb->pcb_tss.tss_esp0 = (int)vmd; + pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); for (i = 0; i < sizeof(vmd->iomap) / 4; i++) vmd->iomap[i] = 0; - tss->tss_ioopt = ((caddr_t)vmd->iomap - (caddr_t)&tss) << 16; + pcb->pcb_tss.tss_ioopt = + ((caddr_t)vmd->iomap - (caddr_t)&pcb->pcb_tss) << 16; /* setup TSS descriptor (including our iomap) */ - setsegment(&vmd->sd, tss, - sizeof(struct i386tss) + sizeof(vmd->iomap) - 1, + setsegment(&vmd->sd, &pcb->pcb_tss, + sizeof(struct pcb) + sizeof(vmd->iomap) - 1, SDT_SYS386TSS, SEL_KPL, 0, 0); /* prepare VM for BIOS calls */ @@ -130,7 +132,7 @@ kvm86_init(void) * XXX this should be done cleanly (in call argument to kvm86_call()) */ -volatile struct i386tss *vm86tss; +volatile struct pcb *vm86pcb; volatile int vm86tssd0, vm86tssd1; volatile paddr_t vm86newptd; volatile struct trapframe *vm86frame; @@ -142,7 +144,7 @@ kvm86_prepare(struct kvm86_data *vmd) vm86newptd = vtophys((vaddr_t)vmd) | PG_V | PG_RW | PG_U | PG_u; vm86pgtableva = vmd->pgtbl; vm86frame = (struct trapframe *)vmd - 1; - vm86tss = &vmd->tss; + vm86pcb = &vmd->pcb; vm86tssd0 = *(int*)&vmd->sd; vm86tssd1 = *((int*)&vmd->sd + 1); } @@ -251,7 +253,7 @@ kvm86_simplecall(int no, struct kvm86regs *regs) { struct trapframe tf; int res; - + memset(&tf, 0, sizeof(struct trapframe)); tf.tf_eax = regs->eax; tf.tf_ebx = regs->ebx; diff --git a/sys/arch/i386/i386/kvm86call.S b/sys/arch/i386/i386/kvm86call.S index 10182b7c63f..37bc547b31d 100644 --- a/sys/arch/i386/i386/kvm86call.S +++ b/sys/arch/i386/i386/kvm86call.S @@ -1,4 +1,4 @@ -/* $OpenBSD: kvm86call.S,v 1.9 2018/03/20 16:39:10 bluhm Exp $ */ +/* $OpenBSD: kvm86call.S,v 1.10 2018/03/22 19:30:18 bluhm Exp $ */ /* $NetBSD: kvm86call.S,v 1.7 2006/04/11 17:14:07 drochner Exp $ */ /*- @@ -33,7 +33,6 @@ #include <machine/asm.h> #include <machine/param.h> -#include <machine/segments.h> #include "assym.h" .data @@ -44,7 +43,7 @@ kvm86_incall: .long 0 /* XXX arguments for kvm86call() */ - .globl vm86tss, vm86newptd, vm86frame, vm86pgtableva + .globl vm86pcb, vm86newptd, vm86frame, vm86pgtableva .globl vm86tssd0, vm86tssd1 /* locals */ @@ -96,13 +95,17 @@ ENTRY(kvm86_call) movl CPU_INFO_CURPCB(%ecx),%eax pushl %eax /* save curpcb */ + + movl vm86pcb,%eax + movl %eax,CPU_INFO_CURPCB(%ecx) /* set curpcb to vm86pcb */ + movl CPU_INFO_CURPROC(%ecx),%ecx + movl P_MD_TSS_SEL(%ecx),%edi #ifdef MULTIPROCESSOR movl CPU_INFO_GDT(%edx),%eax #else movl _C_LABEL(gdt),%eax #endif - movl $GSEL(GTSS_SEL, SEL_KPL),%edi andl $~0x0200,4(%eax,%edi,1) /* reset "task busy" */ movl 0(%eax,%edi,1),%edx @@ -188,7 +191,8 @@ ENTRY(kvm86_ret) leal _C_LABEL(cpu_info_primary),%ecx movl _C_LABEL(gdt),%eax #endif - movl $GSEL(GTSS_SEL, SEL_KPL),%edi + movl CPU_INFO_CURPROC(%ecx),%ecx + movl P_MD_TSS_SEL(%ecx),%edi movl SCRTSS0, %edx movl %edx, 0(%eax,%edi,1) /* restore first word */ movl SCRTSS1, %edx diff --git a/sys/arch/i386/i386/lapic.c b/sys/arch/i386/i386/lapic.c index a5117d90551..af214fd6fe6 100644 --- a/sys/arch/i386/i386/lapic.c +++ b/sys/arch/i386/i386/lapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lapic.c,v 1.42 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: lapic.c,v 1.43 2018/03/22 19:30:18 bluhm Exp $ */ /* $NetBSD: lapic.c,v 1.1.2.8 2000/02/23 06:10:50 sommerfeld Exp $ */ /*- @@ -127,9 +127,9 @@ lapic_set_lvt(void) #ifdef MULTIPROCESSOR if (mp_verbose) { - apic_format_redir(ci->ci_dev->dv_xname, "prelint", 0, 0, + apic_format_redir(ci->ci_dev.dv_xname, "prelint", 0, 0, i82489_readreg(LAPIC_LVINT0)); - apic_format_redir(ci->ci_dev->dv_xname, "prelint", 1, 0, + apic_format_redir(ci->ci_dev.dv_xname, "prelint", 1, 0, i82489_readreg(LAPIC_LVINT1)); } #endif @@ -177,15 +177,15 @@ lapic_set_lvt(void) #ifdef MULTIPROCESSOR if (mp_verbose) { - apic_format_redir(ci->ci_dev->dv_xname, "timer", 0, 0, + apic_format_redir(ci->ci_dev.dv_xname, "timer", 0, 0, i82489_readreg(LAPIC_LVTT)); - apic_format_redir(ci->ci_dev->dv_xname, "pcint", 0, 0, + apic_format_redir(ci->ci_dev.dv_xname, "pcint", 0, 0, i82489_readreg(LAPIC_PCINT)); - apic_format_redir(ci->ci_dev->dv_xname, "lint", 0, 0, + apic_format_redir(ci->ci_dev.dv_xname, "lint", 0, 0, i82489_readreg(LAPIC_LVINT0)); - apic_format_redir(ci->ci_dev->dv_xname, "lint", 1, 0, + apic_format_redir(ci->ci_dev.dv_xname, "lint", 1, 0, i82489_readreg(LAPIC_LVINT1)); - apic_format_redir(ci->ci_dev->dv_xname, "err", 0, 0, + apic_format_redir(ci->ci_dev.dv_xname, "err", 0, 0, i82489_readreg(LAPIC_LVERR)); } #endif @@ -307,7 +307,7 @@ lapic_calibrate_timer(struct cpu_info *ci) int i, ef = read_eflags(); if (mp_verbose) - printf("%s: calibrating local timer\n", ci->ci_dev->dv_xname); + printf("%s: calibrating local timer\n", ci->ci_dev.dv_xname); /* * Configure timer to one-shot, interrupt masked, @@ -343,7 +343,7 @@ lapic_calibrate_timer(struct cpu_info *ci) lapic_per_second = tmp; printf("%s: apic clock running at %lldMHz\n", - ci->ci_dev->dv_xname, tmp / (1000 * 1000)); + ci->ci_dev.dv_xname, tmp / (1000 * 1000)); if (lapic_per_second != 0) { /* diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s index da9e661ec9a..2af9fd290cb 100644 --- a/sys/arch/i386/i386/locore.s +++ b/sys/arch/i386/i386/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.182 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: locore.s,v 1.183 2018/03/22 19:30:18 bluhm Exp $ */ /* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */ /*- @@ -775,11 +775,6 @@ switch_exited: movl PCB_ESP(%ebx),%esp movl PCB_EBP(%ebx),%ebp - /* Set this process' esp0 in the TSS. */ - movl CPUVAR(TSS),%edx - movl PCB_KSTACK(%ebx),%eax - movl %eax,TSS_ESP0(%edx) - /* Record new pcb. */ movl %ebx, CPUVAR(CURPCB) @@ -793,6 +788,14 @@ switch_exited: call _C_LABEL(pmap_switch) addl $8,%esp + /* Load TSS info. */ + movl CPUVAR(GDT),%eax + movl P_MD_TSS_SEL(%edi),%edx + + /* Switch TSS. */ + andl $~0x0200,4-SEL_KPL(%eax,%edx,1) + ltr %dx + /* Restore cr0 (including FPU state). */ movl PCB_CR0(%ebx),%ecx #ifdef MULTIPROCESSOR diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 1ea794eaae8..ede489b3204 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.611 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: machdep.c,v 1.612 2018/03/22 19:30:18 bluhm Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -377,6 +377,16 @@ cpu_startup(void) printf("%s", version); startclocks(); + /* + * We need to call identifycpu here early, so users have at least some + * basic information, if booting hangs later on. + */ + strlcpy(curcpu()->ci_dev.dv_xname, "cpu0", + sizeof(curcpu()->ci_dev.dv_xname)); + curcpu()->ci_signature = cpu_id; + curcpu()->ci_feature_flags = cpu_feature; + identifycpu(curcpu()); + printf("real mem = %llu (%lluMB)\n", (unsigned long long)ptoa((psize_t)physmem), (unsigned long long)ptoa((psize_t)physmem)/1024U/1024U); @@ -426,14 +436,16 @@ i386_proc0_tss_init(void) struct pcb *pcb; curpcb = pcb = &proc0.p_addr->u_pcb; + + pcb->pcb_tss.tss_ioopt = sizeof(pcb->pcb_tss) << 16; pcb->pcb_cr0 = rcr0(); - pcb->pcb_kstack = (int)proc0.p_addr + USPACE - 16; - proc0.p_md.md_regs = (struct trapframe *)pcb->pcb_kstack - 1; + pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + pcb->pcb_tss.tss_esp0 = (int)proc0.p_addr + USPACE - 16; + proc0.p_md.md_regs = (struct trapframe *)pcb->pcb_tss.tss_esp0 - 1; + proc0.p_md.md_tss_sel = tss_alloc(pcb); - /* empty iomap */ - cpu_info_primary.ci_tss->tss_ioopt = sizeof(struct i386tss) << 16; - cpu_info_primary.ci_tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); - cpu_info_primary.ci_tss->tss_esp0 = pcb->pcb_kstack; + ltr(proc0.p_md.md_tss_sel); + lldt(0); } #ifdef MULTIPROCESSOR @@ -442,11 +454,9 @@ i386_init_pcb_tss(struct cpu_info *ci) { struct pcb *pcb = ci->ci_idle_pcb; - ci->ci_tss->tss_ioopt = sizeof(*ci->ci_tss) << 16; - ci->ci_tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); - ci->ci_tss->tss_esp0 = pcb->pcb_kstack; - + pcb->pcb_tss.tss_ioopt = sizeof(pcb->pcb_tss) << 16; pcb->pcb_cr0 = rcr0(); + ci->ci_idle_tss_sel = tss_alloc(pcb); } #endif /* MULTIPROCESSOR */ @@ -1078,7 +1088,7 @@ winchip_cpu_setup(struct cpu_info *ci) ci->ci_feature_flags &= ~CPUID_TSC; /* Disable RDTSC instruction from user-level. */ lcr4(rcr4() | CR4_TSD); - printf("%s: TSC disabled\n", ci->ci_dev->dv_xname); + printf("%s: TSC disabled\n", ci->ci_dev.dv_xname); break; } } @@ -1092,7 +1102,7 @@ cyrix3_setperf_setup(struct cpu_info *ci) est_init(ci, CPUVENDOR_VIA); else printf("%s: Enhanced SpeedStep disabled by BIOS\n", - ci->ci_dev->dv_xname); + ci->ci_dev.dv_xname); } } #endif @@ -1147,7 +1157,7 @@ cyrix3_cpu_setup(struct cpu_info *ci) if (CPU_IS_PRIMARY(ci) && (model == 10 || model == 13 || model == 15)) { /* Setup the sensors structures */ - strlcpy(ci->ci_sensordev.xname, ci->ci_dev->dv_xname, + strlcpy(ci->ci_sensordev.xname, ci->ci_dev.dv_xname, sizeof(ci->ci_sensordev.xname)); ci->ci_sensor.type = SENSOR_TEMP; sensor_task_register(ci, via_update_sensor, 5); @@ -1177,7 +1187,7 @@ cyrix3_cpu_setup(struct cpu_info *ci) val = 0; if (val & (C3_CPUID_HAS_RNG | C3_CPUID_HAS_ACE)) - printf("%s:", ci->ci_dev->dv_xname); + printf("%s:", ci->ci_dev.dv_xname); /* Enable RNG if present and disabled */ if (val & C3_CPUID_HAS_RNG) { @@ -1295,13 +1305,13 @@ cyrix6x86_cpu_setup(struct cpu_info *ci) cyrix_write_reg(0xC3, cyrix_read_reg(0xC3) & ~0x10); printf("%s: xchg bug workaround performed\n", - ci->ci_dev->dv_xname); + ci->ci_dev.dv_xname); break; /* fallthrough? */ case 4: /* GXm */ /* Unset the TSC bit until calibrate_delay() gets fixed. */ clock_broken_latch = 1; curcpu()->ci_feature_flags &= ~CPUID_TSC; - printf("%s: TSC disabled\n", ci->ci_dev->dv_xname); + printf("%s: TSC disabled\n", ci->ci_dev.dv_xname); break; } } @@ -1316,7 +1326,7 @@ natsem6x86_cpu_setup(struct cpu_info *ci) switch (model) { case 4: cpu_feature &= ~CPUID_TSC; - printf("%s: TSC disabled\n", ci->ci_dev->dv_xname); + printf("%s: TSC disabled\n", ci->ci_dev.dv_xname); break; } } @@ -1327,7 +1337,7 @@ intel586_cpu_setup(struct cpu_info *ci) if (!cpu_f00f_bug) { fix_f00f(); printf("%s: F00F bug workaround installed\n", - ci->ci_dev->dv_xname); + ci->ci_dev.dv_xname); } } @@ -1469,7 +1479,7 @@ intel686_cpusensors_setup(struct cpu_info *ci) return; /* Setup the sensors structures */ - strlcpy(ci->ci_sensordev.xname, ci->ci_dev->dv_xname, + strlcpy(ci->ci_sensordev.xname, ci->ci_dev.dv_xname, sizeof(ci->ci_sensordev.xname)); ci->ci_sensor.type = SENSOR_TEMP; sensor_task_register(ci, intelcore_update_sensor, 5); @@ -1490,7 +1500,7 @@ intel686_setperf_setup(struct cpu_info *ci) est_init(ci, CPUVENDOR_INTEL); else printf("%s: Enhanced SpeedStep disabled by BIOS\n", - ci->ci_dev->dv_xname); + ci->ci_dev.dv_xname); } else if ((cpu_feature & (CPUID_ACPI | CPUID_TM)) == (CPUID_ACPI | CPUID_TM)) p4tcc_init(family, step); @@ -1547,7 +1557,7 @@ intel686_cpu_setup(struct cpu_info *ci) wrmsr(MSR_BBL_CR_CTL, msr119); printf("%s: disabling processor serial number\n", - ci->ci_dev->dv_xname); + ci->ci_dev.dv_xname); ci->ci_feature_flags &= ~CPUID_PSN; ci->ci_level = 2; } @@ -1663,7 +1673,7 @@ identifycpu(struct cpu_info *ci) int family, model, step, modif, cachesize; const struct cpu_cpuid_nameclass *cpup = NULL; char *brandstr_from, *brandstr_to; - char *cpu_device = ci->ci_dev->dv_xname; + char *cpu_device = ci->ci_dev.dv_xname; int skipspace; if (cpuid_level == -1) { @@ -2140,7 +2150,7 @@ p4_get_bus_clock(struct cpu_info *ci) default: printf("%s: unknown Pentium 4 (model %d) " "EBC_FREQUENCY_ID value %d\n", - ci->ci_dev->dv_xname, model, bus); + ci->ci_dev.dv_xname, model, bus); break; } } else { @@ -2161,7 +2171,7 @@ p4_get_bus_clock(struct cpu_info *ci) default: printf("%s: unknown Pentium 4 (model %d) " "EBC_FREQUENCY_ID value %d\n", - ci->ci_dev->dv_xname, model, bus); + ci->ci_dev.dv_xname, model, bus); break; } } @@ -2189,7 +2199,7 @@ p3_get_bus_clock(struct cpu_info *ci) break; default: printf("%s: unknown Pentium M FSB_FREQ value %d", - ci->ci_dev->dv_xname, bus); + ci->ci_dev.dv_xname, bus); goto print_msr; } break; @@ -2223,7 +2233,7 @@ p3_get_bus_clock(struct cpu_info *ci) break; default: printf("%s: unknown Core FSB_FREQ value %d", - ci->ci_dev->dv_xname, bus); + ci->ci_dev.dv_xname, bus); goto print_msr; } break; @@ -2247,7 +2257,7 @@ p3_get_bus_clock(struct cpu_info *ci) break; default: printf("%s: unknown Atom FSB_FREQ value %d", - ci->ci_dev->dv_xname, bus); + ci->ci_dev.dv_xname, bus); goto print_msr; } break; @@ -2273,7 +2283,7 @@ p3_get_bus_clock(struct cpu_info *ci) break; default: printf("%s: unknown i686 EBL_CR_POWERON value %d", - ci->ci_dev->dv_xname, bus); + ci->ci_dev.dv_xname, bus); goto print_msr; } break; @@ -3050,8 +3060,6 @@ cpu_init_idt(void) } #endif /* MULTIPROCESSOR */ -struct i386tss proc0_tss; - void init386(paddr_t first_avail) { @@ -3062,7 +3070,6 @@ init386(paddr_t first_avail) proc0.p_addr = proc0paddr; cpu_info_primary.ci_self = &cpu_info_primary; cpu_info_primary.ci_curpcb = &proc0.p_addr->u_pcb; - cpu_info_primary.ci_tss = &proc0_tss; /* make bootstrap gdt gates and memory segments */ setsegment(&gdt[GCODE_SEL].sd, 0, 0xfffff, SDT_MEMERA, SEL_KPL, 1, 1); @@ -3078,8 +3085,6 @@ init386(paddr_t first_avail) SDT_MEMRWA, SEL_UPL, 1, 1); setsegment(&gdt[GUGS_SEL].sd, 0, atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMRWA, SEL_UPL, 1, 1); - setsegment(&gdt[GTSS_SEL].sd, &proc0_tss, sizeof(proc0_tss)-1, - SDT_SYS386TSS, SEL_KPL, 0, 0); /* exceptions */ setgate(&idt[ 0], &IDTVEC(div), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL); @@ -3108,7 +3113,7 @@ init386(paddr_t first_avail) unsetgate(&idt[i]); setgate(&idt[128], &IDTVEC(syscall), 0, SDT_SYS386TGT, SEL_UPL, GCODE_SEL); - setregion(®ion, gdt, GDT_SIZE - 1); + setregion(®ion, gdt, NGDT * sizeof(union descriptor) - 1); lgdt(®ion); setregion(®ion, idt, sizeof(idt_region) - 1); lidt(®ion); diff --git a/sys/arch/i386/i386/mptramp.s b/sys/arch/i386/i386/mptramp.s index a828d0dd2a2..e362005c5fa 100644 --- a/sys/arch/i386/i386/mptramp.s +++ b/sys/arch/i386/i386/mptramp.s @@ -1,4 +1,4 @@ -/* $OpenBSD: mptramp.s,v 1.23 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: mptramp.s,v 1.24 2018/03/22 19:30:19 bluhm Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -181,7 +181,7 @@ nopae: # %ecx points at our cpu_info structure.. - movw $(GDT_SIZE-1), 6(%esp) # prepare segment descriptor + movw $(MAXGDTSIZ-1), 6(%esp) # prepare segment descriptor movl CPU_INFO_GDT(%ecx), %eax # for real gdt movl %eax, 8(%esp) lgdt 6(%esp) diff --git a/sys/arch/i386/i386/pmap.c b/sys/arch/i386/i386/pmap.c index 23534dfe066..6b310c84cc2 100644 --- a/sys/arch/i386/i386/pmap.c +++ b/sys/arch/i386/i386/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.197 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: pmap.c,v 1.198 2018/03/22 19:30:19 bluhm Exp $ */ /* $NetBSD: pmap.c,v 1.91 2000/06/02 17:46:37 thorpej Exp $ */ /* @@ -778,7 +778,7 @@ setcslimit(struct pmap *pm, struct trapframe *tf, struct pcb *pcb, */ curcpu()->ci_gdt[GUCODE_SEL].sd = pm->pm_codeseg; - tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL); + pcb->pcb_cs = tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL); } /* diff --git a/sys/arch/i386/i386/powernow-k7.c b/sys/arch/i386/i386/powernow-k7.c index 19f277cb257..e4f364f8323 100644 --- a/sys/arch/i386/i386/powernow-k7.c +++ b/sys/arch/i386/i386/powernow-k7.c @@ -1,4 +1,4 @@ -/* $OpenBSD: powernow-k7.c,v 1.39 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: powernow-k7.c,v 1.40 2018/03/22 19:30:19 bluhm Exp $ */ /* * Copyright (c) 2004 Martin Végiard. @@ -434,7 +434,7 @@ k7_powernow_init(void) else techname = "PowerNow! K7"; printf("%s: %s %d MHz: speeds:", - ci->ci_dev->dv_xname, techname, cpuspeed); + ci->ci_dev.dv_xname, techname, cpuspeed); for (i = cstate->n_states; i > 0; i--) { state = &cstate->state_table[i-1]; printf(" %d", state->freq); diff --git a/sys/arch/i386/i386/powernow-k8.c b/sys/arch/i386/i386/powernow-k8.c index 04339596364..fff52b11321 100644 --- a/sys/arch/i386/i386/powernow-k8.c +++ b/sys/arch/i386/i386/powernow-k8.c @@ -1,4 +1,4 @@ -/* $OpenBSD: powernow-k8.c,v 1.31 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: powernow-k8.c,v 1.32 2018/03/22 19:30:19 bluhm Exp $ */ /* * Copyright (c) 2004 Martin Végiard. @@ -499,7 +499,7 @@ k8_powernow_init(void) } if (cstate->n_states) { printf("%s: %s %d MHz: speeds:", - ci->ci_dev->dv_xname, techname, cpuspeed); + ci->ci_dev.dv_xname, techname, cpuspeed); for (i = cstate->n_states; i > 0; i--) { state = &cstate->state_table[i-1]; printf(" %d", state->freq); diff --git a/sys/arch/i386/i386/vm_machdep.c b/sys/arch/i386/i386/vm_machdep.c index 2f87f0bfea3..3ca171c4dc0 100644 --- a/sys/arch/i386/i386/vm_machdep.c +++ b/sys/arch/i386/i386/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.68 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.69 2018/03/22 19:30:19 bluhm Exp $ */ /* $NetBSD: vm_machdep.c,v 1.61 1996/05/03 19:42:35 christos Exp $ */ /*- @@ -88,13 +88,17 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb, #endif *pcb = p1->p_addr->u_pcb; - pcb->pcb_kstack = (int)p2->p_addr + USPACE - 16 - + /* Fix up the TSS. */ + pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + pcb->pcb_tss.tss_esp0 = (int)p2->p_addr + USPACE - 16 - (arc4random() & PAGE_MASK & ~_STACKALIGNBYTES); + p2->p_md.md_tss_sel = tss_alloc(pcb); + /* * Copy the trapframe, and arrange for the child to return directly */ - p2->p_md.md_regs = tf = (struct trapframe *)pcb->pcb_kstack - 1; + p2->p_md.md_regs = tf = (struct trapframe *)pcb->pcb_tss.tss_esp0 - 1; *tf = *p1->p_md.md_regs; /* @@ -124,6 +128,8 @@ cpu_exit(struct proc *p) if (p->p_addr->u_pcb.pcb_fpcpu != NULL) npxsave_proc(p, 0); #endif + + tss_free(p->p_md.md_tss_sel); sched_exit(p); } diff --git a/sys/arch/i386/i386/vmm.c b/sys/arch/i386/i386/vmm.c index 4b02416d5a7..58088f39966 100644 --- a/sys/arch/i386/i386/vmm.c +++ b/sys/arch/i386/i386/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.35 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: vmm.c,v 1.36 2018/03/22 19:30:19 bluhm Exp $ */ /* * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org> * @@ -745,7 +745,7 @@ vmm_start(void) delay(10); if (!(ci->ci_flags & CPUF_VMM)) { printf("%s: failed to enter VMM mode\n", - ci->ci_dev->dv_xname); + ci->ci_dev.dv_xname); ret = EIO; } } @@ -755,7 +755,7 @@ vmm_start(void) start_vmm_on_cpu(self); if (!(self->ci_flags & CPUF_VMM)) { printf("%s: failed to enter VMM mode\n", - self->ci_dev->dv_xname); + self->ci_dev.dv_xname); ret = EIO; } @@ -793,7 +793,7 @@ vmm_stop(void) delay(10); if (ci->ci_flags & CPUF_VMM) { printf("%s: failed to exit VMM mode\n", - ci->ci_dev->dv_xname); + ci->ci_dev.dv_xname); ret = EIO; } } @@ -803,7 +803,7 @@ vmm_stop(void) stop_vmm_on_cpu(self); if (self->ci_flags & CPUF_VMM) { printf("%s: failed to exit VMM mode\n", - self->ci_dev->dv_xname); + self->ci_dev.dv_xname); ret = EIO; } @@ -2519,7 +2519,7 @@ vcpu_init_vmx(struct vcpu *vcpu) goto exit; } - if (vmwrite(VMCS_HOST_IA32_TR_SEL, GSEL(GTSS_SEL, SEL_KPL))) { + if (vmwrite(VMCS_HOST_IA32_TR_SEL, proc0.p_md.md_tss_sel)) { ret = EINVAL; goto exit; } @@ -3446,7 +3446,7 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp) /* Host TR base */ if (vmwrite(VMCS_HOST_IA32_TR_BASE, - GSEL(GTSS_SEL, SEL_KPL))) { + proc0.p_md.md_tss_sel)) { ret = EINVAL; break; } diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index f3294535bde..b38d9eaa20d 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.159 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: cpu.h,v 1.160 2018/03/22 19:30:19 bluhm Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -46,7 +46,6 @@ #include <machine/psl.h> #include <machine/segments.h> #include <machine/intrdefs.h> -#include <machine/tss.h> #ifdef MULTIPROCESSOR #include <machine/i82489reg.h> @@ -103,7 +102,7 @@ union vmm_cpu_cap { #ifdef _KERNEL /* XXX stuff to move to cpuvar.h later */ struct cpu_info { - struct device *ci_dev; /* our device */ + struct device ci_dev; /* our device */ struct cpu_info *ci_self; /* pointer to this structure */ struct schedstate_percpu ci_schedstate; /* scheduler state */ struct cpu_info *ci_next; /* next cpu */ @@ -130,6 +129,7 @@ struct cpu_info { struct pcb *ci_curpcb; /* VA of current HW PCB */ struct pcb *ci_idle_pcb; /* VA of current PCB */ + int ci_idle_tss_sel; /* TSS selector of idle PCB */ struct pmap *ci_curpmap; struct intrsource *ci_isources[MAX_INTR_SOURCES]; @@ -175,7 +175,6 @@ struct cpu_info { int ci_want_resched; union descriptor *ci_gdt; - struct i386tss *ci_tss; volatile int ci_ddb_paused; /* paused due to other proc in ddb */ #define CI_DDB_RUNNING 0 @@ -231,7 +230,7 @@ extern struct cpu_info *cpu_info_list; #define CPU_INFO_FOREACH(cii, ci) for (cii = 0, ci = cpu_info_list; \ ci != NULL; ci = ci->ci_next) -#define CPU_INFO_UNIT(ci) ((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0) +#define CPU_INFO_UNIT(ci) ((ci)->ci_dev.dv_unit) #ifdef MULTIPROCESSOR diff --git a/sys/arch/i386/include/gdt.h b/sys/arch/i386/include/gdt.h index fc7fe20f587..e3525e60100 100644 --- a/sys/arch/i386/include/gdt.h +++ b/sys/arch/i386/include/gdt.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gdt.h,v 1.14 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: gdt.h,v 1.15 2018/03/22 19:30:19 bluhm Exp $ */ /* $NetBSD: gdt.h,v 1.7.10.6 2002/08/19 01:22:36 sommerfeld Exp $ */ /*- @@ -35,11 +35,21 @@ struct cpu_info; struct pcb; struct pmap; +union descriptor; void gdt_alloc_cpu(struct cpu_info *); int gdt_get_slot(void); void gdt_init(void); void gdt_init_cpu(struct cpu_info *); void gdt_reload_cpu(/* XXX struct cpu_info * */ void); +int tss_alloc(struct pcb *); +void tss_free(int); void setgdt(int, void *, size_t, int, int, int, int); #endif + +/* + * Maximum GDT size. It cannot exceed 65536 since the selector field of + * a descriptor is just 16 bits, and used as free list link. + */ + +#define MAXGDTSIZ 65536 diff --git a/sys/arch/i386/include/pcb.h b/sys/arch/i386/include/pcb.h index a01afaed5ad..84b364993cd 100644 --- a/sys/arch/i386/include/pcb.h +++ b/sys/arch/i386/include/pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcb.h,v 1.21 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: pcb.h,v 1.22 2018/03/22 19:30:19 bluhm Exp $ */ /* $NetBSD: pcb.h,v 1.21 1996/01/08 13:51:42 mycroft Exp $ */ /*- @@ -46,20 +46,19 @@ #include <sys/signal.h> #include <machine/segments.h> +#include <machine/tss.h> #include <machine/npx.h> #include <machine/sysarch.h> -/* - * Please not that pcb_savefpu must be aligend to 16 bytes. - */ struct pcb { - union savefpu pcb_savefpu; /* floating point state for FPU */ - int pcb_cr3; - int pcb_esp; - int pcb_ebp; - int pcb_kstack; /* kernel stack address */ + struct i386tss pcb_tss; +#define pcb_cr3 pcb_tss.tss_cr3 +#define pcb_esp pcb_tss.tss_esp +#define pcb_ebp pcb_tss.tss_ebp +#define pcb_cs pcb_tss.tss_cs int pcb_cr0; /* saved image of CR0 */ caddr_t pcb_onfault; /* copyin/out fault recovery */ + union savefpu pcb_savefpu; /* floating point state for FPU */ struct segment_descriptor pcb_threadsegs[2]; /* per-thread descriptors */ int vm86_eflags; /* virtual eflags for vm86 mode */ diff --git a/sys/arch/i386/include/proc.h b/sys/arch/i386/include/proc.h index 9f3645a0f3b..af5aafb0371 100644 --- a/sys/arch/i386/include/proc.h +++ b/sys/arch/i386/include/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.8 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: proc.h,v 1.9 2018/03/22 19:30:19 bluhm Exp $ */ /* $NetBSD: proc.h,v 1.10 1995/08/06 05:33:23 mycroft Exp $ */ /* @@ -38,6 +38,7 @@ struct mdproc { struct trapframe *md_regs; /* registers on current frame */ int md_flags; /* machine-dependent flags */ + int md_tss_sel; /* TSS selector */ int md_astpending; }; diff --git a/sys/arch/i386/include/segments.h b/sys/arch/i386/include/segments.h index 7c1a7bc4a47..79e97f76785 100644 --- a/sys/arch/i386/include/segments.h +++ b/sys/arch/i386/include/segments.h @@ -1,4 +1,4 @@ -/* $OpenBSD: segments.h,v 1.22 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: segments.h,v 1.23 2018/03/22 19:30:19 bluhm Exp $ */ /* $NetBSD: segments.h,v 1.23 1996/02/01 22:31:03 mycroft Exp $ */ /*- @@ -221,10 +221,11 @@ void idt_vec_free(int); #define GICODE_SEL 10 /* Interrupt code descriptor (same as Kernel code) */ #define GUFS_SEL 11 /* User per-thread (%fs) descriptor */ #define GUGS_SEL 12 /* User per-thread (%gs) descriptor */ -#define GTSS_SEL 13 /* common TSS */ -#define GBIOS32_SEL 14 /* spare slot for 32 bit BIOS calls */ -#define NGDT 15 +#define NGDT 13 -#define GDT_SIZE (NGDT << 3) +/* + * Entries in the Local Descriptor Table (LDT) + */ +#define NLDT 17 #endif /* _MACHINE_SEGMENTS_H_ */ diff --git a/sys/arch/i386/include/tss.h b/sys/arch/i386/include/tss.h index 93efe7f7457..4de76221feb 100644 --- a/sys/arch/i386/include/tss.h +++ b/sys/arch/i386/include/tss.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tss.h,v 1.9 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: tss.h,v 1.10 2018/03/22 19:30:19 bluhm Exp $ */ /* $NetBSD: tss.h,v 1.6 1995/10/11 04:20:28 mycroft Exp $ */ /*- @@ -50,24 +50,24 @@ struct i386tss { int __tss_ss1; int __tss_esp2; int __tss_ss2; - int __tss_cr3; + int tss_cr3; /* page directory [pointer] paddr */ int __tss_eip; int __tss_eflags; int __tss_eax; int __tss_ecx; int __tss_edx; int __tss_ebx; - int __tss_esp; - int __tss_ebp; + int tss_esp; /* saved stack pointer */ + int tss_ebp; /* saved frame pointer */ int __tss_esi; int __tss_edi; int __tss_es; - int __tss_cs; + int tss_cs; int __tss_ss; int __tss_ds; - int __tss_fs; - int __tss_gs; - int __tss_ldt; + int tss_fs; /* saved segment register */ + int tss_gs; /* saved segment register */ + int tss_ldt; /* LDT selector */ int tss_ioopt; /* options and I/O permission map offset */ }; diff --git a/sys/arch/i386/isa/npx.c b/sys/arch/i386/isa/npx.c index f58b284d9bb..c3befcc3f3e 100644 --- a/sys/arch/i386/isa/npx.c +++ b/sys/arch/i386/isa/npx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: npx.c,v 1.65 2018/03/13 13:51:05 bluhm Exp $ */ +/* $OpenBSD: npx.c,v 1.66 2018/03/22 19:30:19 bluhm Exp $ */ /* $NetBSD: npx.c,v 1.57 1996/05/12 23:12:24 mycroft Exp $ */ #if 0 @@ -353,7 +353,7 @@ npxinit(struct cpu_info *ci) if (npx586bug1(4195835, 3145727) != 0) { i386_fpu_fdivbug = 1; printf("%s: WARNING: Pentium FDIV bug detected!\n", - ci->ci_dev->dv_xname); + ci->ci_dev.dv_xname); } if (fpu_mxcsr_mask == 0 && i386_use_fxsave) { struct savexmm xm __attribute__((aligned(16))); |