aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/amd64/machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/amd64/amd64/machdep.c')
-rw-r--r--sys/amd64/amd64/machdep.c137
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();