* Renato Aguiar <[email protected]> [2020-05-21 12:55:45 -0700]:
Hi Sivaram,
I'm the author of the e-mail thread that you mentioned. After feedback
I got from OpenBSD community, I created a patch for Linux to enable
kvm-clock when booting on VMM. It managed to keep clock in sync, but I
experienced random crashes in vmd after some time running the VM.
Multiple fixes have been merged to vmm/vmd since then, so I'm planning
to give it another try with OpenBSD 6.7.
If you are interested, I can share the patch with you.
Regards,
--
Renato Aguiar
Hi Sivaram and Renato,
I have been looking at this issue this week with Dave. (funnily Dave
and I independently also decided to write a linux patch to attach
pvclock and debugging these crashes).
If you have your linux vm with kvm-clock around, can you try this rather
crude patch and see if it still crashes? This might also fix the '100%
cpu when using alpine via console' problem.
For ref, this is my linux side patch to attach kvm-clock http://ix.io/2lzK
--
Pratik
diff --git a/usr.sbin/vmd/ns8250.c b/usr.sbin/vmd/ns8250.c
index 497e6fad550..33f1a371c16 100644
--- a/usr.sbin/vmd/ns8250.c
+++ b/usr.sbin/vmd/ns8250.c
@@ -36,6 +36,8 @@
extern char *__progname;
struct ns8250_dev com1_dev;
+struct event read_delay_ev;
+struct timeval read_delay_tv;
static void com_rcv_event(int, short, void *);
static void com_rcv(struct ns8250_dev *, uint32_t, uint32_t);
@@ -61,6 +63,11 @@ ratelimit(int fd, short type, void *arg)
vcpu_deassert_pic_irq(com1_dev.vmid, 0, com1_dev.irq);
}
+static void
+arm_read(int fd, short type, void *arg) {
+ event_add(&com1_dev.event, NULL);
+}
+
void
ns8250_init(int fd, uint32_t vmid)
{
@@ -96,7 +103,7 @@ ns8250_init(int fd, uint32_t vmid)
*/
com1_dev.pause_ct = (com1_dev.baudrate / 8) / 1000 * 10;
- event_set(&com1_dev.event, com1_dev.fd, EV_READ | EV_PERSIST,
+ event_set(&com1_dev.event, com1_dev.fd, EV_READ,
com_rcv_event, (void *)(intptr_t)vmid);
/*
@@ -112,6 +119,9 @@ ns8250_init(int fd, uint32_t vmid)
timerclear(&com1_dev.rate_tv);
com1_dev.rate_tv.tv_usec = 10000;
evtimer_set(&com1_dev.rate, ratelimit, NULL);
+ read_delay_tv.tv_usec = 10000;
+ evtimer_set(&read_delay_ev, arm_read,
+ (void *)(intptr_t)vmid);
}
static void
@@ -131,6 +141,7 @@ com_rcv_event(int fd, short kind, void *arg)
*/
if (com1_dev.rcv_pending) {
mutex_unlock(&com1_dev.mutex);
+ evtimer_add(&read_delay_ev, &read_delay_tv);
return;
}
@@ -146,6 +157,7 @@ com_rcv_event(int fd, short kind, void *arg)
vcpu_deassert_pic_irq((uintptr_t)arg, 0, com1_dev.irq);
}
}
+ event_add(&com1_dev.event, NULL);
mutex_unlock(&com1_dev.mutex);
}