untrusted comment: verify with openbsd-63-base.pub
RWRxzbLwAd76ZcGXQxuE4EzAxQPXnp04MmBnvADaNIPBq5VwHNe+UlgOJyvdYHkQj/xJVnovt1uCYPCR8+R68RfF07liSZVpzgI=
OpenBSD 6.3 errata 032, March 27, 2019:
GDT and IDT limits were improperly restored during VMM context switches.
Apply by doing:
signify -Vep /etc/signify/openbsd-63-base.pub -x 032_vmmints.patch.sig \
-m - | (cd /usr/src && patch -p0)
And then rebuild and install a new kernel:
KK=`sysctl -n kern.osversion | cut -d# -f1`
cd /usr/src/sys/arch/`machine`/compile/$KK
make obj
make config
make
make install
Index: sys/arch/amd64/amd64/vmm.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/vmm.c,v
diff -u -p -u -r1.185.2.2 vmm.c
--- sys/arch/amd64/amd64/vmm.c 22 Aug 2018 22:58:53 -0000 1.185.2.2
+++ sys/arch/amd64/amd64/vmm.c 26 Mar 2019 04:50:54 -0000
@@ -291,6 +291,30 @@ extern struct gate_descriptor *idt;
#define CR_CLTS 2
#define CR_LMSW 3
+static __inline void
+sidt(void *p)
+{
+ __asm volatile("sidt (%0)" : : "r" (p) : "memory");
+}
+
+static __inline void
+sgdt(void *p)
+{
+ __asm volatile("sgdt (%0)" : : "r" (p) : "memory");
+}
+
+static __inline void
+bare_lgdt(struct region_descriptor *p)
+{
+ __asm volatile("lgdt (%0)" : : "r" (p) : "memory");
+}
+
+static __inline void
+sldt(u_short *sel)
+{
+ __asm volatile("sldt (%0)" : : "r" (sel) : "memory");
+}
+
/*
* vmm_enabled
*
@@ -3916,7 +3940,8 @@ vcpu_run_vmx(struct vcpu *vcpu, struct v
struct schedstate_percpu *spc;
struct vmx_invvpid_descriptor vid;
uint64_t eii, procbased, int_st;
- uint16_t irq;
+ uint16_t irq, ldt_sel;
+ struct region_descriptor gdtr, idtr;
resume = 0;
irq = vrp->vrp_irq;
@@ -4117,10 +4142,18 @@ vcpu_run_vmx(struct vcpu *vcpu, struct v
break;
}
+ sgdt(&gdtr);
+ sidt(&idtr);
+ sldt(&ldt_sel);
+
KERNEL_UNLOCK();
ret = vmx_enter_guest(&vcpu->vc_control_pa,
&vcpu->vc_gueststate, resume,
curcpu()->ci_vmm_cap.vcc_vmx.vmx_has_l1_flush_msr);
+
+ bare_lgdt(&gdtr);
+ lidt(&idtr);
+ lldt(ldt_sel);
/*
* On exit, interrupts are disabled, and we are running with
Index: sys/arch/i386/i386/vmm.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/Attic/vmm.c,v
diff -u -p -u -r1.36 vmm.c
--- sys/arch/i386/i386/vmm.c 22 Mar 2018 19:30:19 -0000 1.36
+++ sys/arch/i386/i386/vmm.c 26 Mar 2019 05:25:42 -0000
@@ -263,6 +263,30 @@ extern int cpu_pae;
#define CR_CLTS 2
#define CR_LMSW 3
+static __inline void
+bare_lgdt(struct region_descriptor *p)
+{
+ __asm volatile("lgdt (%0)" : : "r" (p) : "memory");
+}
+
+static __inline void
+sidt(void *p)
+{
+ __asm volatile("sidt (%0)" : : "r" (p) : "memory");
+}
+
+static __inline void
+sgdt(void *p)
+{
+ __asm volatile("sgdt (%0)" : : "r" (p) : "memory");
+}
+
+static __inline void
+sldt(u_short *sel)
+{
+ __asm volatile("sldt (%0)" : : "r" (sel) : "memory");
+}
+
/*
* vmm_enabled
*
@@ -3360,7 +3384,8 @@ vcpu_run_vmx(struct vcpu *vcpu, struct v
struct schedstate_percpu *spc;
struct vmx_invvpid_descriptor vid;
uint32_t eii, procbased;
- uint16_t irq;
+ uint16_t irq, ldt_sel;
+ struct region_descriptor gdtr, idtr;
resume = 0;
irq = vrp->vrp_irq;
@@ -3505,11 +3530,19 @@ vcpu_run_vmx(struct vcpu *vcpu, struct v
vid.vid_addr = 0ULL;
invvpid(IA32_VMX_INVVPID_SINGLE_CTX_GLB, &vid);
+ sgdt(&gdtr);
+ sidt(&idtr);
+ sldt(&ldt_sel);
+
/* Start / resume the VCPU */
KERNEL_ASSERT_LOCKED();
KERNEL_UNLOCK();
ret = vmx_enter_guest(&vcpu->vc_control_pa,
&vcpu->vc_gueststate, resume, gdt.rd_base);
+
+ bare_lgdt(&gdtr);
+ lidt(&idtr);
+ lldt(ldt_sel);
exit_reason = VM_EXIT_NONE;
if (ret == 0) {