summaryrefslogtreecommitdiffstats
path: root/usr.sbin/vmd
diff options
context:
space:
mode:
authormlarkin <mlarkin@openbsd.org>2017-03-25 07:46:24 +0000
committermlarkin <mlarkin@openbsd.org>2017-03-25 07:46:24 +0000
commit46635426ba6e01201f3d8e14a59ae7bfe1afe7ee (patch)
treee8d11ec434ae50a46f84ea9d208a1e7434abf037 /usr.sbin/vmd
parentMore PCI extended capabilities handling in pcidump. (diff)
downloadwireguard-openbsd-46635426ba6e01201f3d8e14a59ae7bfe1afe7ee.tar.xz
wireguard-openbsd-46635426ba6e01201f3d8e14a59ae7bfe1afe7ee.zip
Introduce a new function to obtain properly sized input data, and convert
i8253/i8259/mc146818 emulation to use this.
Diffstat (limited to 'usr.sbin/vmd')
-rw-r--r--usr.sbin/vmd/i8253.c4
-rw-r--r--usr.sbin/vmd/i8259.c4
-rw-r--r--usr.sbin/vmd/mc146818.c20
-rw-r--r--usr.sbin/vmd/vm.c25
-rw-r--r--usr.sbin/vmd/vmm.h1
5 files changed, 36 insertions, 18 deletions
diff --git a/usr.sbin/vmd/i8253.c b/usr.sbin/vmd/i8253.c
index 3f9b7383d7b..2979d492a93 100644
--- a/usr.sbin/vmd/i8253.c
+++ b/usr.sbin/vmd/i8253.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i8253.c,v 1.9 2017/03/24 11:08:43 reyk Exp $ */
+/* $OpenBSD: i8253.c,v 1.10 2017/03/25 07:46:24 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
@@ -133,7 +133,7 @@ vcpu_exit_i8253(struct vm_run_params *vrp)
struct timeval now, delta;
union vm_exit *vei = vrp->vrp_exit;
- out_data = vei->vei.vei_data & 0xFF;
+ out_data = get_input_data(vei);
if (vei->vei.vei_port == TIMER_CTRL) {
if (vei->vei.vei_dir == VEI_DIR_OUT) { /* OUT instruction */
diff --git a/usr.sbin/vmd/i8259.c b/usr.sbin/vmd/i8259.c
index 1be0daf0251..61229d79b6f 100644
--- a/usr.sbin/vmd/i8259.c
+++ b/usr.sbin/vmd/i8259.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i8259.c,v 1.10 2017/03/24 11:08:43 reyk Exp $ */
+/* $OpenBSD: i8259.c,v 1.11 2017/03/25 07:46:24 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
@@ -556,7 +556,7 @@ static void
i8259_io_write(union vm_exit *vei)
{
uint16_t port = vei->vei.vei_port;
- uint8_t data = vei->vei.vei_data;
+ uint8_t data = get_input_data(vei);
uint8_t n = 0;
switch (port) {
diff --git a/usr.sbin/vmd/mc146818.c b/usr.sbin/vmd/mc146818.c
index 59b5c57a2c9..5c265457dde 100644
--- a/usr.sbin/vmd/mc146818.c
+++ b/usr.sbin/vmd/mc146818.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mc146818.c,v 1.8 2017/03/23 07:59:41 mlarkin Exp $ */
+/* $OpenBSD: mc146818.c,v 1.9 2017/03/25 07:46:24 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
@@ -249,7 +249,9 @@ vcpu_exit_mc146818(struct vm_run_params *vrp)
union vm_exit *vei = vrp->vrp_exit;
uint16_t port = vei->vei.vei_port;
uint8_t dir = vei->vei.vei_dir;
- uint32_t data = vei->vei.vei_data & 0xFF;
+ uint32_t data;
+
+ data = get_input_data(vei);
if (port == IO_RTC) {
/* Discard NMI bit */
@@ -259,16 +261,10 @@ vcpu_exit_mc146818(struct vm_run_params *vrp)
if (dir == 0) {
if (data < (NVRAM_SIZE))
rtc.idx = data;
- else {
- log_warnx("%s: mc146818 bogus register 0x%x",
- __func__, data);
+ else
rtc.idx = MC_REGD;
- }
- } else {
- log_warnx("%s: mc146818 illegal read from port 0x%x",
- __func__, port);
- set_return_data(vei, 0xFF);
- }
+ } else
+ set_return_data(vei, rtc.idx);
} else if (port == IO_RTC + 1) {
if (dir == 0) {
switch (rtc.idx) {
@@ -291,7 +287,6 @@ vcpu_exit_mc146818(struct vm_run_params *vrp)
log_warnx("%s: mc146818 illegal reg %x\n",
__func__, rtc.idx);
}
- rtc.idx = MC_REGD;
} else {
data = rtc.regs[rtc.idx];
set_return_data(vei, data);
@@ -300,7 +295,6 @@ vcpu_exit_mc146818(struct vm_run_params *vrp)
/* Reset IRQ state */
rtc.regs[MC_REGC] &= ~MC_REGC_PF;
}
- rtc.idx = MC_REGD;
}
} else {
log_warnx("%s: mc146818 unknown port 0x%x",
diff --git a/usr.sbin/vmd/vm.c b/usr.sbin/vmd/vm.c
index 896364b7c07..ad3ca6d25c6 100644
--- a/usr.sbin/vmd/vm.c
+++ b/usr.sbin/vmd/vm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm.c,v 1.6 2017/03/24 08:04:02 mlarkin Exp $ */
+/* $OpenBSD: vm.c,v 1.7 2017/03/25 07:46:24 mlarkin Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -1333,3 +1333,26 @@ set_return_data(union vm_exit *vei, uint32_t data)
break;
}
}
+
+/*
+ * get_input_data
+ *
+ * Utility function for manipulating register data in vm exit info structs. This
+ * function ensures that the data is copied from the vei->vei.vei_data field with
+ * the proper size for the operation being performed.
+ *
+ * Parameters:
+ * vei: exit information
+ */
+uint32_t
+get_input_data(union vm_exit *vei)
+{
+ switch (vei->vei.vei_size) {
+ case 1: return vei->vei.vei_data & 0xFF;
+ case 2: return vei->vei.vei_data & 0xFFFF;
+ case 4: return vei->vei.vei_data;
+ }
+
+ log_warnx("%s: invalid i/o size %d", __func__, vei->vei.vei_size);
+ return 0;
+}
diff --git a/usr.sbin/vmd/vmm.h b/usr.sbin/vmd/vmm.h
index 0104225dae9..5e5bb50dceb 100644
--- a/usr.sbin/vmd/vmm.h
+++ b/usr.sbin/vmd/vmm.h
@@ -20,3 +20,4 @@ typedef uint8_t (*io_fn_t)(struct vm_run_params *);
void vcpu_assert_pic_irq(uint32_t, uint32_t, int);
void set_return_data(union vm_exit *, uint32_t);
+uint32_t get_input_data(union vm_exit *);