Cleanly teardown and restore emulated device state on vm send/receive.
authordv <dv@openbsd.org>
Mon, 29 Mar 2021 13:09:41 +0000 (13:09 +0000)
committerdv <dv@openbsd.org>
Mon, 29 Mar 2021 13:09:41 +0000 (13:09 +0000)
This cleans up events on a pause or resume, but also fixes an issue
where the vm_pipe event channels are not properly reinitialized on a
received guest leading to broken serial console.

OK pd@, mlarkin@

usr.sbin/vmd/i8253.c
usr.sbin/vmd/mc146818.c
usr.sbin/vmd/ns8250.c

index b5a6bc5..24619ab 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: i8253.c,v 1.32 2020/06/28 16:52:45 pd Exp $ */
+/* $OpenBSD: i8253.c,v 1.33 2021/03/29 13:09:41 dv Exp $ */
 /*
  * Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
  *
@@ -412,6 +412,9 @@ i8253_restore(int fd, uint32_t vm_id)
                    &i8253_channel[i]);
                i8253_reset(i);
        }
+
+       vm_pipe_init(&dev_pipe, i8253_pipe_dispatch);
+
        return (0);
 }
 
@@ -421,6 +424,7 @@ i8253_stop()
        int i;
        for (i = 0; i < 3; i++)
                evtimer_del(&i8253_channel[i].timer);
+       event_del(&dev_pipe.read_ev);
 }
 
 void
@@ -430,4 +434,5 @@ i8253_start()
        for (i = 0; i < 3; i++)
                if (i8253_channel[i].in_use)
                        i8253_reset(i);
+       event_add(&dev_pipe.read_ev, NULL);
 }
index 7925bd9..311dc0c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: mc146818.c,v 1.22 2020/06/28 16:52:45 pd Exp $ */
+/* $OpenBSD: mc146818.c,v 1.23 2021/03/29 13:09:41 dv Exp $ */
 /*
  * Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
  *
@@ -368,6 +368,9 @@ mc146818_restore(int fd, uint32_t vm_id)
        memset(&rtc.per, 0, sizeof(struct event));
        evtimer_set(&rtc.sec, rtc_fire1, NULL);
        evtimer_set(&rtc.per, rtc_fireper, (void *)(intptr_t)rtc.vm_id);
+
+       vm_pipe_init(&dev_pipe, mc146818_pipe_dispatch);
+
        return (0);
 }
 
@@ -376,11 +379,13 @@ mc146818_stop()
 {
        evtimer_del(&rtc.per);
        evtimer_del(&rtc.sec);
+       event_del(&dev_pipe.read_ev);
 }
 
 void
 mc146818_start()
 {
        evtimer_add(&rtc.sec, &rtc.sec_tv);
+       event_add(&dev_pipe.read_ev, NULL);
        rtc_reschedule_per();
 }
index a1bc492..24ab70f 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ns8250.c,v 1.29 2020/06/28 16:52:45 pd Exp $ */
+/* $OpenBSD: ns8250.c,v 1.30 2021/03/29 13:09:41 dv Exp $ */
 /*
  * Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
  *
@@ -694,9 +694,7 @@ ns8250_restore(int fd, int con_fd, uint32_t vmid)
        com1_dev.byte_out = 0;
        com1_dev.regs.divlo = 1;
        com1_dev.baudrate = 115200;
-       com1_dev.rate_tv.tv_usec = 10000;
        com1_dev.pause_ct = (com1_dev.baudrate / 8) / 1000 * 10;
-       evtimer_set(&com1_dev.rate, ratelimit, NULL);
 
        event_set(&com1_dev.event, com1_dev.fd, EV_READ | EV_PERSIST,
            com_rcv_event, (void *)(intptr_t)vmid);
@@ -704,6 +702,12 @@ ns8250_restore(int fd, int con_fd, uint32_t vmid)
        event_set(&com1_dev.wake, com1_dev.fd, EV_WRITE,
            com_rcv_event, (void *)(intptr_t)vmid);
 
+       timerclear(&com1_dev.rate_tv);
+       com1_dev.rate_tv.tv_usec = 10000;
+       evtimer_set(&com1_dev.rate, ratelimit, NULL);
+
+       vm_pipe_init(&dev_pipe, ns8250_pipe_dispatch);
+
        return (0);
 }
 
@@ -712,6 +716,7 @@ ns8250_stop()
 {
        if(event_del(&com1_dev.event))
                log_warn("could not delete ns8250 event handler");
+       event_del(&dev_pipe.read_ev);
        evtimer_del(&com1_dev.rate);
 }
 
@@ -720,5 +725,6 @@ ns8250_start()
 {
        event_add(&com1_dev.event, NULL);
        event_add(&com1_dev.wake, NULL);
+       event_add(&dev_pipe.read_ev, NULL);
        evtimer_add(&com1_dev.rate, &com1_dev.rate_tv);
 }