diff options
Diffstat (limited to 'sys/amd64/amd64/machdep.c')
-rw-r--r-- | sys/amd64/amd64/machdep.c | 137 |
1 files changed, 73 insertions, 64 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 9979592acc19..c8539b7b189d 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -36,13 +36,9 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "opt_atpic.h" #include "opt_cpu.h" #include "opt_ddb.h" @@ -50,7 +46,6 @@ __FBSDID("$FreeBSD$"); #include "opt_isa.h" #include "opt_kstack_pages.h" #include "opt_maxmem.h" -#include "opt_mp_watchdog.h" #include "opt_pci.h" #include "opt_platform.h" #include "opt_sched.h" @@ -118,6 +113,8 @@ __FBSDID("$FreeBSD$"); #include <net/netisr.h> +#include <dev/smbios/smbios.h> + #include <machine/clock.h> #include <machine/cpu.h> #include <machine/cputypes.h> @@ -126,7 +123,6 @@ __FBSDID("$FreeBSD$"); #include <x86/mca.h> #include <machine/md_var.h> #include <machine/metadata.h> -#include <machine/mp_watchdog.h> #include <machine/pc/bios.h> #include <machine/pcb.h> #include <machine/proc.h> @@ -202,6 +198,7 @@ int cold = 1; long Maxmem = 0; long realmem = 0; +int late_console = 1; struct kva_md_info kmi; @@ -221,8 +218,7 @@ void (*vmm_resume_p)(void); bool efi_boot; static void -cpu_startup(dummy) - void *dummy; +cpu_startup(void *dummy) { uintmax_t memsize; char *sysenv; @@ -326,13 +322,13 @@ cpu_setregs(void) { register_t cr0; + TSENTER(); cr0 = rcr0(); - /* - * CR0_MP, CR0_NE and CR0_TS are also set by npx_probe() for the - * BSP. See the comments there about why we set them. - */ cr0 |= CR0_MP | CR0_NE | CR0_TS | CR0_WP | CR0_AM; + TSENTER2("load_cr0"); load_cr0(cr0); + TSEXIT2("load_cr0"); + TSEXIT(); } /* @@ -358,8 +354,8 @@ CTASSERT(sizeof(struct nmi_pcpu) == 16); * slots as corresponding segments for i386 kernel. */ struct soft_segment_descriptor gdt_segs[] = { -/* GNULL_SEL 0 Null Descriptor */ -{ .ssd_base = 0x0, +[GNULL_SEL] = { /* 0 Null Descriptor */ + .ssd_base = 0x0, .ssd_limit = 0x0, .ssd_type = 0, .ssd_dpl = 0, @@ -367,8 +363,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 0, .ssd_def32 = 0, .ssd_gran = 0 }, -/* GNULL2_SEL 1 Null Descriptor */ -{ .ssd_base = 0x0, +[GNULL2_SEL] = { /* 1 Null Descriptor */ + .ssd_base = 0x0, .ssd_limit = 0x0, .ssd_type = 0, .ssd_dpl = 0, @@ -376,8 +372,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 0, .ssd_def32 = 0, .ssd_gran = 0 }, -/* GUFS32_SEL 2 32 bit %gs Descriptor for user */ -{ .ssd_base = 0x0, +[GUFS32_SEL] = { /* 2 32 bit %gs Descriptor for user */ + .ssd_base = 0x0, .ssd_limit = 0xfffff, .ssd_type = SDT_MEMRWA, .ssd_dpl = SEL_UPL, @@ -385,8 +381,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 0, .ssd_def32 = 1, .ssd_gran = 1 }, -/* GUGS32_SEL 3 32 bit %fs Descriptor for user */ -{ .ssd_base = 0x0, +[GUGS32_SEL] = { /* 3 32 bit %fs Descriptor for user */ + .ssd_base = 0x0, .ssd_limit = 0xfffff, .ssd_type = SDT_MEMRWA, .ssd_dpl = SEL_UPL, @@ -394,8 +390,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 0, .ssd_def32 = 1, .ssd_gran = 1 }, -/* GCODE_SEL 4 Code Descriptor for kernel */ -{ .ssd_base = 0x0, +[GCODE_SEL] = { /* 4 Code Descriptor for kernel */ + .ssd_base = 0x0, .ssd_limit = 0xfffff, .ssd_type = SDT_MEMERA, .ssd_dpl = SEL_KPL, @@ -403,8 +399,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 1, .ssd_def32 = 0, .ssd_gran = 1 }, -/* GDATA_SEL 5 Data Descriptor for kernel */ -{ .ssd_base = 0x0, +[GDATA_SEL] = { /* 5 Data Descriptor for kernel */ + .ssd_base = 0x0, .ssd_limit = 0xfffff, .ssd_type = SDT_MEMRWA, .ssd_dpl = SEL_KPL, @@ -412,8 +408,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 1, .ssd_def32 = 0, .ssd_gran = 1 }, -/* GUCODE32_SEL 6 32 bit Code Descriptor for user */ -{ .ssd_base = 0x0, +[GUCODE32_SEL] = { /* 6 32 bit Code Descriptor for user */ + .ssd_base = 0x0, .ssd_limit = 0xfffff, .ssd_type = SDT_MEMERA, .ssd_dpl = SEL_UPL, @@ -421,8 +417,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 0, .ssd_def32 = 1, .ssd_gran = 1 }, -/* GUDATA_SEL 7 32/64 bit Data Descriptor for user */ -{ .ssd_base = 0x0, +[GUDATA_SEL] = { /* 7 32/64 bit Data Descriptor for user */ + .ssd_base = 0x0, .ssd_limit = 0xfffff, .ssd_type = SDT_MEMRWA, .ssd_dpl = SEL_UPL, @@ -430,8 +426,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 0, .ssd_def32 = 1, .ssd_gran = 1 }, -/* GUCODE_SEL 8 64 bit Code Descriptor for user */ -{ .ssd_base = 0x0, +[GUCODE_SEL] = { /* 8 64 bit Code Descriptor for user */ + .ssd_base = 0x0, .ssd_limit = 0xfffff, .ssd_type = SDT_MEMERA, .ssd_dpl = SEL_UPL, @@ -439,8 +435,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 1, .ssd_def32 = 0, .ssd_gran = 1 }, -/* GPROC0_SEL 9 Proc 0 Tss Descriptor */ -{ .ssd_base = 0x0, +[GPROC0_SEL] = { /* 9 Proc 0 TSS Descriptor */ + .ssd_base = 0x0, .ssd_limit = sizeof(struct amd64tss) + IOPERM_BITMAP_SIZE - 1, .ssd_type = SDT_SYSTSS, .ssd_dpl = SEL_KPL, @@ -448,8 +444,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 0, .ssd_def32 = 0, .ssd_gran = 0 }, -/* Actually, the TSS is a system descriptor which is double size */ -{ .ssd_base = 0x0, +[GPROC0_SEL + 1] = { /* 10 Proc 0 TSS descriptor, double size */ + .ssd_base = 0x0, .ssd_limit = 0x0, .ssd_type = 0, .ssd_dpl = 0, @@ -457,8 +453,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 0, .ssd_def32 = 0, .ssd_gran = 0 }, -/* GUSERLDT_SEL 11 LDT Descriptor */ -{ .ssd_base = 0x0, +[GUSERLDT_SEL] = { /* 11 LDT Descriptor */ + .ssd_base = 0x0, .ssd_limit = 0x0, .ssd_type = 0, .ssd_dpl = 0, @@ -466,8 +462,8 @@ struct soft_segment_descriptor gdt_segs[] = { .ssd_long = 0, .ssd_def32 = 0, .ssd_gran = 0 }, -/* GUSERLDT_SEL 12 LDT Descriptor, double size */ -{ .ssd_base = 0x0, +[GUSERLDT_SEL + 1] = { /* 12 LDT Descriptor, double size */ + .ssd_base = 0x0, .ssd_limit = 0x0, .ssd_type = 0, .ssd_dpl = 0, @@ -520,7 +516,7 @@ extern inthand_t * Display the index and function name of any IDT entries that don't use * the default 'rsvd' entry point. */ -DB_SHOW_COMMAND(idt, db_show_idt) +DB_SHOW_COMMAND_FLAGS(idt, db_show_idt, DB_CMD_MEMSAFE) { struct gate_descriptor *ip; int idx; @@ -539,7 +535,7 @@ DB_SHOW_COMMAND(idt, db_show_idt) } /* Show privileged registers. */ -DB_SHOW_COMMAND(sysregs, db_show_sysregs) +DB_SHOW_COMMAND_FLAGS(sysregs, db_show_sysregs, DB_CMD_MEMSAFE) { struct { uint16_t limit; @@ -572,7 +568,7 @@ DB_SHOW_COMMAND(sysregs, db_show_sysregs) db_printf("GSBASE\t0x%016lx\n", rdmsr(MSR_GSBASE)); } -DB_SHOW_COMMAND(dbregs, db_show_dbregs) +DB_SHOW_COMMAND_FLAGS(dbregs, db_show_dbregs, DB_CMD_MEMSAFE) { db_printf("dr0\t0x%016lx\n", rdr0()); @@ -580,14 +576,12 @@ DB_SHOW_COMMAND(dbregs, db_show_dbregs) db_printf("dr2\t0x%016lx\n", rdr2()); db_printf("dr3\t0x%016lx\n", rdr3()); db_printf("dr6\t0x%016lx\n", rdr6()); - db_printf("dr7\t0x%016lx\n", rdr7()); + db_printf("dr7\t0x%016lx\n", rdr7()); } #endif void -sdtossd(sd, ssd) - struct user_segment_descriptor *sd; - struct soft_segment_descriptor *ssd; +sdtossd(struct user_segment_descriptor *sd, struct soft_segment_descriptor *ssd) { ssd->ssd_base = (sd->sd_hibase << 24) | sd->sd_lobase; @@ -601,9 +595,7 @@ sdtossd(sd, ssd) } void -ssdtosd(ssd, sd) - struct soft_segment_descriptor *ssd; - struct user_segment_descriptor *sd; +ssdtosd(struct soft_segment_descriptor *ssd, struct user_segment_descriptor *sd) { sd->sd_lobase = (ssd->ssd_base) & 0xffffff; @@ -619,9 +611,7 @@ ssdtosd(ssd, sd) } void -ssdtosyssd(ssd, sd) - struct soft_segment_descriptor *ssd; - struct system_segment_descriptor *sd; +ssdtosyssd(struct soft_segment_descriptor *ssd, struct system_segment_descriptor *sd) { sd->sd_lobase = (ssd->ssd_base) & 0xffffff; @@ -876,6 +866,7 @@ getmemsize(caddr_t kmdp, u_int64_t first) quad_t dcons_addr, dcons_size; int page_counter; + TSENTER(); /* * Tell the physical memory allocator about pages used to store * the kernel and preloaded data. See kmem_bootstrap_free(). @@ -991,10 +982,11 @@ getmemsize(caddr_t kmdp, u_int64_t first) if (physmap[i + 1] < end) end = trunc_page(physmap[i + 1]); for (pa = round_page(physmap[i]); pa < end; pa += PAGE_SIZE) { - int tmp, page_bad, full; int *ptr = (int *)CADDR1; + int tmp; + bool full, page_bad; - full = FALSE; + full = false; /* * block out kernel memory as not available. */ @@ -1009,7 +1001,7 @@ getmemsize(caddr_t kmdp, u_int64_t first) && pa < dcons_addr + dcons_size) goto do_dump_avail; - page_bad = FALSE; + page_bad = false; if (memtest == 0) goto skip_memtest; @@ -1033,25 +1025,25 @@ getmemsize(caddr_t kmdp, u_int64_t first) */ *(volatile int *)ptr = 0xaaaaaaaa; if (*(volatile int *)ptr != 0xaaaaaaaa) - page_bad = TRUE; + page_bad = true; /* * Test for alternating 0's and 1's */ *(volatile int *)ptr = 0x55555555; if (*(volatile int *)ptr != 0x55555555) - page_bad = TRUE; + page_bad = true; /* * Test for all 1's */ *(volatile int *)ptr = 0xffffffff; if (*(volatile int *)ptr != 0xffffffff) - page_bad = TRUE; + page_bad = true; /* * Test for all 0's */ *(volatile int *)ptr = 0x0; if (*(volatile int *)ptr != 0x0) - page_bad = TRUE; + page_bad = true; /* * Restore original value. */ @@ -1061,7 +1053,7 @@ skip_memtest: /* * Adjust array of valid/good pages. */ - if (page_bad == TRUE) + if (page_bad == true) continue; /* * If this good page is a continuation of the @@ -1082,7 +1074,7 @@ skip_memtest: printf( "Too many holes in the physical address space, giving up\n"); pa_indx--; - full = TRUE; + full = true; goto do_dump_avail; } phys_avail[pa_indx++] = pa; /* start */ @@ -1131,6 +1123,7 @@ do_next: /* Map the message buffer. */ msgbufp = (struct msgbuf *)PHYS_TO_DMAP(phys_avail[pa_indx]); + TSEXIT(); } static caddr_t @@ -1301,7 +1294,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) struct user_segment_descriptor *gdt; struct region_descriptor r_gdt; size_t kstack0_sz; - int late_console; TSRAW(&thread0, TS_ENTER, __func__, NULL); @@ -1324,6 +1316,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) identify_cpu1(); identify_hypervisor(); + identify_hypervisor_smbios(); identify_cpu_fixup_bsp(); identify_cpu2(); initializecpucache(); @@ -1343,6 +1336,19 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) pmap_pcid_enabled = 0; } + /* + * Now we can do small core initialization, after the PCID + * CPU features and user knobs are evaluated. + */ + TUNABLE_INT_FETCH("vm.pmap.pcid_invlpg_workaround", + &pmap_pcid_invlpg_workaround_uena); + cpu_init_small_core(); + + if ((cpu_feature2 & CPUID2_XSAVE) != 0) { + use_xsave = 1; + TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave); + } + link_elf_ireloc(kmdp); /* @@ -1473,7 +1479,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) TUNABLE_INT_FETCH("hw.spec_store_bypass_disable", &hw_ssb_disable); TUNABLE_INT_FETCH("machdep.mitigations.ssb.disable", &hw_ssb_disable); - TUNABLE_INT_FETCH("machdep.syscall_ret_l1d_flush", + TUNABLE_INT_FETCH("machdep.syscall_ret_flush_l1d", &syscall_ret_l1d_flush_mode); TUNABLE_INT_FETCH("hw.mds_disable", &hw_mds_disable); @@ -1481,9 +1487,13 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) TUNABLE_INT_FETCH("machdep.mitigations.taa.enable", &x86_taa_enable); - TUNABLE_INT_FETCH("machdep.mitigations.rndgs.enable", + TUNABLE_INT_FETCH("machdep.mitigations.rngds.enable", &x86_rngds_mitg_enable); + TUNABLE_INT_FETCH("machdep.mitigations.zenbleed.enable", + &zenbleed_enable); + zenbleed_sanitize_enable(); + finishidentcpu(); /* Final stage of CPU initialization */ /* @@ -1521,7 +1531,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) * Default to late console initialization to support these drivers. * This loses mainly printf()s in getmemsize() and early debugging. */ - late_console = 1; TUNABLE_INT_FETCH("debug.late_console", &late_console); if (!late_console) { cninit(); |