-/* $OpenBSD: vmm.c,v 1.137 2017/04/28 10:09:37 mlarkin Exp $ */
+/* $OpenBSD: vmm.c,v 1.138 2017/05/02 02:57:46 mlarkin Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
*
uint64_t sel, limit, ar;
uint64_t *gprs = vrs->vrs_gprs;
uint64_t *crs = vrs->vrs_crs;
+ uint64_t *msrs = vrs->vrs_msrs;
struct vcpu_segment_info *sregs = vrs->vrs_sregs;
+ struct vmx_msr_store *msr_store;
if (vcpu_reload_vmcs_vmx(&vcpu->vc_control_pa))
return (EINVAL);
goto errout;
}
+ msr_store = (struct vmx_msr_store *)vcpu->vc_vmx_msr_exit_save_va;
+
+ if (regmask & VM_RWREGS_MSRS) {
+ for (i = 0; i < VCPU_REGS_NMSRS; i++) {
+ msrs[i] = msr_store[i].vms_data;
+ }
+ }
+
goto out;
errout:
uint64_t limit, ar;
uint64_t *gprs = vrs->vrs_gprs;
uint64_t *crs = vrs->vrs_crs;
+ uint64_t *msrs = vrs->vrs_msrs;
struct vcpu_segment_info *sregs = vrs->vrs_sregs;
+ struct vmx_msr_store *msr_store;
if (loadvmcs) {
if (vcpu_reload_vmcs_vmx(&vcpu->vc_control_pa))
goto errout;
}
+ msr_store = (struct vmx_msr_store *)vcpu->vc_vmx_msr_exit_save_va;
+
+ if (regmask & VM_RWREGS_MSRS) {
+ for (i = 0; i < VCPU_REGS_NMSRS; i++) {
+ msr_store[i].vms_data = msrs[i];
+ }
+ }
+
goto out;
errout:
* IA32_VMX_LOAD_DEBUG_CONTROLS
* IA32_VMX_LOAD_IA32_PERF_GLOBAL_CTRL_ON_ENTRY
*/
- if (ug == 1)
+ if (ug == 1 && !(vrs->vrs_msrs[VCPU_REGS_EFER] & EFER_LMA))
want1 = 0;
else
want1 = IA32_VMX_IA32E_MODE_GUEST;
*/
msr_store = (struct vmx_msr_store *)vcpu->vc_vmx_msr_exit_save_va;
- /*
- * Make sure LME is enabled in EFER if restricted guest mode is
- * needed.
- */
- msr_store[0].vms_index = MSR_EFER;
- if (ug == 1)
- msr_store[0].vms_data = 0ULL; /* Initial value */
- else
- msr_store[0].vms_data = EFER_LME;
-
- msr_store[1].vms_index = MSR_STAR;
- msr_store[1].vms_data = 0ULL; /* Initial value */
- msr_store[2].vms_index = MSR_LSTAR;
- msr_store[2].vms_data = 0ULL; /* Initial value */
- msr_store[3].vms_index = MSR_CSTAR;
- msr_store[3].vms_data = 0ULL; /* Initial value */
- msr_store[4].vms_index = MSR_SFMASK;
- msr_store[4].vms_data = 0ULL; /* Initial value */
- msr_store[5].vms_index = MSR_KERNELGSBASE;
- msr_store[5].vms_data = 0ULL; /* Initial value */
+ msr_store[VCPU_REGS_EFER].vms_index = MSR_EFER;
+ msr_store[VCPU_REGS_STAR].vms_index = MSR_STAR;
+ msr_store[VCPU_REGS_LSTAR].vms_index = MSR_LSTAR;
+ msr_store[VCPU_REGS_CSTAR].vms_index = MSR_CSTAR;
+ msr_store[VCPU_REGS_SFMASK].vms_index = MSR_SFMASK;
+ msr_store[VCPU_REGS_KGSBASE].vms_index = MSR_KERNELGSBASE;
/*
* Currently we have the same count of entry/exit MSRs loads/stores
*/
ret = vcpu_writeregs_vmx(vcpu, VM_RWREGS_ALL, 0, vrs);
+ /*
+ * Make sure LME is enabled in EFER if restricted guest mode is
+ * needed.
+ */
+ if (ug == 0)
+ msr_store[VCPU_REGS_EFER].vms_data |= EFER_LME;
+
/*
* Set up the MSR bitmap
*/
return (EINVAL);
}
- if (msr_store[0].vms_data & EFER_LME)
+ if (msr_store[VCPU_REGS_EFER].vms_data & EFER_LME)
ectls |= IA32_VMX_IA32E_MODE_GUEST;
else
ectls &= ~IA32_VMX_IA32E_MODE_GUEST;
-/* $OpenBSD: vmmvar.h,v 1.35 2017/04/28 07:44:36 mlarkin Exp $ */
+/* $OpenBSD: vmmvar.h,v 1.36 2017/05/02 02:57:46 mlarkin Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
*
#define VCPU_REGS_TR 7
#define VCPU_REGS_NSREGS (VCPU_REGS_TR + 1)
+#define VCPU_REGS_EFER 0
+#define VCPU_REGS_STAR 1
+#define VCPU_REGS_LSTAR 2
+#define VCPU_REGS_CSTAR 3
+#define VCPU_REGS_SFMASK 4
+#define VCPU_REGS_KGSBASE 5
+#define VCPU_REGS_NMSRS (VCPU_REGS_KGSBASE + 1)
+
struct vcpu_reg_state {
uint64_t vrs_gprs[VCPU_REGS_NGPRS];
uint64_t vrs_crs[VCPU_REGS_NCRS];
+ uint64_t vrs_msrs[VCPU_REGS_NMSRS];
struct vcpu_segment_info vrs_sregs[VCPU_REGS_NSREGS];
struct vcpu_segment_info vrs_gdtr;
struct vcpu_segment_info vrs_idtr;
#define VM_RWREGS_GPRS 0x1 /* read/write GPRs */
#define VM_RWREGS_SREGS 0x2 /* read/write segment registers */
#define VM_RWREGS_CRS 0x4 /* read/write CRs */
-#define VM_RWREGS_ALL (VM_RWREGS_GPRS | VM_RWREGS_SREGS | VM_RWREGS_CRS)
+#define VM_RWREGS_MSRS 0x8 /* read/write MSRs */
+#define VM_RWREGS_ALL (VM_RWREGS_GPRS | VM_RWREGS_SREGS | VM_RWREGS_CRS | \
+ VM_RWREGS_MSRS)
struct vm_rwregs_params {
uint32_t vrwp_vm_id;