From owner-svn-src-head@freebsd.org Sun Nov 10 09:28:20 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id B0E8B1AF96C; Sun, 10 Nov 2019 09:28:20 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 479pb84ypYz3Hqn; Sun, 10 Nov 2019 09:28:20 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 8E9FB24E8D; Sun, 10 Nov 2019 09:28:20 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xAA9SK2K062375; Sun, 10 Nov 2019 09:28:20 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xAA9SIY6062366; Sun, 10 Nov 2019 09:28:18 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201911100928.xAA9SIY6062366@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Sun, 10 Nov 2019 09:28:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354589 - in head/sys/amd64: amd64 include X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: in head/sys/amd64: amd64 include X-SVN-Commit-Revision: 354589 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Nov 2019 09:28:20 -0000 Author: kib Date: Sun Nov 10 09:28:18 2019 New Revision: 354589 URL: https://svnweb.freebsd.org/changeset/base/354589 Log: amd64: move common_tss into pcpu. This saves some memory, around 256K I think. It removes some code, e.g. KPTI does not need to specially map common_tss anymore. Also, common_tss become domain-local. Reviewed by: jhb Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D22231 Modified: head/sys/amd64/amd64/cpu_switch.S head/sys/amd64/amd64/db_interface.c head/sys/amd64/amd64/genassym.c head/sys/amd64/amd64/machdep.c head/sys/amd64/amd64/mp_machdep.c head/sys/amd64/amd64/pmap.c head/sys/amd64/amd64/sys_machdep.c head/sys/amd64/include/pcpu.h head/sys/amd64/include/tss.h Modified: head/sys/amd64/amd64/cpu_switch.S ============================================================================== --- head/sys/amd64/amd64/cpu_switch.S Sun Nov 10 09:25:19 2019 (r354588) +++ head/sys/amd64/amd64/cpu_switch.S Sun Nov 10 09:28:18 2019 (r354589) @@ -188,8 +188,10 @@ do_kthread: /* Do we need to reload tss ? */ movq PCPU(TSSP),%rax movq PCB_TSSP(%r8),%rdx + movq PCPU(PRVSPACE),%r13 + addq $PC_COMMONTSS,%r13 testq %rdx,%rdx - cmovzq PCPU(COMMONTSSP),%rdx + cmovzq %r13,%rdx cmpq %rax,%rdx jne do_tss done_tss: Modified: head/sys/amd64/amd64/db_interface.c ============================================================================== --- head/sys/amd64/amd64/db_interface.c Sun Nov 10 09:25:19 2019 (r354588) +++ head/sys/amd64/amd64/db_interface.c Sun Nov 10 09:28:18 2019 (r354589) @@ -97,9 +97,9 @@ void db_show_mdpcpu(struct pcpu *pc) { + db_printf("self = %p\n", pc->pc_prvspace); db_printf("curpmap = %p\n", pc->pc_curpmap); db_printf("tssp = %p\n", pc->pc_tssp); - db_printf("commontssp = %p\n", pc->pc_commontssp); db_printf("rsp0 = 0x%lx\n", pc->pc_rsp0); db_printf("kcr3 = 0x%lx\n", pc->pc_kcr3); db_printf("ucr3 = 0x%lx\n", pc->pc_ucr3); Modified: head/sys/amd64/amd64/genassym.c ============================================================================== --- head/sys/amd64/amd64/genassym.c Sun Nov 10 09:25:19 2019 (r354588) +++ head/sys/amd64/amd64/genassym.c Sun Nov 10 09:28:18 2019 (r354589) @@ -225,7 +225,7 @@ ASSYM(PC_RSP0, offsetof(struct pcpu, pc_rsp0)); ASSYM(PC_FS32P, offsetof(struct pcpu, pc_fs32p)); ASSYM(PC_GS32P, offsetof(struct pcpu, pc_gs32p)); ASSYM(PC_LDT, offsetof(struct pcpu, pc_ldt)); -ASSYM(PC_COMMONTSSP, offsetof(struct pcpu, pc_commontssp)); +ASSYM(PC_COMMONTSS, offsetof(struct pcpu, pc_common_tss)); ASSYM(PC_TSS, offsetof(struct pcpu, pc_tss)); ASSYM(PC_PM_SAVE_CNT, offsetof(struct pcpu, pc_pm_save_cnt)); ASSYM(PC_KCR3, offsetof(struct pcpu, pc_kcr3)); Modified: head/sys/amd64/amd64/machdep.c ============================================================================== --- head/sys/amd64/amd64/machdep.c Sun Nov 10 09:25:19 2019 (r354588) +++ head/sys/amd64/amd64/machdep.c Sun Nov 10 09:28:18 2019 (r354589) @@ -669,8 +669,6 @@ static char nmi0_stack[PAGE_SIZE] __aligned(16); static char dbg0_stack[PAGE_SIZE] __aligned(16); CTASSERT(sizeof(struct nmi_pcpu) == 16); -struct amd64tss common_tss[MAXCPU]; - /* * Software prototypes -- in more palatable form. * @@ -1550,8 +1548,7 @@ amd64_bsp_pcpu_init1(struct pcpu *pc) PCPU_SET(prvspace, pc); PCPU_SET(curthread, &thread0); - PCPU_SET(tssp, &common_tss[0]); - PCPU_SET(commontssp, &common_tss[0]); + PCPU_SET(tssp, PCPU_PTR(common_tss)); PCPU_SET(tss, (struct system_segment_descriptor *)&gdt[GPROC0_SEL]); PCPU_SET(ldt, (struct system_segment_descriptor *)&gdt[GUSERLDT_SEL]); PCPU_SET(fs32p, &gdt[GUFS32_SEL]); @@ -1572,9 +1569,12 @@ void amd64_bsp_ist_init(struct pcpu *pc) { struct nmi_pcpu *np; + struct amd64tss *tssp; + tssp = &pc->pc_common_tss; + /* doublefault stack space, runs on ist1 */ - common_tss[0].tss_ist1 = (long)&dblfault_stack[sizeof(dblfault_stack)]; + tssp->tss_ist1 = (long)&dblfault_stack[sizeof(dblfault_stack)]; /* * NMI stack, runs on ist2. The pcpu pointer is stored just @@ -1582,7 +1582,7 @@ amd64_bsp_ist_init(struct pcpu *pc) */ np = ((struct nmi_pcpu *)&nmi0_stack[sizeof(nmi0_stack)]) - 1; np->np_pcpu = (register_t)pc; - common_tss[0].tss_ist2 = (long)np; + tssp->tss_ist2 = (long)np; /* * MC# stack, runs on ist3. The pcpu pointer is stored just @@ -1590,14 +1590,14 @@ amd64_bsp_ist_init(struct pcpu *pc) */ np = ((struct nmi_pcpu *)&mce0_stack[sizeof(mce0_stack)]) - 1; np->np_pcpu = (register_t)pc; - common_tss[0].tss_ist3 = (long)np; + tssp->tss_ist3 = (long)np; /* * DB# stack, runs on ist4. */ np = ((struct nmi_pcpu *)&dbg0_stack[sizeof(dbg0_stack)]) - 1; np->np_pcpu = (register_t)pc; - common_tss[0].tss_ist4 = (long)np; + tssp->tss_ist4 = (long)np; } u_int64_t @@ -1664,6 +1664,8 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) */ pmap_thread_init_invl_gen(&thread0); + pc = &temp_bsp_pcpu; + /* * make gdt memory segments */ @@ -1672,14 +1674,13 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) x != GUSERLDT_SEL && x != (GUSERLDT_SEL) + 1) ssdtosd(&gdt_segs[x], &gdt[x]); } - gdt_segs[GPROC0_SEL].ssd_base = (uintptr_t)&common_tss[0]; + gdt_segs[GPROC0_SEL].ssd_base = (uintptr_t)&pc->pc_common_tss; ssdtosyssd(&gdt_segs[GPROC0_SEL], (struct system_segment_descriptor *)&gdt[GPROC0_SEL]); r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; r_gdt.rd_base = (long) gdt; lgdt(&r_gdt); - pc = &temp_bsp_pcpu; wrmsr(MSR_FSBASE, 0); /* User value */ wrmsr(MSR_GSBASE, (u_int64_t)pc); @@ -1781,7 +1782,8 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) amd64_bsp_ist_init(pc); /* Set the IO permission bitmap (empty due to tss seg limit) */ - common_tss[0].tss_iobase = sizeof(struct amd64tss) + IOPERM_BITMAP_SIZE; + pc->pc_common_tss.tss_iobase = sizeof(struct amd64tss) + + IOPERM_BITMAP_SIZE; gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); ltr(gsel_tss); @@ -1865,7 +1867,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) rsp0 = thread0.td_md.md_stack_base; /* Ensure the stack is aligned to 16 bytes */ rsp0 &= ~0xFul; - common_tss[0].tss_rsp0 = rsp0; + __pcpu[0].pc_common_tss.tss_rsp0 = rsp0; amd64_bsp_pcpu_init2(rsp0); /* transfer to user mode */ Modified: head/sys/amd64/amd64/mp_machdep.c ============================================================================== --- head/sys/amd64/amd64/mp_machdep.c Sun Nov 10 09:25:19 2019 (r354588) +++ head/sys/amd64/amd64/mp_machdep.c Sun Nov 10 09:28:18 2019 (r354589) @@ -285,26 +285,51 @@ init_secondary(void) /* Update microcode before doing anything else. */ ucode_load_ap(cpu); + /* Get per-cpu data and save */ + pc = &__pcpu[cpu]; + + /* prime data page for it to use */ + pcpu_init(pc, cpu, sizeof(struct pcpu)); + dpcpu_init(dpcpu, cpu); + pc->pc_apic_id = cpu_apic_ids[cpu]; + pc->pc_prvspace = pc; + pc->pc_curthread = 0; + pc->pc_tssp = &pc->pc_common_tss; + 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]; + /* See comment in pmap_bootstrap(). */ + pc->pc_pcid_next = PMAP_PCID_KERN + 2; + pc->pc_pcid_gen = 1; + /* Init tss */ - common_tss[cpu] = common_tss[0]; - common_tss[cpu].tss_iobase = sizeof(struct amd64tss) + + pc->pc_common_tss = __pcpu[0].pc_common_tss; + pc->pc_common_tss.tss_iobase = sizeof(struct amd64tss) + IOPERM_BITMAP_SIZE; - common_tss[cpu].tss_ist1 = (long)&doublefault_stack[PAGE_SIZE]; + pc->pc_common_tss.tss_rsp0 = 0; + pc->pc_common_tss.tss_ist1 = (long)&doublefault_stack[PAGE_SIZE]; + /* The NMI stack runs on IST2. */ np = ((struct nmi_pcpu *) &nmi_stack[PAGE_SIZE]) - 1; - common_tss[cpu].tss_ist2 = (long) np; + pc->pc_common_tss.tss_ist2 = (long)np; /* The MC# stack runs on IST3. */ np = ((struct nmi_pcpu *) &mce_stack[PAGE_SIZE]) - 1; - common_tss[cpu].tss_ist3 = (long) np; + pc->pc_common_tss.tss_ist3 = (long)np; /* The DB# stack runs on IST4. */ np = ((struct nmi_pcpu *) &dbg_stack[PAGE_SIZE]) - 1; - common_tss[cpu].tss_ist4 = (long) np; + pc->pc_common_tss.tss_ist4 = (long)np; /* Prepare private GDT */ - gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpu]; + 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)) @@ -313,45 +338,20 @@ init_secondary(void) ssdtosyssd(&gdt_segs[GPROC0_SEL], (struct system_segment_descriptor *)&gdt[NGDT * cpu + GPROC0_SEL]); ap_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; - ap_gdt.rd_base = (long) &gdt[NGDT * cpu]; + ap_gdt.rd_base = (u_long)&gdt[NGDT * cpu]; lgdt(&ap_gdt); /* does magic intra-segment return */ - /* Get per-cpu data */ - pc = &__pcpu[cpu]; - - /* prime data page for it to use */ - pcpu_init(pc, cpu, sizeof(struct pcpu)); - dpcpu_init(dpcpu, cpu); - pc->pc_apic_id = cpu_apic_ids[cpu]; - pc->pc_prvspace = pc; - pc->pc_curthread = 0; - pc->pc_tssp = &common_tss[cpu]; - pc->pc_commontssp = &common_tss[cpu]; - 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]; - /* See comment in pmap_bootstrap(). */ - pc->pc_pcid_next = PMAP_PCID_KERN + 2; - pc->pc_pcid_gen = 1; - common_tss[cpu].tss_rsp0 = 0; - /* Save the per-cpu pointer for use by the NMI handler. */ np = ((struct nmi_pcpu *) &nmi_stack[PAGE_SIZE]) - 1; - np->np_pcpu = (register_t) pc; + np->np_pcpu = (register_t)pc; /* Save the per-cpu pointer for use by the MC# handler. */ np = ((struct nmi_pcpu *) &mce_stack[PAGE_SIZE]) - 1; - np->np_pcpu = (register_t) pc; + np->np_pcpu = (register_t)pc; /* Save the per-cpu pointer for use by the DB# handler. */ np = ((struct nmi_pcpu *) &dbg_stack[PAGE_SIZE]) - 1; - np->np_pcpu = (register_t) pc; + np->np_pcpu = (register_t)pc; wrmsr(MSR_FSBASE, 0); /* User value */ wrmsr(MSR_GSBASE, (u_int64_t)pc); Modified: head/sys/amd64/amd64/pmap.c ============================================================================== --- head/sys/amd64/amd64/pmap.c Sun Nov 10 09:25:19 2019 (r354588) +++ head/sys/amd64/amd64/pmap.c Sun Nov 10 09:28:18 2019 (r354589) @@ -1765,6 +1765,10 @@ pmap_bootstrap(vm_paddr_t *firstaddr) pcpu_init(&__pcpu[0], 0, sizeof(struct pcpu)); amd64_bsp_pcpu_init1(&__pcpu[0]); amd64_bsp_ist_init(&__pcpu[0]); + 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]); + 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; @@ -9719,20 +9723,19 @@ pmap_pti_init(void) 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); - pmap_pti_add_kva_locked((vm_offset_t)common_tss, - (vm_offset_t)common_tss + sizeof(struct amd64tss) * MAXCPU, false); CPU_FOREACH(i) { /* Doublefault stack IST 1 */ - va = common_tss[i].tss_ist1; + va = __pcpu[i].pc_common_tss.tss_ist1; pmap_pti_add_kva_locked(va - PAGE_SIZE, va, false); /* NMI stack IST 2 */ - va = common_tss[i].tss_ist2 + sizeof(struct nmi_pcpu); + va = __pcpu[i].pc_common_tss.tss_ist2 + sizeof(struct nmi_pcpu); pmap_pti_add_kva_locked(va - PAGE_SIZE, va, false); /* MC# stack IST 3 */ - va = common_tss[i].tss_ist3 + sizeof(struct nmi_pcpu); + va = __pcpu[i].pc_common_tss.tss_ist3 + + sizeof(struct nmi_pcpu); pmap_pti_add_kva_locked(va - PAGE_SIZE, va, false); /* DB# stack IST 4 */ - va = common_tss[i].tss_ist4 + sizeof(struct nmi_pcpu); + va = __pcpu[i].pc_common_tss.tss_ist4 + sizeof(struct nmi_pcpu); pmap_pti_add_kva_locked(va - PAGE_SIZE, va, false); } pmap_pti_add_kva_locked((vm_offset_t)kernphys + KERNBASE, Modified: head/sys/amd64/amd64/sys_machdep.c ============================================================================== --- head/sys/amd64/amd64/sys_machdep.c Sun Nov 10 09:25:19 2019 (r354588) +++ head/sys/amd64/amd64/sys_machdep.c Sun Nov 10 09:28:18 2019 (r354589) @@ -426,8 +426,7 @@ amd64_set_ioperm(td, uap) memset(iomap, 0xff, IOPERM_BITMAP_SIZE); critical_enter(); /* Takes care of tss_rsp0. */ - memcpy(tssp, &common_tss[PCPU_GET(cpuid)], - sizeof(struct amd64tss)); + memcpy(tssp, PCPU_PTR(common_tss), sizeof(struct amd64tss)); tssp->tss_iobase = sizeof(*tssp); pcb->pcb_tssp = tssp; tss_sd = PCPU_GET(tss); Modified: head/sys/amd64/include/pcpu.h ============================================================================== --- head/sys/amd64/include/pcpu.h Sun Nov 10 09:25:19 2019 (r354588) +++ head/sys/amd64/include/pcpu.h Sun Nov 10 09:28:18 2019 (r354589) @@ -35,6 +35,8 @@ #error "sys/cdefs.h is a prerequisite for this file" #endif +#include + #define PC_PTI_STACK_SZ 16 struct monitorbuf { @@ -56,7 +58,7 @@ _Static_assert(sizeof(struct monitorbuf) == 128, "2x c struct pcpu *pc_prvspace; /* Self-reference */ \ struct pmap *pc_curpmap; \ struct amd64tss *pc_tssp; /* TSS segment active on CPU */ \ - struct amd64tss *pc_commontssp;/* Common TSS for the CPU */ \ + void *pc_pad0; \ uint64_t pc_kcr3; \ uint64_t pc_ucr3; \ uint64_t pc_saved_ucr3; \ @@ -89,7 +91,8 @@ _Static_assert(sizeof(struct monitorbuf) == 128, "2x c uint32_t pc_pad[2]; \ uint8_t pc_mds_tmp[64]; \ u_int pc_ipi_bitmap; \ - char __pad[3172] /* pad to UMA_PCPU_ALLOC_SIZE */ + struct amd64tss pc_common_tss; \ + char __pad[3068] /* pad to UMA_PCPU_ALLOC_SIZE */ #define PC_DBREG_CMD_NONE 0 #define PC_DBREG_CMD_LOAD 1 Modified: head/sys/amd64/include/tss.h ============================================================================== --- head/sys/amd64/include/tss.h Sun Nov 10 09:25:19 2019 (r354588) +++ head/sys/amd64/include/tss.h Sun Nov 10 09:28:18 2019 (r354589) @@ -65,8 +65,4 @@ struct amd64tss { u_int16_t tss_iobase; /* io bitmap offset */ }; -#ifdef _KERNEL -extern struct amd64tss common_tss[]; -#endif - #endif /* _MACHINE_TSS_H_ */