diff options
author | 2018-07-09 16:11:37 +0000 | |
---|---|---|
committer | 2018-07-09 16:11:37 +0000 | |
commit | 7b36e131d56f6465b99f23042c66e678db30d8b1 (patch) | |
tree | e7ff4a2528babca983130e02fd089e961155af3d | |
parent | vmd(8): better debug message in a failure case (diff) | |
download | wireguard-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.c | 3 | ||||
-rw-r--r-- | usr.sbin/vmd/mc146818.c | 3 | ||||
-rw-r--r-- | usr.sbin/vmd/ns8250.c | 9 | ||||
-rw-r--r-- | usr.sbin/vmd/virtio.c | 11 |
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); } |