summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormlarkin <mlarkin@openbsd.org>2018-07-09 16:11:37 +0000
committermlarkin <mlarkin@openbsd.org>2018-07-09 16:11:37 +0000
commit7b36e131d56f6465b99f23042c66e678db30d8b1 (patch)
treee7ff4a2528babca983130e02fd089e961155af3d
parentvmd(8): better debug message in a failure case (diff)
downloadwireguard-openbsd-7b36e131d56f6465b99f23042c66e678db30d8b1.tar.xz
wireguard-openbsd-7b36e131d56f6465b99f23042c66e678db30d8b1.zip
vmd(8): deassert interrupt pins in the PIC at the right times. Helps fix
situations where vmd gets stuck at 100% cpu usage because the guest VM is constantly trying to ack interrupts that already occurred. tested by phessler on a VM that used to exhibit the issue. ok phessler
-rw-r--r--usr.sbin/vmd/i8253.c3
-rw-r--r--usr.sbin/vmd/mc146818.c3
-rw-r--r--usr.sbin/vmd/ns8250.c9
-rw-r--r--usr.sbin/vmd/virtio.c11
4 files changed, 17 insertions, 9 deletions
diff --git a/usr.sbin/vmd/i8253.c b/usr.sbin/vmd/i8253.c
index 4d4943ab27c..14c10f31bd7 100644
--- a/usr.sbin/vmd/i8253.c
+++ b/usr.sbin/vmd/i8253.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i8253.c,v 1.26 2018/06/19 17:12:34 reyk Exp $ */
+/* $OpenBSD: i8253.c,v 1.27 2018/07/09 16:11:37 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
@@ -339,6 +339,7 @@ i8253_fire(int fd, short type, void *arg)
struct i8253_channel *ctr = (struct i8253_channel *)arg;
vcpu_assert_pic_irq(ctr->vm_id, 0, 0);
+ vcpu_deassert_pic_irq(ctr->vm_id, 0, 0);
if (ctr->mode != TIMER_INTTC) {
timerclear(&tv);
diff --git a/usr.sbin/vmd/mc146818.c b/usr.sbin/vmd/mc146818.c
index 8e77b631300..4392af5be39 100644
--- a/usr.sbin/vmd/mc146818.c
+++ b/usr.sbin/vmd/mc146818.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mc146818.c,v 1.16 2018/02/28 06:53:25 pd Exp $ */
+/* $OpenBSD: mc146818.c,v 1.17 2018/07/09 16:11:37 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
@@ -129,6 +129,7 @@ rtc_fireper(int fd, short type, void *arg)
rtc.regs[MC_REGC] |= MC_REGC_PF;
vcpu_assert_pic_irq((ptrdiff_t)arg, 0, 8);
+ vcpu_deassert_pic_irq((ptrdiff_t)arg, 0, 8);
evtimer_add(&rtc.per, &rtc.per_tv);
}
diff --git a/usr.sbin/vmd/ns8250.c b/usr.sbin/vmd/ns8250.c
index a893a43bb6b..2348422d12e 100644
--- a/usr.sbin/vmd/ns8250.c
+++ b/usr.sbin/vmd/ns8250.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ns8250.c,v 1.15 2018/06/19 17:12:34 reyk Exp $ */
+/* $OpenBSD: ns8250.c,v 1.16 2018/07/09 16:11:37 mlarkin Exp $ */
/*
* Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
*
@@ -58,6 +58,7 @@ ratelimit(int fd, short type, void *arg)
com1_dev.regs.iir |= IIR_TXRDY;
com1_dev.regs.iir &= ~IIR_NOPEND;
vcpu_assert_pic_irq(com1_dev.vmid, 0, com1_dev.irq);
+ vcpu_deassert_pic_irq(com1_dev.vmid, 0, com1_dev.irq);
}
void
@@ -127,6 +128,7 @@ com_rcv_event(int fd, short kind, void *arg)
if ((com1_dev.regs.iir & IIR_NOPEND) == 0) {
/* XXX: vcpu_id */
vcpu_assert_pic_irq((uintptr_t)arg, 0, com1_dev.irq);
+ vcpu_deassert_pic_irq((uintptr_t)arg, 0, com1_dev.irq);
}
}
@@ -592,11 +594,6 @@ vcpu_exit_com(struct vm_run_params *vrp)
mutex_unlock(&com1_dev.mutex);
- if ((com1_dev.regs.iir & IIR_NOPEND)) {
- /* XXX: vcpu_id */
- vcpu_deassert_pic_irq(com1_dev.vmid, 0, com1_dev.irq);
- }
-
return (intr);
}
diff --git a/usr.sbin/vmd/virtio.c b/usr.sbin/vmd/virtio.c
index 599dda467bf..4622ef4943f 100644
--- a/usr.sbin/vmd/virtio.c
+++ b/usr.sbin/vmd/virtio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: virtio.c,v 1.62 2018/07/09 08:43:09 mlarkin Exp $ */
+/* $OpenBSD: virtio.c,v 1.63 2018/07/09 16:11:37 mlarkin Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -308,6 +308,7 @@ virtio_rnd_io(int dir, uint16_t reg, uint32_t *data, uint8_t *intr,
case VIRTIO_CONFIG_ISR_STATUS:
*data = viornd.cfg.isr_status;
viornd.cfg.isr_status = 0;
+ vcpu_deassert_pic_irq(viornd.vm_id, 0, viornd.irq);
break;
}
}
@@ -759,6 +760,7 @@ virtio_blk_io(int dir, uint16_t reg, uint32_t *data, uint8_t *intr,
dev->cfg.queue_notify = 0;
dev->cfg.isr_status = 0;
dev->vq[0].last_avail = 0;
+ vcpu_deassert_pic_irq(dev->vm_id, 0, dev->irq);
}
break;
default:
@@ -927,6 +929,7 @@ virtio_blk_io(int dir, uint16_t reg, uint32_t *data, uint8_t *intr,
case VIRTIO_CONFIG_ISR_STATUS:
*data = dev->cfg.isr_status;
dev->cfg.isr_status = 0;
+ vcpu_deassert_pic_irq(dev->vm_id, 0, dev->irq);
break;
}
}
@@ -982,6 +985,7 @@ virtio_net_io(int dir, uint16_t reg, uint32_t *data, uint8_t *intr,
dev->vq[RXQ].notified_avail = 0;
dev->vq[TXQ].last_avail = 0;
dev->vq[TXQ].notified_avail = 0;
+ vcpu_deassert_pic_irq(dev->vm_id, 0, dev->irq);
}
break;
default:
@@ -1022,6 +1026,7 @@ virtio_net_io(int dir, uint16_t reg, uint32_t *data, uint8_t *intr,
case VIRTIO_CONFIG_ISR_STATUS:
*data = dev->cfg.isr_status;
dev->cfg.isr_status = 0;
+ vcpu_deassert_pic_irq(dev->vm_id, 0, dev->irq);
break;
}
}
@@ -1727,6 +1732,7 @@ vmmci_io(int dir, uint16_t reg, uint32_t *data, uint8_t *intr,
case VIRTIO_CONFIG_ISR_STATUS:
*data = vmmci.cfg.isr_status;
vmmci.cfg.isr_status = 0;
+ vcpu_deassert_pic_irq(vmmci.vm_id, 0, vmmci.irq);
break;
}
}
@@ -1770,6 +1776,7 @@ virtio_init(struct vmd_vm *vm, int child_cdrom, int *child_disks,
+ sizeof(uint16_t) * (2 + VIORND_QUEUE_SIZE));
viornd.pci_id = id;
viornd.irq = pci_get_dev_irq(id);
+ viornd.vm_id = vcp->vcp_id;
if (vcp->vcp_ndisks > 0) {
nr_vioblk = vcp->vcp_ndisks;
@@ -1813,6 +1820,7 @@ virtio_init(struct vmd_vm *vm, int child_cdrom, int *child_disks,
vioblk[i].cfg.device_feature = VIRTIO_BLK_F_SIZE_MAX;
vioblk[i].max_xfer = 1048576;
vioblk[i].pci_id = id;
+ vioblk[i].vm_id = vcp->vcp_id;
vioblk[i].irq = pci_get_dev_irq(id);
}
}
@@ -1944,6 +1952,7 @@ virtio_init(struct vmd_vm *vm, int child_cdrom, int *child_disks,
vioscsi->n_blocks = sz >> 11; /* num of 2048 blocks in file */
vioscsi->max_xfer = VIOSCSI_BLOCK_SIZE_CDROM;
vioscsi->pci_id = id;
+ vioscsi->vm_id = vcp->vcp_id;
vioscsi->irq = pci_get_dev_irq(id);
}