-/* $OpenBSD: vmm.c,v 1.214 2018/07/11 18:04:18 nayden Exp $ */
+/* $OpenBSD: vmm.c,v 1.215 2018/07/12 10:15:44 mlarkin Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
*
*/
if (vrp->vrp_continue) {
if (copyin(vrp->vrp_exit, &vcpu->vc_exit,
- sizeof(union vm_exit)) == EFAULT) {
+ sizeof(struct vm_exit)) == EFAULT) {
return (EFAULT);
}
}
vcpu->vc_state = VCPU_STATE_STOPPED;
if (copyout(&vcpu->vc_exit, vrp->vrp_exit,
- sizeof(union vm_exit)) == EFAULT) {
+ sizeof(struct vm_exit)) == EFAULT) {
ret = EFAULT;
} else
ret = 0;
}
}
+ /* Copy the VCPU register state to the exit structure */
+ if (vcpu_readregs_vmx(vcpu, VM_RWREGS_ALL, &vcpu->vc_exit.vrs))
+ ret = EINVAL;
/*
* We are heading back to userspace (vmd), either because we need help
* handling an exit, a guest interrupt is pending, or we failed in some
} else
ret = EINVAL;
+
#ifdef VMM_DEBUG
KERNEL_ASSERT_LOCKED();
#endif /* VMM_DEBUG */
/*
* We are heading back to userspace (vmd), either because we need help
* handling an exit, a guest interrupt is pending, or we failed in some
- * way to enter the guest.
+ * way to enter the guest. Copy the guest registers to the exit struct
+ * and return to vmd.
*/
+ if (vcpu_readregs_svm(vcpu, VM_RWREGS_ALL, &vcpu->vc_exit.vrs))
+ ret = EINVAL;
#ifdef VMM_DEBUG
KERNEL_ASSERT_LOCKED();
-/* $OpenBSD: vmmvar.h,v 1.55 2018/07/11 13:19:42 mlarkin Exp $ */
+/* $OpenBSD: vmmvar.h,v 1.56 2018/07/12 10:15:44 mlarkin Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
*
uint32_t vei_data; /* data */
};
-/*
- * union vm_exit
- *
- * Contains VM exit information communicated to vmd(8). This information is
- * gathered by vmm(4) from the CPU on each exit that requires help from vmd.
- */
-union vm_exit {
- struct vm_exit_inout vei; /* IN/OUT exit */
-};
-
/*
* struct vcpu_segment_info
*
size_t vmr_size;
};
+/*
+ * struct vm_exit
+ *
+ * Contains VM exit information communicated to vmd(8). This information is
+ * gathered by vmm(4) from the CPU on each exit that requires help from vmd.
+ */
+struct vm_exit {
+ union {
+ struct vm_exit_inout vei; /* IN/OUT exit */
+ };
+
+ struct vcpu_reg_state vrs;
+};
+
+
struct vm_create_params {
/* Input parameters to VMM_IOC_CREATE */
size_t vcp_nmemranges;
uint16_t vrp_irq; /* IRQ to inject */
/* Input/output parameter to VMM_IOC_RUN */
- union vm_exit *vrp_exit; /* updated exit data */
+ struct vm_exit *vrp_exit; /* updated exit data */
/* Output parameter from VMM_IOC_RUN */
uint16_t vrp_exit_reason; /* exit reason */
uint8_t vc_virt_mode;
struct cpu_info *vc_last_pcpu;
- union vm_exit vc_exit;
+ struct vm_exit vc_exit;
uint16_t vc_intr;
uint8_t vc_irqready;
-/* $OpenBSD: i8253.c,v 1.27 2018/07/09 16:11:37 mlarkin Exp $ */
+/* $OpenBSD: i8253.c,v 1.28 2018/07/12 10:15:44 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
uint8_t
vcpu_exit_i8253_misc(struct vm_run_params *vrp)
{
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
uint16_t cur;
uint64_t ns, ticks;
struct timespec now, delta;
uint8_t sel, rw, data;
uint64_t ns, ticks;
struct timespec now, delta;
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
get_input_data(vei, &out_data);
-/* $OpenBSD: i8259.c,v 1.18 2018/06/19 17:12:34 reyk Exp $ */
+/* $OpenBSD: i8259.c,v 1.19 2018/07/12 10:15:44 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
* vei: vm exit info for this I/O
*/
static void
-i8259_io_write(union vm_exit *vei)
+i8259_io_write(struct vm_exit *vei)
{
uint16_t port = vei->vei.vei_port;
uint32_t data;
* data that was read, based on the port information in 'vei'
*/
static uint8_t
-i8259_io_read(union vm_exit *vei)
+i8259_io_read(struct vm_exit *vei)
{
uint16_t port = vei->vei.vei_port;
uint8_t n = 0;
uint8_t
vcpu_exit_i8259(struct vm_run_params *vrp)
{
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
if (vei->vei.vei_dir == VEI_DIR_OUT) {
i8259_io_write(vei);
uint8_t
vcpu_exit_elcr(struct vm_run_params *vrp)
{
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
uint8_t elcr_reg = vei->vei.vei_port - ELCR0;
if (elcr_reg > 1) {
-/* $OpenBSD: mc146818.c,v 1.17 2018/07/09 16:11:37 mlarkin Exp $ */
+/* $OpenBSD: mc146818.c,v 1.18 2018/07/12 10:15:44 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
uint8_t
vcpu_exit_mc146818(struct vm_run_params *vrp)
{
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
uint16_t port = vei->vei.vei_port;
uint8_t dir = vei->vei.vei_dir;
uint32_t data = 0;
-/* $OpenBSD: ns8250.c,v 1.16 2018/07/09 16:11:37 mlarkin Exp $ */
+/* $OpenBSD: ns8250.c,v 1.17 2018/07/12 10:15:44 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
* interrupt to inject, or 0xFF if nothing to inject
*/
uint8_t
-vcpu_process_com_data(union vm_exit *vei, uint32_t vm_id, uint32_t vcpu_id)
+vcpu_process_com_data(struct vm_exit *vei, uint32_t vm_id, uint32_t vcpu_id)
{
/*
* vei_dir == VEI_DIR_OUT : out instruction
* instruction being performed
*/
void
-vcpu_process_com_lcr(union vm_exit *vei)
+vcpu_process_com_lcr(struct vm_exit *vei)
{
uint8_t data = (uint8_t)vei->vei.vei_data;
uint16_t divisor;
* instruction being performed
*/
void
-vcpu_process_com_iir(union vm_exit *vei)
+vcpu_process_com_iir(struct vm_exit *vei)
{
/*
* vei_dir == VEI_DIR_OUT : out instruction
* instruction being performed
*/
void
-vcpu_process_com_mcr(union vm_exit *vei)
+vcpu_process_com_mcr(struct vm_exit *vei)
{
/*
* vei_dir == VEI_DIR_OUT : out instruction
* instruction being performed
*/
void
-vcpu_process_com_lsr(union vm_exit *vei)
+vcpu_process_com_lsr(struct vm_exit *vei)
{
/*
* vei_dir == VEI_DIR_OUT : out instruction
* instruction being performed
*/
void
-vcpu_process_com_msr(union vm_exit *vei)
+vcpu_process_com_msr(struct vm_exit *vei)
{
/*
* vei_dir == VEI_DIR_OUT : out instruction
* instruction being performed
*/
void
-vcpu_process_com_scr(union vm_exit *vei)
+vcpu_process_com_scr(struct vm_exit *vei)
{
/*
* vei_dir == VEI_DIR_OUT : out instruction
* instruction being performed
*/
void
-vcpu_process_com_ier(union vm_exit *vei)
+vcpu_process_com_ier(struct vm_exit *vei)
{
/*
* vei_dir == VEI_DIR_OUT : out instruction
vcpu_exit_com(struct vm_run_params *vrp)
{
uint8_t intr = 0xFF;
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
mutex_lock(&com1_dev.mutex);
-/* $OpenBSD: ns8250.h,v 1.5 2017/06/07 14:53:28 mlarkin Exp $ */
+/* $OpenBSD: ns8250.h,v 1.6 2018/07/12 10:15:44 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
void ns8250_init(int, uint32_t);
uint8_t vcpu_exit_com(struct vm_run_params *);
-uint8_t vcpu_process_com_data(union vm_exit *, uint32_t, uint32_t);
-void vcpu_process_com_lcr(union vm_exit *);
-void vcpu_process_com_lsr(union vm_exit *);
-void vcpu_process_com_ier(union vm_exit *);
-void vcpu_process_com_mcr(union vm_exit *);
-void vcpu_process_com_iir(union vm_exit *);
-void vcpu_process_com_msr(union vm_exit *);
-void vcpu_process_com_scr(union vm_exit *);
+uint8_t vcpu_process_com_data(struct vm_exit *, uint32_t, uint32_t);
+void vcpu_process_com_lcr(struct vm_exit *);
+void vcpu_process_com_lsr(struct vm_exit *);
+void vcpu_process_com_ier(struct vm_exit *);
+void vcpu_process_com_mcr(struct vm_exit *);
+void vcpu_process_com_iir(struct vm_exit *);
+void vcpu_process_com_msr(struct vm_exit *);
+void vcpu_process_com_scr(struct vm_exit *);
int ns8250_dump(int);
int ns8250_restore(int, int, uint32_t);
-/* $OpenBSD: pci.c,v 1.26 2018/07/10 20:43:15 reyk Exp $ */
+/* $OpenBSD: pci.c,v 1.27 2018/07/12 10:15:44 mlarkin Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
void
pci_handle_address_reg(struct vm_run_params *vrp)
{
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
/*
* vei_dir == VEI_DIR_OUT : out instruction
int i, j, k, l;
uint16_t reg, b_hi, b_lo;
pci_iobar_fn_t fn;
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
uint8_t intr, dir;
k = -1;
void
pci_handle_data_reg(struct vm_run_params *vrp)
{
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
uint8_t b, d, f, o, baridx, ofs, sz;
int ret;
pci_cs_fn_t csfunc;
-/* $OpenBSD: vm.c,v 1.36 2018/07/10 08:40:20 mlarkin Exp $ */
+/* $OpenBSD: vm.c,v 1.37 2018/07/12 10:15:44 mlarkin Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
/* caller will exit, so skip freeing */
return (ENOMEM);
}
- vrp[i]->vrp_exit = malloc(sizeof(union vm_exit));
+ vrp[i]->vrp_exit = malloc(sizeof(struct vm_exit));
if (vrp[i]->vrp_exit == NULL) {
log_warn("%s: memory allocation error - "
"exiting.", __progname);
uint8_t
vcpu_exit_pci(struct vm_run_params *vrp)
{
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
uint8_t intr;
intr = 0xFF;
void
vcpu_exit_inout(struct vm_run_params *vrp)
{
- union vm_exit *vei = vrp->vrp_exit;
+ struct vm_exit *vei = vrp->vrp_exit;
uint8_t intr = 0xFF;
if (ioports_map[vei->vei.vei_port] != NULL)
* data: return data
*/
void
-set_return_data(union vm_exit *vei, uint32_t data)
+set_return_data(struct vm_exit *vei, uint32_t data)
{
switch (vei->vei.vei_size) {
case 1:
* data: location to store the result
*/
void
-get_input_data(union vm_exit *vei, uint32_t *data)
+get_input_data(struct vm_exit *vei, uint32_t *data)
{
switch (vei->vei.vei_size) {
case 1:
void vcpu_assert_pic_irq(uint32_t, uint32_t, int);
void vcpu_deassert_pic_irq(uint32_t, uint32_t, int);
-void set_return_data(union vm_exit *, uint32_t);
-void get_input_data(union vm_exit *, uint32_t *);
+void set_return_data(struct vm_exit *, uint32_t);
+void get_input_data(struct vm_exit *, uint32_t *);