Print this page
8956 Implement KPTI
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
@@ -30,11 +30,11 @@
*/
/*
* Portions Copyright 2009 Advanced Micro Devices, Inc.
*/
/*
- * Copyright 2017 Joyent, Inc.
+ * Copyright 2018 Joyent, Inc.
*/
/*
* Various routines to handle identification
* and classification of x86 processors.
*/
@@ -56,10 +56,11 @@
#include <sys/bitmap.h>
#include <sys/auxv_386.h>
#include <sys/memnode.h>
#include <sys/pci_cfgspace.h>
#include <sys/comm_page.h>
+#include <sys/mach_mmu.h>
#include <sys/tsc.h>
#ifdef __xpv
#include <sys/hypervisor.h>
#else
@@ -81,11 +82,11 @@
*
* o Determining vendor/model/family/stepping and setting x86_type and
* x86_vendor accordingly.
* o Processing the feature flags returned by the cpuid instruction while
* applying any workarounds or tricks for the specific processor.
- * o Mapping the feature flags into Solaris feature bits (X86_*).
+ * o Mapping the feature flags into illumos feature bits (X86_*).
* o Processing extended feature flags if supported by the processor,
* again while applying specific processor knowledge.
* o Determining the CMT characteristics of the system.
*
* Pass 1 is done on non-boot CPUs during their initialization and the results
@@ -120,10 +121,18 @@
uint_t x86_vendor = X86_VENDOR_IntelClone;
uint_t x86_type = X86_TYPE_OTHER;
uint_t x86_clflush_size = 0;
+#if defined(__xpv)
+int x86_use_pcid = 0;
+int x86_use_invpcid = 0;
+#else
+int x86_use_pcid = -1;
+int x86_use_invpcid = -1;
+#endif
+
uint_t pentiumpro_bug4046376;
uchar_t x86_featureset[BT_SIZEOFMAP(NUM_X86_FEATURES)];
static char *x86_feature_names[NUM_X86_FEATURES] = {
@@ -194,10 +203,12 @@
"xsaves",
"sha",
"umip",
"pku",
"ospke",
+ "pcid",
+ "invpcid",
};
boolean_t
is_x86_feature(void *featureset, uint_t feature)
{
@@ -1296,10 +1307,14 @@
}
if (ecp->cp_ebx & CPUID_INTC_EBX_7_0_SMEP)
add_x86_feature(featureset, X86FSET_SMEP);
+ if (ecp->cp_ebx & CPUID_INTC_EBX_7_0_INVPCID) {
+ add_x86_feature(featureset, X86FSET_INVPCID);
+ }
+
/*
* We check disable_smap here in addition to in startup_smap()
* to ensure CPUs that aren't the boot CPU don't accidentally
* include it in the feature set and thus generate a mismatched
* x86 feature set across CPUs. Note that at this time we only
@@ -1498,10 +1513,17 @@
add_x86_feature(featureset,
X86FSET_AVX512FMAPS);
}
}
}
+
+ if (cpi->cpi_vendor == X86_VENDOR_Intel) {
+ if (cp->cp_ecx & CPUID_INTC_ECX_PCID) {
+ add_x86_feature(featureset, X86FSET_PCID);
+ }
+ }
+
if (cp->cp_ecx & CPUID_INTC_ECX_X2APIC) {
add_x86_feature(featureset, X86FSET_X2APIC);
}
if (cp->cp_edx & CPUID_INTC_EDX_DE) {
add_x86_feature(featureset, X86FSET_DE);
@@ -4990,10 +5012,33 @@
no_trap();
}
#endif /* !__xpv */
}
+void
+enable_pcid(void)
+{
+ if (x86_use_pcid == -1)
+ x86_use_pcid = is_x86_feature(x86_featureset, X86FSET_PCID);
+
+ if (x86_use_invpcid == -1) {
+ x86_use_invpcid = is_x86_feature(x86_featureset,
+ X86FSET_INVPCID);
+ }
+
+ if (!x86_use_pcid)
+ return;
+
+ /*
+ * Intel say that on setting PCIDE, it immediately starts using the PCID
+ * bits; better make sure there's nothing there.
+ */
+ ASSERT((getcr3() & MMU_PAGEOFFSET) == PCID_NONE);
+
+ setcr4(getcr4() | CR4_PCIDE);
+}
+
/*
* Setup necessary registers to enable XSAVE feature on this processor.
* This function needs to be called early enough, so that no xsave/xrstor
* ops will execute on the processor before the MSRs are properly set up.
*