summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormlarkin <mlarkin@openbsd.org>2018-07-12 10:15:44 +0000
committermlarkin <mlarkin@openbsd.org>2018-07-12 10:15:44 +0000
commit02ee787fcd78d11b22dcab625f1f53fd122b6cd9 (patch)
tree5c696e1af8ef99114bac6d50e87686b774b6050f
parentrc(8) infrastructure for rad (diff)
downloadwireguard-openbsd-02ee787fcd78d11b22dcab625f1f53fd122b6cd9.tar.xz
wireguard-openbsd-02ee787fcd78d11b22dcab625f1f53fd122b6cd9.zip
vmm(8)/vmm(4): send a copy of the guest register state to vmd on exit,
avoiding multiple readregs ioctls back to vmm in case register content is needed subsequently. ok phessler
-rw-r--r--sys/arch/amd64/amd64/vmm.c15
-rw-r--r--sys/arch/amd64/include/vmmvar.h31
-rw-r--r--usr.sbin/vmd/i8253.c6
-rw-r--r--usr.sbin/vmd/i8259.c10
-rw-r--r--usr.sbin/vmd/mc146818.c4
-rw-r--r--usr.sbin/vmd/ns8250.c20
-rw-r--r--usr.sbin/vmd/ns8250.h18
-rw-r--r--usr.sbin/vmd/pci.c8
-rw-r--r--usr.sbin/vmd/vm.c12
-rw-r--r--usr.sbin/vmd/vmm.h4
10 files changed, 70 insertions, 58 deletions
diff --git a/sys/arch/amd64/amd64/vmm.c b/sys/arch/amd64/amd64/vmm.c
index 1b67245908e..b9052f92a81 100644
--- a/sys/arch/amd64/amd64/vmm.c
+++ b/sys/arch/amd64/amd64/vmm.c
@@ -1,4 +1,4 @@
-/* $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>
*
@@ -3740,7 +3740,7 @@ vm_run(struct vm_run_params *vrp)
*/
if (vrp->vrp_continue) {
if (copyin(vrp->vrp_exit, &vcpu->vc_exit,
- sizeof(union vm_exit)) == EFAULT) {
+ sizeof(struct vm_exit)) == EFAULT) {
return (EFAULT);
}
}
@@ -3773,7 +3773,7 @@ vm_run(struct vm_run_params *vrp)
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;
@@ -4272,6 +4272,9 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp)
}
}
+ /* 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
@@ -4285,6 +4288,7 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp)
} else
ret = EINVAL;
+
#ifdef VMM_DEBUG
KERNEL_ASSERT_LOCKED();
#endif /* VMM_DEBUG */
@@ -6398,8 +6402,11 @@ vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp)
/*
* 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();
diff --git a/sys/arch/amd64/include/vmmvar.h b/sys/arch/amd64/include/vmmvar.h
index 033bb6e21e8..0bbe2aef46d 100644
--- a/sys/arch/amd64/include/vmmvar.h
+++ b/sys/arch/amd64/include/vmmvar.h
@@ -1,4 +1,4 @@
-/* $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>
*
@@ -352,16 +352,6 @@ struct vm_exit_inout {
};
/*
- * 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
*
* Describes a segment + selector set, used in constructing the initial vcpu
@@ -440,6 +430,21 @@ struct vm_mem_range {
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;
@@ -465,7 +470,7 @@ struct vm_run_params {
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 */
@@ -845,7 +850,7 @@ struct vcpu {
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;
diff --git a/usr.sbin/vmd/i8253.c b/usr.sbin/vmd/i8253.c
index 14c10f31bd7..cf2dfd2d744 100644
--- a/usr.sbin/vmd/i8253.c
+++ b/usr.sbin/vmd/i8253.c
@@ -1,4 +1,4 @@
-/* $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>
*
@@ -137,7 +137,7 @@ i8253_do_readback(uint32_t data)
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;
@@ -197,7 +197,7 @@ vcpu_exit_i8253(struct vm_run_params *vrp)
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);
diff --git a/usr.sbin/vmd/i8259.c b/usr.sbin/vmd/i8259.c
index 1922e9bf827..deb731422c9 100644
--- a/usr.sbin/vmd/i8259.c
+++ b/usr.sbin/vmd/i8259.c
@@ -1,4 +1,4 @@
-/* $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>
*
@@ -586,7 +586,7 @@ i8259_read_cmdreg(uint8_t n)
* 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;
@@ -627,7 +627,7 @@ i8259_io_write(union vm_exit *vei)
* 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;
@@ -670,7 +670,7 @@ i8259_io_read(union vm_exit *vei)
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);
@@ -728,7 +728,7 @@ pic_set_elcr(uint8_t irq, uint8_t val)
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) {
diff --git a/usr.sbin/vmd/mc146818.c b/usr.sbin/vmd/mc146818.c
index 4392af5be39..014232c7aab 100644
--- a/usr.sbin/vmd/mc146818.c
+++ b/usr.sbin/vmd/mc146818.c
@@ -1,4 +1,4 @@
-/* $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>
*
@@ -259,7 +259,7 @@ rtc_update_regb(uint32_t data)
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;
diff --git a/usr.sbin/vmd/ns8250.c b/usr.sbin/vmd/ns8250.c
index 2348422d12e..74e86a92954 100644
--- a/usr.sbin/vmd/ns8250.c
+++ b/usr.sbin/vmd/ns8250.c
@@ -1,4 +1,4 @@
-/* $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>
*
@@ -216,7 +216,7 @@ com_rcv(struct ns8250_dev *com, uint32_t vm_id, uint32_t vcpu_id)
* 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
@@ -299,7 +299,7 @@ vcpu_process_com_data(union vm_exit *vei, uint32_t vm_id, uint32_t vcpu_id)
* 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;
@@ -352,7 +352,7 @@ vcpu_process_com_lcr(union vm_exit *vei)
* 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
@@ -391,7 +391,7 @@ vcpu_process_com_iir(union vm_exit *vei)
* 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
@@ -420,7 +420,7 @@ vcpu_process_com_mcr(union vm_exit *vei)
* 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
@@ -452,7 +452,7 @@ vcpu_process_com_lsr(union vm_exit *vei)
* 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
@@ -484,7 +484,7 @@ vcpu_process_com_msr(union vm_exit *vei)
* 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
@@ -514,7 +514,7 @@ vcpu_process_com_scr(union vm_exit *vei)
* 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
@@ -560,7 +560,7 @@ uint8_t
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);
diff --git a/usr.sbin/vmd/ns8250.h b/usr.sbin/vmd/ns8250.h
index 6c861107e67..0edeeb95a39 100644
--- a/usr.sbin/vmd/ns8250.h
+++ b/usr.sbin/vmd/ns8250.h
@@ -1,4 +1,4 @@
-/* $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>
*
@@ -60,13 +60,13 @@ struct ns8250_dev {
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);
diff --git a/usr.sbin/vmd/pci.c b/usr.sbin/vmd/pci.c
index 6395c981a2e..ef7053e9594 100644
--- a/usr.sbin/vmd/pci.c
+++ b/usr.sbin/vmd/pci.c
@@ -1,4 +1,4 @@
-/* $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>
@@ -228,7 +228,7 @@ pci_init(void)
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
@@ -253,7 +253,7 @@ pci_handle_io(struct vm_run_params *vrp)
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;
@@ -303,7 +303,7 @@ pci_handle_io(struct vm_run_params *vrp)
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;
diff --git a/usr.sbin/vmd/vm.c b/usr.sbin/vmd/vm.c
index 2f57d769ae9..67252e5cf89 100644
--- a/usr.sbin/vmd/vm.c
+++ b/usr.sbin/vmd/vm.c
@@ -1,4 +1,4 @@
-/* $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>
@@ -1108,7 +1108,7 @@ run_vm(int child_cdrom, int *child_disks, int *child_taps,
/* 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);
@@ -1394,7 +1394,7 @@ vcpu_pic_intr(uint32_t vm_id, uint32_t vcpu_id, uint8_t intr)
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;
@@ -1433,7 +1433,7 @@ vcpu_exit_pci(struct vm_run_params *vrp)
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)
@@ -1873,7 +1873,7 @@ mutex_unlock(pthread_mutex_t *m)
* 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:
@@ -1903,7 +1903,7 @@ set_return_data(union vm_exit *vei, uint32_t data)
* 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:
diff --git a/usr.sbin/vmd/vmm.h b/usr.sbin/vmd/vmm.h
index 084554fc87c..214d41d01ea 100644
--- a/usr.sbin/vmd/vmm.h
+++ b/usr.sbin/vmd/vmm.h
@@ -20,5 +20,5 @@ typedef uint8_t (*io_fn_t)(struct vm_run_params *);
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 *);