summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/boot/sys/boot/forth/logo-illumos.4th38
-rw-r--r--usr/src/boot/sys/boot/i386/cdboot/cdboot.S8
-rw-r--r--usr/src/cmd/bhyve/bhyverun.c10
-rw-r--r--usr/src/cmd/bhyve/spinup_ap.c16
-rw-r--r--usr/src/lib/libvmmapi/common/vmmapi.c3
-rw-r--r--usr/src/pkg/manifests/driver-network-rge.mf4
-rw-r--r--usr/src/uts/i86pc/io/vmm/amd/svm.c8
-rw-r--r--usr/src/uts/i86pc/io/vmm/intel/vmx.c595
-rw-r--r--usr/src/uts/i86pc/io/vmm/intel/vmx.h17
-rw-r--r--usr/src/uts/i86pc/ml/cpr_wakecode.s3
-rw-r--r--usr/src/uts/i86pc/ml/kpti_trampolines.s3
-rw-r--r--usr/src/uts/i86pc/ml/locore.s3
-rw-r--r--usr/src/uts/i86pc/ml/mpcore.s3
-rw-r--r--usr/src/uts/i86pc/sys/vmm.h10
-rw-r--r--usr/src/uts/intel/brand/common/brand_asm.h5
-rw-r--r--usr/src/uts/intel/ia32/ml/float.s5
-rw-r--r--usr/src/uts/intel/kdi/kdi_idthdl.s3
-rw-r--r--usr/src/uts/intel/os/driver_aliases2
18 files changed, 204 insertions, 532 deletions
diff --git a/usr/src/boot/sys/boot/forth/logo-illumos.4th b/usr/src/boot/sys/boot/forth/logo-illumos.4th
index 656f5ff53b..84948ec3ad 100644
--- a/usr/src/boot/sys/boot/forth/logo-illumos.4th
+++ b/usr/src/boot/sys/boot/forth/logo-illumos.4th
@@ -38,25 +38,25 @@
0 0 0 0 0 s" /boot/illumos.png" fb-putimage if 2drop exit then
- s" @[33m, " logo+
- s" @[33m,./% @[31m& " logo+
- s" @[33m(****@[31m*( " logo+
- s" @[33m*/*@[31m// " logo+
- s" @[33m*,//@[31m/(( " logo+
- s" @[33m,*/@[31m/((/% " logo+
- s" @[33m//@[31m/((((% " logo+
- s" @[33m,*@[31m/(((((% @[33m&@[31m#///((&" logo+
- s" @[33m./@[31m//((((((% %/(((/ " logo+
- s" @[33m./@[31m///(((((///((, " logo+
- s" @[33m.*//@[31m//(((((((((( " logo+
- s" ./((((((((/ " logo+
- s" (/((((((( " logo+
- s" ,,((((((/ " logo+
- s" /(((( " logo+
- s" %/(((( " logo+
- s" @[33m&@[31m%#/((((. " logo+
- s" @[33m,@[31m( ,/ /(/ " logo+
- s" ,/@[m " logo+
+ s" @[33m,@[m " logo+
+ s" @[33m,./% @[31m&@[m " logo+
+ s" @[33m(****@[31m*(@[m " logo+
+ s" @[33m*/*@[31m//@[m " logo+
+ s" @[33m*,//@[31m/((@[m " logo+
+ s" @[33m,*/@[31m/((/%@[m " logo+
+ s" @[33m//@[31m/((((%@[m " logo+
+ s" @[33m,*@[31m/(((((%@[m @[33m&@[31m#///((&@[m" logo+
+ s" @[33m./@[31m//((((((%@[m @[31m%/(((/@[m " logo+
+ s" @[33m./@[31m///(((((///((,@[m " logo+
+ s" @[33m.*//@[31m//((((((((((@[m " logo+
+ s" @[31m./((((((((/@[m " logo+
+ s" @[31m(/(((((((@[m " logo+
+ s" @[31m,,((((((/@[m " logo+
+ s" @[31m/((((@[m " logo+
+ s" @[31m%/((((@[m " logo+
+ s" @[33m&@[31m%#/((((.@[m " logo+
+ s" @[33m,@[31m(@[m @[31m,/@[m @[31m/(/@[m " logo+
+ s" @[31m,/@[m " logo+
2drop
;
diff --git a/usr/src/boot/sys/boot/i386/cdboot/cdboot.S b/usr/src/boot/sys/boot/i386/cdboot/cdboot.S
index 22e277eace..3ab75c1fb2 100644
--- a/usr/src/boot/sys/boot/i386/cdboot/cdboot.S
+++ b/usr/src/boot/sys/boot/i386/cdboot/cdboot.S
@@ -34,7 +34,7 @@
#
# Basically, we first create a set of boot arguments to pass to the loaded
# binary. Then we attempt to load /boot/loader from the CD we were booted
-# off of.
+# from.
#
#include <bootargs.h>
@@ -136,7 +136,7 @@ real_start: cld # string ops inc
stosl # to zero
mov drive,%dl # Store BIOS boot device
mov %dl,0x4(%bx) # in kargs->bootdev
- or $KARGS_FLAGS_CD,0x8(%bx) # kargs->bootflags |=
+ orb $KARGS_FLAGS_CD,0x8(%bx) # kargs->bootflags |=
# KARGS_FLAGS_CD
#
# Load Volume Descriptor
@@ -494,7 +494,7 @@ twiddle: push %ax # Save
# legacy-free and simply doesn't have a keyboard controller.
# Thus, the A20 line is already enabled.
#
-seta20: cli # Disable interrupts
+seta20: cli # Disable interrupts
xor %cx,%cx # Clear
seta20.1: inc %cx # Increment, overflow?
jz seta20.3 # Yes
@@ -518,7 +518,7 @@ hex8: pushl %eax # Save
shrb $0x4,%al # Do upper
call hex8.1 # 4
popl %eax # Restore
-hex8.1: andb $0xf,%al # Get lower 4
+hex8.1: andb $0xf,%al # Get lower 4
cmpb $0xa,%al # Convert
sbbb $0x69,%al # to hex
das # digit
diff --git a/usr/src/cmd/bhyve/bhyverun.c b/usr/src/cmd/bhyve/bhyverun.c
index b8a993784a..e3c56bdbd0 100644
--- a/usr/src/cmd/bhyve/bhyverun.c
+++ b/usr/src/cmd/bhyve/bhyverun.c
@@ -39,6 +39,7 @@
*
* Copyright 2015 Pluribus Networks Inc.
* Copyright 2018 Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
*/
#include <sys/cdefs.h>
@@ -952,6 +953,7 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip)
static int
num_vcpus_allowed(struct vmctx *ctx)
{
+#ifdef __FreeBSD__
int tmp, error;
error = vm_get_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, &tmp);
@@ -964,6 +966,10 @@ num_vcpus_allowed(struct vmctx *ctx)
return (VM_MAXCPU);
else
return (1);
+#else
+ /* Unrestricted Guest is always enabled on illumos */
+ return (VM_MAXCPU);
+#endif /* __FreeBSD__ */
}
void
@@ -1340,11 +1346,15 @@ main(int argc, char *argv[])
vga_init(1);
if (lpc_bootrom()) {
+#ifdef __FreeBSD__
if (vm_set_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, 1)) {
fprintf(stderr, "ROM boot failed: unrestricted guest "
"capability not available\n");
exit(4);
}
+#else
+ /* Unrestricted Guest is always enabled on illumos */
+#endif
error = vcpu_reset(ctx, BSP);
assert(error == 0);
}
diff --git a/usr/src/cmd/bhyve/spinup_ap.c b/usr/src/cmd/bhyve/spinup_ap.c
index ecdd05694c..80caafe78e 100644
--- a/usr/src/cmd/bhyve/spinup_ap.c
+++ b/usr/src/cmd/bhyve/spinup_ap.c
@@ -27,6 +27,18 @@
*
* $FreeBSD$
*/
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * Copyright 2020 Oxide Computer Company
+ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -89,6 +101,7 @@ spinup_ap(struct vmctx *ctx, int vcpu, int newcpu, uint64_t rip)
fbsdrun_set_capabilities(ctx, newcpu);
+#ifdef __FreeBSD__
/*
* Enable the 'unrestricted guest' mode for 'newcpu'.
*
@@ -97,6 +110,9 @@ spinup_ap(struct vmctx *ctx, int vcpu, int newcpu, uint64_t rip)
*/
error = vm_set_capability(ctx, newcpu, VM_CAP_UNRESTRICTED_GUEST, 1);
assert(error == 0);
+#else
+ /* Unrestricted Guest is always enabled on illumos */
+#endif
spinup_ap_realmode(ctx, newcpu, &rip);
diff --git a/usr/src/lib/libvmmapi/common/vmmapi.c b/usr/src/lib/libvmmapi/common/vmmapi.c
index 9589d09ae1..7d3446a845 100644
--- a/usr/src/lib/libvmmapi/common/vmmapi.c
+++ b/usr/src/lib/libvmmapi/common/vmmapi.c
@@ -39,6 +39,7 @@
*
* Copyright 2015 Pluribus Networks Inc.
* Copyright 2019 Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
*/
#include <sys/cdefs.h>
@@ -1004,7 +1005,9 @@ static const char *capstrmap[] = {
[VM_CAP_HALT_EXIT] = "hlt_exit",
[VM_CAP_MTRAP_EXIT] = "mtrap_exit",
[VM_CAP_PAUSE_EXIT] = "pause_exit",
+#ifdef __FreeBSD__
[VM_CAP_UNRESTRICTED_GUEST] = "unrestricted_guest",
+#endif
[VM_CAP_ENABLE_INVPCID] = "enable_invpcid",
[VM_CAP_BPT_EXIT] = "bpt_exit",
};
diff --git a/usr/src/pkg/manifests/driver-network-rge.mf b/usr/src/pkg/manifests/driver-network-rge.mf
index b009225b6b..83c8c0ea64 100644
--- a/usr/src/pkg/manifests/driver-network-rge.mf
+++ b/usr/src/pkg/manifests/driver-network-rge.mf
@@ -47,7 +47,9 @@ driver name=rge clone_perms="rge 0666 root sys" perms="* 0666 root sys" \
alias=pci10ec,8168 \
alias=pci10ec,8169 \
alias=pci16ec,116 \
- alias=pciex10ec,8136
+ alias=pciex10ec,8136 \
+ alias=pciex10ec,8168 \
+ alias=pciex10ec,8169
file path=kernel/drv/$(ARCH64)/rge group=sys
file path=usr/share/man/man7d/rge.7d
legacy pkg=SUNWrge desc="Realtek Gigabit Ethernet Network Adapter Driver" \
diff --git a/usr/src/uts/i86pc/io/vmm/amd/svm.c b/usr/src/uts/i86pc/io/vmm/amd/svm.c
index 9d3c3a2477..f717962c4e 100644
--- a/usr/src/uts/i86pc/io/vmm/amd/svm.c
+++ b/usr/src/uts/i86pc/io/vmm/amd/svm.c
@@ -2342,11 +2342,6 @@ svm_setcap(void *arg, int vcpu, int type, int val)
svm_set_intercept(sc, vcpu, VMCB_CTRL1_INTCPT,
VMCB_INTCPT_PAUSE, val);
break;
- case VM_CAP_UNRESTRICTED_GUEST:
- /* Unrestricted guest execution cannot be disabled in SVM */
- if (val == 0)
- error = EINVAL;
- break;
default:
error = ENOENT;
break;
@@ -2372,9 +2367,6 @@ svm_getcap(void *arg, int vcpu, int type, int *retval)
*retval = svm_get_intercept(sc, vcpu, VMCB_CTRL1_INTCPT,
VMCB_INTCPT_PAUSE);
break;
- case VM_CAP_UNRESTRICTED_GUEST:
- *retval = 1; /* unrestricted guest is always enabled */
- break;
default:
error = ENOENT;
break;
diff --git a/usr/src/uts/i86pc/io/vmm/intel/vmx.c b/usr/src/uts/i86pc/io/vmm/intel/vmx.c
index 683c1a96bc..8469c99f33 100644
--- a/usr/src/uts/i86pc/io/vmm/intel/vmx.c
+++ b/usr/src/uts/i86pc/io/vmm/intel/vmx.c
@@ -134,7 +134,14 @@ __FBSDID("$FreeBSD$");
PROCBASED_CR3_STORE_EXITING | \
PROCBASED_IO_BITMAPS)
-#define PROCBASED_CTLS2_ONE_SETTING PROCBASED2_ENABLE_EPT
+/*
+ * EPT and Unrestricted Guest are considered necessities. The latter is not a
+ * requirement on FreeBSD, where grub2-bhyve is used to load guests directly
+ * without a bootrom starting in real mode.
+ */
+#define PROCBASED_CTLS2_ONE_SETTING \
+ (PROCBASED2_ENABLE_EPT | \
+ PROCBASED2_UNRESTRICTED_GUEST)
#define PROCBASED_CTLS2_ZERO_SETTING 0
#define VM_EXIT_CTLS_ONE_SETTING \
@@ -206,10 +213,6 @@ static int cap_pause_exit;
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, pause_exit, CTLFLAG_RD, &cap_pause_exit,
0, "PAUSE triggers a VM-exit");
-static int cap_unrestricted_guest;
-SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, unrestricted_guest, CTLFLAG_RD,
- &cap_unrestricted_guest, 0, "Unrestricted guests");
-
static int cap_monitor_trap;
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, monitor_trap, CTLFLAG_RD,
&cap_monitor_trap, 0, "Monitor trap flag");
@@ -218,17 +221,8 @@ static int cap_invpcid;
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, invpcid, CTLFLAG_RD, &cap_invpcid,
0, "Guests are allowed to use INVPCID");
-static int tpr_shadowing;
-SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, tpr_shadowing, CTLFLAG_RD,
- &tpr_shadowing, 0, "TPR shadowing support");
-
-static int virtual_interrupt_delivery;
-SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, virtual_interrupt_delivery, CTLFLAG_RD,
- &virtual_interrupt_delivery, 0, "APICv virtual interrupt delivery support");
-
-static int posted_interrupts;
-SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, posted_interrupts, CTLFLAG_RD,
- &posted_interrupts, 0, "APICv posted interrupt support");
+/* Extra capabilities (VMX_CAP_*) beyond the minimum */
+static enum vmx_caps vmx_capabilities;
static int pirvec = -1;
SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, posted_interrupt_vector, CTLFLAG_RD,
@@ -601,94 +595,6 @@ vpid_alloc(uint16_t *vpid, int num)
}
}
-#ifdef __FreeBSD__
-static void
-vpid_init(void)
-{
- /*
- * VPID 0 is required when the "enable VPID" execution control is
- * disabled.
- *
- * VPIDs [1,VM_MAXCPU] are used as the "overflow namespace" when the
- * unit number allocator does not have sufficient unique VPIDs to
- * satisfy the allocation.
- *
- * The remaining VPIDs are managed by the unit number allocator.
- */
- vpid_unr = new_unrhdr(VM_MAXCPU + 1, 0xffff, NULL);
-}
-
-static void
-vmx_disable(void *arg __unused)
-{
- struct invvpid_desc invvpid_desc = { 0 };
- struct invept_desc invept_desc = { 0 };
-
- if (vmxon_enabled[curcpu]) {
- /*
- * See sections 25.3.3.3 and 25.3.3.4 in Intel Vol 3b.
- *
- * VMXON or VMXOFF are not required to invalidate any TLB
- * caching structures. This prevents potential retention of
- * cached information in the TLB between distinct VMX episodes.
- */
- invvpid(INVVPID_TYPE_ALL_CONTEXTS, invvpid_desc);
- invept(INVEPT_TYPE_ALL_CONTEXTS, invept_desc);
- vmxoff();
- }
- load_cr4(rcr4() & ~CR4_VMXE);
-}
-
-static int
-vmx_cleanup(void)
-{
-
- if (pirvec >= 0)
- lapic_ipi_free(pirvec);
-
- if (vpid_unr != NULL) {
- delete_unrhdr(vpid_unr);
- vpid_unr = NULL;
- }
-
- if (nmi_flush_l1d_sw == 1)
- nmi_flush_l1d_sw = 0;
-
- smp_rendezvous(NULL, vmx_disable, NULL, NULL);
-
- return (0);
-}
-
-static void
-vmx_enable(void *arg __unused)
-{
- int error;
- uint64_t feature_control;
-
- feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL);
- if ((feature_control & IA32_FEATURE_CONTROL_LOCK) == 0 ||
- (feature_control & IA32_FEATURE_CONTROL_VMX_EN) == 0) {
- wrmsr(MSR_IA32_FEATURE_CONTROL,
- feature_control | IA32_FEATURE_CONTROL_VMX_EN |
- IA32_FEATURE_CONTROL_LOCK);
- }
-
- load_cr4(rcr4() | CR4_VMXE);
-
- *(uint32_t *)vmxon_region[curcpu] = vmx_revision();
- error = vmxon(vmxon_region[curcpu]);
- if (error == 0)
- vmxon_enabled[curcpu] = 1;
-}
-
-static void
-vmx_restore(void)
-{
-
- if (vmxon_enabled[curcpu])
- vmxon(vmxon_region[curcpu]);
-}
-#else /* __FreeBSD__ */
static int
vmx_cleanup(void)
{
@@ -701,48 +607,14 @@ vmx_restore(void)
{
/* No-op on illumos */
}
-#endif /* __FreeBSD__ */
static int
vmx_init(int ipinum)
{
int error;
-#ifdef __FreeBSD__
- uint64_t basic, fixed0, fixed1, feature_control;
-#else
uint64_t fixed0, fixed1;
-#endif
- uint32_t tmp, procbased2_vid_bits;
-
-#ifdef __FreeBSD__
- /* CPUID.1:ECX[bit 5] must be 1 for processor to support VMX */
- if (!(cpu_feature2 & CPUID2_VMX)) {
- printf("vmx_init: processor does not support VMX operation\n");
- return (ENXIO);
- }
-
- /*
- * Verify that MSR_IA32_FEATURE_CONTROL lock and VMXON enable bits
- * are set (bits 0 and 2 respectively).
- */
- feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL);
- if ((feature_control & IA32_FEATURE_CONTROL_LOCK) == 1 &&
- (feature_control & IA32_FEATURE_CONTROL_VMX_EN) == 0) {
- printf("vmx_init: VMX operation disabled by BIOS\n");
- return (ENXIO);
- }
-
- /*
- * Verify capabilities MSR_VMX_BASIC:
- * - bit 54 indicates support for INS/OUTS decoding
- */
- basic = rdmsr(MSR_VMX_BASIC);
- if ((basic & (1UL << 54)) == 0) {
- printf("vmx_init: processor does not support desired basic "
- "capabilities\n");
- return (EINVAL);
- }
-#endif /* __FreeBSD__ */
+ uint32_t tmp;
+ enum vmx_caps avail_caps = VMX_CAP_NONE;
/* Check support for primary processor-based VM-execution controls */
error = vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS,
@@ -826,93 +698,53 @@ vmx_init(int ipinum)
PROCBASED_PAUSE_EXITING, 0,
&tmp) == 0);
- cap_unrestricted_guest = (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2,
- MSR_VMX_PROCBASED_CTLS2,
- PROCBASED2_UNRESTRICTED_GUEST, 0,
- &tmp) == 0);
-
cap_invpcid = (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2,
MSR_VMX_PROCBASED_CTLS2, PROCBASED2_ENABLE_INVPCID, 0,
&tmp) == 0);
- /*
- * Check support for TPR shadow.
+ /* Check for APIC virtualization capabilities:
+ * - TPR shadowing
+ * - Full APICv (with or without x2APIC support)
+ * - Posted interrupt handling
*/
- error = vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS,
- MSR_VMX_TRUE_PROCBASED_CTLS, PROCBASED_USE_TPR_SHADOW, 0,
- &tmp);
- if (error == 0) {
- tpr_shadowing = 1;
- TUNABLE_INT_FETCH("hw.vmm.vmx.use_tpr_shadowing",
- &tpr_shadowing);
- }
-
- if (tpr_shadowing) {
- procbased_ctls |= PROCBASED_USE_TPR_SHADOW;
- procbased_ctls &= ~PROCBASED_CR8_LOAD_EXITING;
- procbased_ctls &= ~PROCBASED_CR8_STORE_EXITING;
- }
+ if (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS, MSR_VMX_TRUE_PROCBASED_CTLS,
+ PROCBASED_USE_TPR_SHADOW, 0, &tmp) == 0) {
+ avail_caps |= VMX_CAP_TPR_SHADOW;
+
+ const uint32_t apicv_bits =
+ PROCBASED2_VIRTUALIZE_APIC_ACCESSES |
+ PROCBASED2_APIC_REGISTER_VIRTUALIZATION |
+ PROCBASED2_VIRTUALIZE_X2APIC_MODE |
+ PROCBASED2_VIRTUAL_INTERRUPT_DELIVERY;
+ if (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2,
+ MSR_VMX_PROCBASED_CTLS2, apicv_bits, 0, &tmp) == 0) {
+ avail_caps |= VMX_CAP_APICV;
- /*
- * Check support for virtual interrupt delivery.
- */
- procbased2_vid_bits = (PROCBASED2_VIRTUALIZE_APIC_ACCESSES |
- PROCBASED2_VIRTUALIZE_X2APIC_MODE |
- PROCBASED2_APIC_REGISTER_VIRTUALIZATION |
- PROCBASED2_VIRTUAL_INTERRUPT_DELIVERY);
-
- error = vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2, MSR_VMX_PROCBASED_CTLS2,
- procbased2_vid_bits, 0, &tmp);
- if (error == 0 && tpr_shadowing) {
- virtual_interrupt_delivery = 1;
- TUNABLE_INT_FETCH("hw.vmm.vmx.use_apic_vid",
- &virtual_interrupt_delivery);
- }
-
- if (virtual_interrupt_delivery) {
- procbased_ctls |= PROCBASED_USE_TPR_SHADOW;
- procbased_ctls2 |= procbased2_vid_bits;
- procbased_ctls2 &= ~PROCBASED2_VIRTUALIZE_X2APIC_MODE;
-
- /*
- * Check for Posted Interrupts only if Virtual Interrupt
- * Delivery is enabled.
- */
- error = vmx_set_ctlreg(MSR_VMX_PINBASED_CTLS,
- MSR_VMX_TRUE_PINBASED_CTLS, PINBASED_POSTED_INTERRUPT, 0,
- &tmp);
- if (error == 0) {
-#ifdef __FreeBSD__
- pirvec = lapic_ipi_alloc(pti ? &IDTVEC(justreturn1_pti) :
- &IDTVEC(justreturn));
- if (pirvec < 0) {
- if (bootverbose) {
- printf("vmx_init: unable to allocate "
- "posted interrupt vector\n");
- }
- } else {
- posted_interrupts = 1;
- TUNABLE_INT_FETCH("hw.vmm.vmx.use_apic_pir",
- &posted_interrupts);
- }
-#else
/*
- * If the PSM-provided interfaces for requesting and
- * using a PIR IPI vector are present, use them for
- * posted interrupts.
+ * It may make sense in the future to differentiate
+ * hardware (or software) configurations with APICv but
+ * no support for accelerating x2APIC mode.
*/
- if (psm_get_pir_ipivect != NULL &&
- psm_send_pir_ipi != NULL) {
- pirvec = psm_get_pir_ipivect();
- posted_interrupts = 1;
+ avail_caps |= VMX_CAP_APICV_X2APIC;
+
+ error = vmx_set_ctlreg(MSR_VMX_PINBASED_CTLS,
+ MSR_VMX_TRUE_PINBASED_CTLS,
+ PINBASED_POSTED_INTERRUPT, 0, &tmp);
+ if (error == 0) {
+ /*
+ * If the PSM-provided interfaces for requesting
+ * and using a PIR IPI vector are present, use
+ * them for posted interrupts.
+ */
+ if (psm_get_pir_ipivect != NULL &&
+ psm_send_pir_ipi != NULL) {
+ pirvec = psm_get_pir_ipivect();
+ avail_caps |= VMX_CAP_APICV_PIR;
+ }
}
-#endif
}
}
- if (posted_interrupts)
- pinbased_ctls |= PINBASED_POSTED_INTERRUPT;
-
/* Initialize EPT */
error = ept_init(ipinum);
if (error) {
@@ -960,11 +792,10 @@ vmx_init(int ipinum)
cr0_zeros_mask = ~fixed0 & ~fixed1;
/*
- * CR0_PE and CR0_PG can be set to zero in VMX non-root operation
- * if unrestricted guest execution is allowed.
+ * Since Unrestricted Guest was already verified present, CR0_PE and
+ * CR0_PG are allowed to be set to zero in VMX non-root operation
*/
- if (cap_unrestricted_guest)
- cr0_ones_mask &= ~(CR0_PG | CR0_PE);
+ cr0_ones_mask &= ~(CR0_PG | CR0_PE);
/*
* Do not allow the guest to set CR0_NW or CR0_CD.
@@ -976,17 +807,9 @@ vmx_init(int ipinum)
cr4_ones_mask = fixed0 & fixed1;
cr4_zeros_mask = ~fixed0 & ~fixed1;
-#ifdef __FreeBSD__
- vpid_init();
-#endif
-
vmx_msr_init();
-#ifdef __FreeBSD__
- /* enable VMX operation */
- smp_rendezvous(NULL, vmx_enable, NULL, NULL);
-#endif
-
+ vmx_capabilities = avail_caps;
vmx_initialized = 1;
return (0);
@@ -1063,6 +886,7 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
struct vmcs *vmcs;
uint32_t exc_bitmap;
uint16_t maxcpus;
+ uint32_t proc_ctls, proc2_ctls, pin_ctls;
vmx = malloc(sizeof(struct vmx), M_VMX, M_WAITOK | M_ZERO);
if ((uintptr_t)vmx & PAGE_MASK) {
@@ -1117,16 +941,38 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
vpid_alloc(vpid, VM_MAXCPU);
- if (virtual_interrupt_delivery) {
+ /* Grab the established defaults */
+ proc_ctls = procbased_ctls;
+ proc2_ctls = procbased_ctls2;
+ pin_ctls = pinbased_ctls;
+ /* For now, default to the available capabilities */
+ vmx->vmx_caps = vmx_capabilities;
+
+ if (vmx_cap_en(vmx, VMX_CAP_TPR_SHADOW)) {
+ proc_ctls |= PROCBASED_USE_TPR_SHADOW;
+ proc_ctls &= ~PROCBASED_CR8_LOAD_EXITING;
+ proc_ctls &= ~PROCBASED_CR8_STORE_EXITING;
+ }
+ if (vmx_cap_en(vmx, VMX_CAP_APICV)) {
+ ASSERT(vmx_cap_en(vmx, VMX_CAP_TPR_SHADOW));
+
+ proc2_ctls |= (PROCBASED2_VIRTUALIZE_APIC_ACCESSES |
+ PROCBASED2_APIC_REGISTER_VIRTUALIZATION |
+ PROCBASED2_VIRTUAL_INTERRUPT_DELIVERY);
+
error = vm_map_mmio(vm, DEFAULT_APIC_BASE, PAGE_SIZE,
APIC_ACCESS_ADDRESS);
/* XXX this should really return an error to the caller */
KASSERT(error == 0, ("vm_map_mmio(apicbase) error %d", error));
}
+ if (vmx_cap_en(vmx, VMX_CAP_APICV_PIR)) {
+ ASSERT(vmx_cap_en(vmx, VMX_CAP_APICV));
+
+ pin_ctls |= PINBASED_POSTED_INTERRUPT;
+ }
maxcpus = vm_get_maxcpus(vm);
for (i = 0; i < maxcpus; i++) {
-#ifndef __FreeBSD__
/*
* Cache physical address lookups for various components which
* may be required inside the critical_enter() section implied
@@ -1135,13 +981,10 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
vm_paddr_t msr_bitmap_pa = vtophys(vmx->msr_bitmap);
vm_paddr_t apic_page_pa = vtophys(&vmx->apic_page[i]);
vm_paddr_t pir_desc_pa = vtophys(&vmx->pir_desc[i]);
-#endif /* __FreeBSD__ */
vmcs = &vmx->vmcs[i];
vmcs->identifier = vmx_revision();
-#ifndef __FreeBSD__
vmcs->vmcs_pa = (uint64_t)vtophys(vmcs);
-#endif
error = vmclear(vmcs);
if (error != 0) {
panic("vmx_vminit: vmclear error %d on vcpu %d\n",
@@ -1155,25 +998,14 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
VMPTRLD(vmcs);
error = 0;
-#ifdef __FreeBSD__
- /*
- * The illumos vmx_enter_guest implementation avoids some of
- * the %rsp-manipulation games which are present in the stock
- * one from FreeBSD.
- */
- error += vmwrite(VMCS_HOST_RSP, (u_long)&vmx->ctx[i]);
-#endif
+
error += vmwrite(VMCS_EPTP, vmx->eptp);
- error += vmwrite(VMCS_PIN_BASED_CTLS, pinbased_ctls);
- error += vmwrite(VMCS_PRI_PROC_BASED_CTLS, procbased_ctls);
- error += vmwrite(VMCS_SEC_PROC_BASED_CTLS, procbased_ctls2);
+ error += vmwrite(VMCS_PIN_BASED_CTLS, pin_ctls);
+ error += vmwrite(VMCS_PRI_PROC_BASED_CTLS, proc_ctls);
+ error += vmwrite(VMCS_SEC_PROC_BASED_CTLS, proc2_ctls);
error += vmwrite(VMCS_EXIT_CTLS, exit_ctls);
error += vmwrite(VMCS_ENTRY_CTLS, entry_ctls);
-#ifdef __FreeBSD__
- error += vmwrite(VMCS_MSR_BITMAP, vtophys(vmx->msr_bitmap));
-#else
error += vmwrite(VMCS_MSR_BITMAP, msr_bitmap_pa);
-#endif
error += vmwrite(VMCS_VPID, vpid[i]);
if (guest_l1d_flush && !guest_l1d_flush_sw) {
@@ -1195,37 +1027,27 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
vmx->ctx[i].guest_dr6 = DBREG_DR6_RESERVED1;
error += vmwrite(VMCS_GUEST_DR7, DBREG_DR7_RESERVED1);
- if (tpr_shadowing) {
-#ifdef __FreeBSD__
- error += vmwrite(VMCS_VIRTUAL_APIC,
- vtophys(&vmx->apic_page[i]));
-#else
+ if (vmx_cap_en(vmx, VMX_CAP_TPR_SHADOW)) {
error += vmwrite(VMCS_VIRTUAL_APIC, apic_page_pa);
-#endif
}
- if (virtual_interrupt_delivery) {
+ if (vmx_cap_en(vmx, VMX_CAP_APICV)) {
error += vmwrite(VMCS_APIC_ACCESS, APIC_ACCESS_ADDRESS);
error += vmwrite(VMCS_EOI_EXIT0, 0);
error += vmwrite(VMCS_EOI_EXIT1, 0);
error += vmwrite(VMCS_EOI_EXIT2, 0);
error += vmwrite(VMCS_EOI_EXIT3, 0);
}
- if (posted_interrupts) {
+ if (vmx_cap_en(vmx, VMX_CAP_APICV_PIR)) {
error += vmwrite(VMCS_PIR_VECTOR, pirvec);
-#ifdef __FreeBSD__
- error += vmwrite(VMCS_PIR_DESC,
- vtophys(&vmx->pir_desc[i]));
-#else
error += vmwrite(VMCS_PIR_DESC, pir_desc_pa);
-#endif
}
VMCLEAR(vmcs);
KASSERT(error == 0, ("vmx_vminit: error customizing the vmcs"));
vmx->cap[i].set = 0;
- vmx->cap[i].proc_ctls = procbased_ctls;
- vmx->cap[i].proc_ctls2 = procbased_ctls2;
+ vmx->cap[i].proc_ctls = proc_ctls;
+ vmx->cap[i].proc_ctls2 = proc2_ctls;
vmx->cap[i].exc_bitmap = exc_bitmap;
vmx->state[i].nextrip = ~0;
@@ -1534,7 +1356,6 @@ vmx_inject_nmi(struct vmx *vmx, int vcpu)
#endif
}
-#ifndef __FreeBSD__
static void
vmx_inject_interrupts(struct vmx *vmx, int vcpu, struct vlapic *vlapic,
uint64_t guestrip)
@@ -1638,7 +1459,7 @@ vmx_inject_interrupts(struct vmx *vmx, int vcpu, struct vlapic *vlapic,
*/
KASSERT(vector >= 0 && vector <= 255,
("invalid vector %d from INTR", vector));
- } else if (!virtual_interrupt_delivery) {
+ } else if (!vmx_cap_en(vmx, VMX_CAP_APICV)) {
/* Ask the local apic for a vector to inject */
if (!vlapic_pending_intr(vlapic, &vector))
return;
@@ -1713,197 +1534,6 @@ cantinject:
*/
vmx_set_int_window_exiting(vmx, vcpu);
}
-#else
-static void
-vmx_inject_interrupts(struct vmx *vmx, int vcpu, struct vlapic *vlapic,
- uint64_t guestrip)
-{
- int vector, need_nmi_exiting, extint_pending;
- uint64_t rflags, entryinfo;
- uint32_t gi, info;
-
- vlapic_tmr_update(vlapic);
-
- if (vmx->state[vcpu].nextrip != guestrip) {
- gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
- if (gi & HWINTR_BLOCKING) {
- VCPU_CTR2(vmx->vm, vcpu, "Guest interrupt blocking "
- "cleared due to rip change: %#lx/%#lx",
- vmx->state[vcpu].nextrip, guestrip);
- gi &= ~HWINTR_BLOCKING;
- vmcs_write(VMCS_GUEST_INTERRUPTIBILITY, gi);
- }
- }
-
- if (vm_entry_intinfo(vmx->vm, vcpu, &entryinfo)) {
- KASSERT((entryinfo & VMCS_INTR_VALID) != 0, ("%s: entry "
- "intinfo is not valid: %#lx", __func__, entryinfo));
-
- info = vmcs_read(VMCS_ENTRY_INTR_INFO);
- KASSERT((info & VMCS_INTR_VALID) == 0, ("%s: cannot inject "
- "pending exception: %#lx/%#x", __func__, entryinfo, info));
-
- info = entryinfo;
- vector = info & 0xff;
- if (vector == IDT_BP || vector == IDT_OF) {
- /*
- * VT-x requires #BP and #OF to be injected as software
- * exceptions.
- */
- info &= ~VMCS_INTR_T_MASK;
- info |= VMCS_INTR_T_SWEXCEPTION;
- }
-
- if (info & VMCS_INTR_DEL_ERRCODE)
- vmcs_write(VMCS_ENTRY_EXCEPTION_ERROR, entryinfo >> 32);
-
- vmcs_write(VMCS_ENTRY_INTR_INFO, info);
- }
-
- if (vm_nmi_pending(vmx->vm, vcpu)) {
- /*
- * If there are no conditions blocking NMI injection then
- * inject it directly here otherwise enable "NMI window
- * exiting" to inject it as soon as we can.
- *
- * We also check for STI_BLOCKING because some implementations
- * don't allow NMI injection in this case. If we are running
- * on a processor that doesn't have this restriction it will
- * immediately exit and the NMI will be injected in the
- * "NMI window exiting" handler.
- */
- need_nmi_exiting = 1;
- gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
- if ((gi & (HWINTR_BLOCKING | NMI_BLOCKING)) == 0) {
- info = vmcs_read(VMCS_ENTRY_INTR_INFO);
- if ((info & VMCS_INTR_VALID) == 0) {
- vmx_inject_nmi(vmx, vcpu);
- need_nmi_exiting = 0;
- } else {
- VCPU_CTR1(vmx->vm, vcpu, "Cannot inject NMI "
- "due to VM-entry intr info %#x", info);
- }
- } else {
- VCPU_CTR1(vmx->vm, vcpu, "Cannot inject NMI due to "
- "Guest Interruptibility-state %#x", gi);
- }
-
- if (need_nmi_exiting)
- vmx_set_nmi_window_exiting(vmx, vcpu);
- }
-
- extint_pending = vm_extint_pending(vmx->vm, vcpu);
-
- if (!extint_pending && virtual_interrupt_delivery) {
- vmx_inject_pir(vlapic);
- return;
- }
-
- /*
- * If interrupt-window exiting is already in effect then don't bother
- * checking for pending interrupts. This is just an optimization and
- * not needed for correctness.
- */
- if ((vmx->cap[vcpu].proc_ctls & PROCBASED_INT_WINDOW_EXITING) != 0) {
- VCPU_CTR0(vmx->vm, vcpu, "Skip interrupt injection due to "
- "pending int_window_exiting");
- return;
- }
-
- if (!extint_pending) {
- /* Ask the local apic for a vector to inject */
- if (!vlapic_pending_intr(vlapic, &vector))
- return;
-
- /*
- * From the Intel SDM, Volume 3, Section "Maskable
- * Hardware Interrupts":
- * - maskable interrupt vectors [16,255] can be delivered
- * through the local APIC.
- */
- KASSERT(vector >= 16 && vector <= 255,
- ("invalid vector %d from local APIC", vector));
- } else {
- /* Ask the legacy pic for a vector to inject */
- vatpic_pending_intr(vmx->vm, &vector);
-
- /*
- * From the Intel SDM, Volume 3, Section "Maskable
- * Hardware Interrupts":
- * - maskable interrupt vectors [0,255] can be delivered
- * through the INTR pin.
- */
- KASSERT(vector >= 0 && vector <= 255,
- ("invalid vector %d from INTR", vector));
- }
-
- /* Check RFLAGS.IF and the interruptibility state of the guest */
- rflags = vmcs_read(VMCS_GUEST_RFLAGS);
- if ((rflags & PSL_I) == 0) {
- VCPU_CTR2(vmx->vm, vcpu, "Cannot inject vector %d due to "
- "rflags %#lx", vector, rflags);
- goto cantinject;
- }
-
- gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
- if (gi & HWINTR_BLOCKING) {
- VCPU_CTR2(vmx->vm, vcpu, "Cannot inject vector %d due to "
- "Guest Interruptibility-state %#x", vector, gi);
- goto cantinject;
- }
-
- info = vmcs_read(VMCS_ENTRY_INTR_INFO);
- if (info & VMCS_INTR_VALID) {
- /*
- * This is expected and could happen for multiple reasons:
- * - A vectoring VM-entry was aborted due to astpending
- * - A VM-exit happened during event injection.
- * - An exception was injected above.
- * - An NMI was injected above or after "NMI window exiting"
- */
- VCPU_CTR2(vmx->vm, vcpu, "Cannot inject vector %d due to "
- "VM-entry intr info %#x", vector, info);
- goto cantinject;
- }
-
- /* Inject the interrupt */
- info = VMCS_INTR_T_HWINTR | VMCS_INTR_VALID;
- info |= vector;
- vmcs_write(VMCS_ENTRY_INTR_INFO, info);
-
- if (!extint_pending) {
- /* Update the Local APIC ISR */
- vlapic_intr_accepted(vlapic, vector);
- } else {
- vm_extint_clear(vmx->vm, vcpu);
- vatpic_intr_accepted(vmx->vm, vector);
-
- /*
- * After we accepted the current ExtINT the PIC may
- * have posted another one. If that is the case, set
- * the Interrupt Window Exiting execution control so
- * we can inject that one too.
- *
- * Also, interrupt window exiting allows us to inject any
- * pending APIC vector that was preempted by the ExtINT
- * as soon as possible. This applies both for the software
- * emulated vlapic and the hardware assisted virtual APIC.
- */
- vmx_set_int_window_exiting(vmx, vcpu);
- }
-
- VCPU_CTR1(vmx->vm, vcpu, "Injecting hwintr at vector %d", vector);
-
- return;
-
-cantinject:
- /*
- * Set the Interrupt Window Exiting execution control so we can inject
- * the interrupt as soon as blocking condition goes away.
- */
- vmx_set_int_window_exiting(vmx, vcpu);
-}
-#endif /* __FreeBSD__ */
/*
* If the Virtual NMIs execution control is '1' then the logical processor
@@ -2828,11 +2458,12 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
SDT_PROBE3(vmm, vmx, exit, halt, vmx, vcpu, vmexit);
vmexit->exitcode = VM_EXITCODE_HLT;
vmexit->u.hlt.rflags = vmcs_read(VMCS_GUEST_RFLAGS);
- if (virtual_interrupt_delivery)
+ if (vmx_cap_en(vmx, VMX_CAP_APICV)) {
vmexit->u.hlt.intr_status =
vmcs_read(VMCS_GUEST_INTR_STATUS);
- else
+ } else {
vmexit->u.hlt.intr_status = 0;
+ }
break;
case EXIT_REASON_MTF:
vmm_stat_incr(vmx->vm, vcpu, VMEXIT_MTRAP, 1);
@@ -3334,22 +2965,16 @@ vmx_run(void *arg, int vcpu, register_t rip, pmap_t pmap,
*
* The same reasoning applies to the IPI generated by
* pmap_invalidate_ept().
- */
-#ifdef __FreeBSD__
- disable_intr();
- vmx_inject_interrupts(vmx, vcpu, vlapic, rip);
-#else
- /*
+ *
* The bulk of guest interrupt injection is done without
* interrupts disabled on the host CPU. This is necessary
* since contended mutexes might force the thread to sleep.
*/
vmx_inject_interrupts(vmx, vcpu, vlapic, rip);
disable_intr();
- if (virtual_interrupt_delivery) {
+ if (vmx_cap_en(vmx, VMX_CAP_APICV)) {
vmx_inject_pir(vlapic);
}
-#endif /* __FreeBSD__ */
/*
* Check for vcpu suspension after injecting events because
@@ -3447,12 +3072,15 @@ vmx_run(void *arg, int vcpu, register_t rip, pmap_t pmap,
#endif
/*
- * If TPR Shadowing is enabled, the TPR Threshold
- * must be updated right before entering the guest.
+ * If TPR Shadowing is enabled, the TPR Threshold must be
+ * updated right before entering the guest.
*/
- if (tpr_shadowing && !virtual_interrupt_delivery) {
- if ((vmx->cap[vcpu].proc_ctls & PROCBASED_USE_TPR_SHADOW) != 0) {
- vmcs_write(VMCS_TPR_THRESHOLD, vlapic_get_cr8(vlapic));
+ if (vmx_cap_en(vmx, VMX_CAP_TPR_SHADOW) &&
+ !vmx_cap_en(vmx, VMX_CAP_APICV)) {
+ if ((vmx->cap[vcpu].proc_ctls &
+ PROCBASED_USE_TPR_SHADOW) != 0) {
+ vmcs_write(VMCS_TPR_THRESHOLD,
+ vlapic_get_cr8(vlapic));
}
}
@@ -3810,10 +3438,6 @@ vmx_getcap(void *arg, int vcpu, int type, int *retval)
if (cap_monitor_trap)
ret = 0;
break;
- case VM_CAP_UNRESTRICTED_GUEST:
- if (cap_unrestricted_guest)
- ret = 0;
- break;
case VM_CAP_ENABLE_INVPCID:
if (cap_invpcid)
ret = 0;
@@ -3874,15 +3498,6 @@ vmx_setcap(void *arg, int vcpu, int type, int val)
reg = VMCS_PRI_PROC_BASED_CTLS;
}
break;
- case VM_CAP_UNRESTRICTED_GUEST:
- if (cap_unrestricted_guest) {
- retval = 0;
- pptr = &vmx->cap[vcpu].proc_ctls2;
- baseval = *pptr;
- flag = PROCBASED2_UNRESTRICTED_GUEST;
- reg = VMCS_SEC_PROC_BASED_CTLS;
- }
- break;
case VM_CAP_ENABLE_INVPCID:
if (cap_invpcid) {
retval = 0;
@@ -4307,20 +3922,20 @@ vmx_vlapic_init(void *arg, int vcpuid)
vlapic_vtx->pir_desc = &vmx->pir_desc[vcpuid];
vlapic_vtx->vmx = vmx;
- if (tpr_shadowing) {
+ if (vmx_cap_en(vmx, VMX_CAP_TPR_SHADOW)) {
vlapic->ops.enable_x2apic_mode = vmx_enable_x2apic_mode_ts;
}
-
- if (virtual_interrupt_delivery) {
+ if (vmx_cap_en(vmx, VMX_CAP_APICV)) {
vlapic->ops.set_intr_ready = vmx_set_intr_ready;
vlapic->ops.pending_intr = vmx_pending_intr;
vlapic->ops.intr_accepted = vmx_intr_accepted;
vlapic->ops.set_tmr = vmx_set_tmr;
vlapic->ops.enable_x2apic_mode = vmx_enable_x2apic_mode_vid;
- }
- if (posted_interrupts)
- vlapic->ops.post_intr = vmx_post_intr;
+ if (vmx_cap_en(vmx, VMX_CAP_APICV_PIR)) {
+ vlapic->ops.post_intr = vmx_post_intr;
+ }
+ }
vlapic_init(vlapic);
diff --git a/usr/src/uts/i86pc/io/vmm/intel/vmx.h b/usr/src/uts/i86pc/io/vmm/intel/vmx.h
index 3c88efba48..0fd723f9c9 100644
--- a/usr/src/uts/i86pc/io/vmm/intel/vmx.h
+++ b/usr/src/uts/i86pc/io/vmm/intel/vmx.h
@@ -29,7 +29,17 @@
*/
/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
* Copyright 2018 Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
*/
#ifndef _VMX_H_
@@ -151,6 +161,7 @@ struct vmx {
struct vmxcap cap[VM_MAXCPU];
struct vmxstate state[VM_MAXCPU];
uint64_t eptp;
+ enum vmx_caps vmx_caps;
struct vm *vm;
long eptgen[MAXCPU]; /* cached pmap->pm_eptgen */
};
@@ -158,6 +169,12 @@ CTASSERT((offsetof(struct vmx, vmcs) & PAGE_MASK) == 0);
CTASSERT((offsetof(struct vmx, msr_bitmap) & PAGE_MASK) == 0);
CTASSERT((offsetof(struct vmx, pir_desc[0]) & 63) == 0);
+static __inline bool
+vmx_cap_en(const struct vmx *vmx, enum vmx_caps cap)
+{
+ return ((vmx->vmx_caps & cap) == cap);
+}
+
#define VMX_GUEST_VMEXIT 0
#define VMX_VMRESUME_ERROR 1
#define VMX_VMLAUNCH_ERROR 2
diff --git a/usr/src/uts/i86pc/ml/cpr_wakecode.s b/usr/src/uts/i86pc/ml/cpr_wakecode.s
index 7b0d642884..c4a36a5ef6 100644
--- a/usr/src/uts/i86pc/ml/cpr_wakecode.s
+++ b/usr/src/uts/i86pc/ml/cpr_wakecode.s
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2019 Joyent, Inc.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
#include <sys/asm_linkage.h>
@@ -583,7 +584,7 @@ kernel_wc_code:
* Before proceeding, enable usage of the page table NX bit if
* that's how the page tables are set up.
*/
- bt $X86FSET_NX, x86_featureset(%rip)
+ btl $X86FSET_NX, x86_featureset(%rip)
jnc 1f
movl $MSR_AMD_EFER, %ecx
rdmsr
diff --git a/usr/src/uts/i86pc/ml/kpti_trampolines.s b/usr/src/uts/i86pc/ml/kpti_trampolines.s
index df7f1c3aae..3943fc8f3b 100644
--- a/usr/src/uts/i86pc/ml/kpti_trampolines.s
+++ b/usr/src/uts/i86pc/ml/kpti_trampolines.s
@@ -10,6 +10,7 @@
*/
/*
* Copyright 2019 Joyent, Inc.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
/*
@@ -256,7 +257,7 @@ kpti_kbase:
pushq %r14; \
subq $KPTI_R14, %rsp; \
/* Check for clobbering */ \
- cmp $0, KPTI_FLAG(%rsp); \
+ cmpq $0, KPTI_FLAG(%rsp); \
je 1f; \
/* Don't worry, this totally works */ \
int $8; \
diff --git a/usr/src/uts/i86pc/ml/locore.s b/usr/src/uts/i86pc/ml/locore.s
index 3ef051d928..4f966dc1e8 100644
--- a/usr/src/uts/i86pc/ml/locore.s
+++ b/usr/src/uts/i86pc/ml/locore.s
@@ -24,6 +24,7 @@
*/
/*
* Copyright 2019 Joyent, Inc.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
@@ -184,7 +185,7 @@
/*
* (We just assert this works by virtue of being here)
*/
- bts $X86FSET_CPUID, x86_featureset(%rip)
+ btsl $X86FSET_CPUID, x86_featureset(%rip)
/*
* mlsetup() gets called with a struct regs as argument, while
diff --git a/usr/src/uts/i86pc/ml/mpcore.s b/usr/src/uts/i86pc/ml/mpcore.s
index 249fd2aec0..3f75268e5c 100644
--- a/usr/src/uts/i86pc/ml/mpcore.s
+++ b/usr/src/uts/i86pc/ml/mpcore.s
@@ -26,6 +26,7 @@
* All rights reserved.
*
* Copyright 2019 Joyent, Inc.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
#include <sys/asm_linkage.h>
@@ -275,7 +276,7 @@ kernel_cs_code:
* Before going any further, enable usage of page table NX bit if
* that's how our page tables are set up.
*/
- bt $X86FSET_NX, x86_featureset(%rip)
+ btl $X86FSET_NX, x86_featureset(%rip)
jnc 1f
movl $MSR_AMD_EFER, %ecx
rdmsr
diff --git a/usr/src/uts/i86pc/sys/vmm.h b/usr/src/uts/i86pc/sys/vmm.h
index ad7c39271f..45838e343e 100644
--- a/usr/src/uts/i86pc/sys/vmm.h
+++ b/usr/src/uts/i86pc/sys/vmm.h
@@ -39,6 +39,7 @@
*
* Copyright 2015 Pluribus Networks Inc.
* Copyright 2019 Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
*/
#ifndef _VMM_H_
@@ -165,12 +166,19 @@ enum vm_cap_type {
VM_CAP_HALT_EXIT,
VM_CAP_MTRAP_EXIT,
VM_CAP_PAUSE_EXIT,
- VM_CAP_UNRESTRICTED_GUEST,
VM_CAP_ENABLE_INVPCID,
VM_CAP_BPT_EXIT,
VM_CAP_MAX
};
+enum vmx_caps {
+ VMX_CAP_NONE = 0,
+ VMX_CAP_TPR_SHADOW = (1UL << 0),
+ VMX_CAP_APICV = (1UL << 1),
+ VMX_CAP_APICV_X2APIC = (1UL << 2),
+ VMX_CAP_APICV_PIR = (1UL << 3),
+};
+
enum vm_intr_trigger {
EDGE_TRIGGER,
LEVEL_TRIGGER
diff --git a/usr/src/uts/intel/brand/common/brand_asm.h b/usr/src/uts/intel/brand/common/brand_asm.h
index 1d540db2a9..175b98eb7d 100644
--- a/usr/src/uts/intel/brand/common/brand_asm.h
+++ b/usr/src/uts/intel/brand/common/brand_asm.h
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
#ifndef _COMMON_BRAND_ASM_H
@@ -65,7 +66,7 @@ extern "C" {
* 24 | saved stack pointer |
* | 16 | lwp pointer |
* v 8 | user return address |
- * 0 | BRAND_CALLBACK()'s return addr |
+ * 0 | BRAND_CALLBACK()'s return addr |
* --------------------------------------
*/
@@ -182,7 +183,7 @@ extern "C" {
GET_P_BRAND_DATA(SP_REG, 0, scr); /* get p_brand_data */ \
cmp $0, scr; \
je 9f; \
- cmp $0, handler(scr); /* check handler */ \
+ cmpq $0, handler(scr); /* check handler */ \
je 9f
/*
diff --git a/usr/src/uts/intel/ia32/ml/float.s b/usr/src/uts/intel/ia32/ml/float.s
index b3c4643707..807647f553 100644
--- a/usr/src/uts/intel/ia32/ml/float.s
+++ b/usr/src/uts/intel/ia32/ml/float.s
@@ -22,6 +22,7 @@
/*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, Joyent, Inc.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
@@ -262,7 +263,7 @@
*/
ENTRY_NP(fpdisable)
- STTS(%rdi) /* set TS bit in %cr0 (disable FPU) */
+ STTS(%rdi) /* set TS bit in %cr0 (disable FPU) */
ret
SET_SIZE(fpdisable)
@@ -284,7 +285,7 @@
leaq avx_initial(%rip), %rcx
xorl %edx, %edx
movl $XFEATURE_AVX, %eax
- bt $X86FSET_AVX, x86_featureset
+ btl $X86FSET_AVX, x86_featureset
cmovael %edx, %eax
orl $(XFEATURE_LEGACY_FP | XFEATURE_SSE), %eax
xrstor (%rcx)
diff --git a/usr/src/uts/intel/kdi/kdi_idthdl.s b/usr/src/uts/intel/kdi/kdi_idthdl.s
index 77ef433184..9c50f7e23f 100644
--- a/usr/src/uts/intel/kdi/kdi_idthdl.s
+++ b/usr/src/uts/intel/kdi/kdi_idthdl.s
@@ -23,6 +23,7 @@
* Use is subject to license terms.
*
* Copyright 2018 Joyent, Inc.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
/*
@@ -71,7 +72,7 @@
pushq %r14; \
subq $KPTI_R14, %rsp; \
/* Check for clobbering */ \
- cmp $0, KPTI_FLAG(%rsp); \
+ cmpq $0, KPTI_FLAG(%rsp); \
je 1f; \
/* Don't worry, this totally works */ \
int $8; \
diff --git a/usr/src/uts/intel/os/driver_aliases b/usr/src/uts/intel/os/driver_aliases
index 73c693018d..a7d3a648a6 100644
--- a/usr/src/uts/intel/os/driver_aliases
+++ b/usr/src/uts/intel/os/driver_aliases
@@ -1331,6 +1331,8 @@ rge "pci10ec,8168"
rge "pci10ec,8169"
rge "pci16ec,116"
rge "pciex10ec,8136"
+rge "pciex10ec,8168"
+rge "pciex10ec,8169"
rtls "pci10ec,8139"
rtls "pci1113,1211"
rtls "pci1186,1300"