On Sun, Feb 18, 2018 at 12:00:01PM -0600, Scott Cheloha wrote:
> Hi,
> 
> Is it bad if the olatch counts up if the host's wall clock
> is set backward?  Or if the olatch makes a big jump for
> the same reason?
> 
> Serious question: I don't have any EPT hardware to test
> this (sorry).
> 
> While here, it looks like we can (a) roll the olatch-writing
> parts of i8253_do_readback into a loop, and (b) use the
> timespecsub macro from sys/time.h, to make the code briefer.
> 
> Anyone down to test?
> 
> --
> Scott Cheloha
> 

Before I read through this, can you briefly explain what this is trying 
to fix?

-ml

> Index: usr.sbin/vmd/i8253.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/vmd/i8253.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 i8253.c
> --- usr.sbin/vmd/i8253.c      14 Aug 2017 19:46:44 -0000      1.17
> +++ usr.sbin/vmd/i8253.c      18 Feb 2018 17:53:48 -0000
> @@ -25,6 +25,7 @@
>  #include <event.h>
>  #include <string.h>
>  #include <stddef.h>
> +#include <time.h>
>  #include <unistd.h>
>  
>  #include "i8253.h"
> @@ -53,7 +54,7 @@ void
>  i8253_init(uint32_t vm_id)
>  {
>       memset(&i8253_channel, 0, sizeof(struct i8253_channel));
> -     gettimeofday(&i8253_channel[0].tv, NULL);
> +     clock_gettime(CLOCK_MONOTONIC, &i8253_channel[0].ts);
>       i8253_channel[0].start = 0xFFFF;
>       i8253_channel[0].mode = TIMER_INTTC;
>       i8253_channel[0].last_r = 1;
> @@ -86,8 +87,10 @@ i8253_init(uint32_t vm_id)
>  void
>  i8253_do_readback(uint32_t data)
>  {
> -     struct timeval now, delta;
> +     struct timespec now, delta;
>       uint64_t ns, ticks;
> +     int readback_channel[3] = { TIMER_RB_C0, TIMER_RB_C1, TIMER_RB_C2 };
> +     int i;
>  
>       /* bits are inverted here - !TIMER_RB_STATUS == enable chan readback */
>       if (data & ~TIMER_RB_STATUS) {
> @@ -98,73 +101,19 @@ i8253_do_readback(uint32_t data)
>  
>       /* !TIMER_RB_COUNT == enable counter readback */
>       if (data & ~TIMER_RB_COUNT) {
> -             if (data & TIMER_RB_C0) {
> -                     gettimeofday(&now, NULL);
> -                     delta.tv_sec = now.tv_sec - i8253_channel[0].tv.tv_sec;
> -                     delta.tv_usec = now.tv_usec -
> -                         i8253_channel[0].tv.tv_usec;
> -                     if (delta.tv_usec < 0) {
> -                             delta.tv_sec--;
> -                             delta.tv_usec += 1000000;
> +             for (i = 0; i < 3; i++) {
> +                     if (data & readback_channel[i]) {
> +                             clock_gettime(CLOCK_MONOTONIC, &now);
> +                             timespecsub(&now, &i8253_channel[i].ts, &delta);
> +                             ns = delta.tv_sec * 1000000000 + delta.tv_nsec;
> +                             ticks = ns / NS_PER_TICK;
> +                             if (i8253_channel[i].start)
> +                                     i8253_channel[i].olatch =
> +                                         i8253_channel[i].start -
> +                                         ticks % i8253_channel[i].start;
> +                             else
> +                                     i8253_channel[i].olatch = 0;
>                       }
> -                     if (delta.tv_usec > 1000000) {
> -                             delta.tv_sec++;
> -                             delta.tv_usec -= 1000000;
> -                     }
> -                     ns = delta.tv_usec * 1000 + delta.tv_sec * 1000000000;
> -                     ticks = ns / NS_PER_TICK;
> -                     if (i8253_channel[0].start)
> -                             i8253_channel[0].olatch =
> -                                 i8253_channel[0].start -
> -                                 ticks % i8253_channel[0].start;
> -                     else
> -                             i8253_channel[0].olatch = 0;
> -             }
> -
> -             if (data & TIMER_RB_C1) {
> -                     gettimeofday(&now, NULL);
> -                     delta.tv_sec = now.tv_sec - i8253_channel[1].tv.tv_sec;
> -                     delta.tv_usec = now.tv_usec -
> -                         i8253_channel[1].tv.tv_usec;
> -                     if (delta.tv_usec < 0) {
> -                             delta.tv_sec--;
> -                             delta.tv_usec += 1000000;
> -                     }
> -                     if (delta.tv_usec > 1000000) {
> -                             delta.tv_sec++;
> -                             delta.tv_usec -= 1000000;
> -                     }
> -                     ns = delta.tv_usec * 1000 + delta.tv_sec * 1000000000;
> -                     ticks = ns / NS_PER_TICK;
> -                     if (i8253_channel[1].start)
> -                             i8253_channel[1].olatch =
> -                                 i8253_channel[1].start -
> -                                 ticks % i8253_channel[1].start;
> -                     else
> -                             i8253_channel[1].olatch = 0;
> -             }
> -
> -             if (data & TIMER_RB_C2) {
> -                     gettimeofday(&now, NULL);
> -                     delta.tv_sec = now.tv_sec - i8253_channel[2].tv.tv_sec;
> -                     delta.tv_usec = now.tv_usec -
> -                         i8253_channel[2].tv.tv_usec;
> -                     if (delta.tv_usec < 0) {
> -                             delta.tv_sec--;
> -                             delta.tv_usec += 1000000;
> -                     }
> -                     if (delta.tv_usec > 1000000) {
> -                             delta.tv_sec++;
> -                             delta.tv_usec -= 1000000;
> -                     }
> -                     ns = delta.tv_usec * 1000 + delta.tv_sec * 1000000000;
> -                     ticks = ns / NS_PER_TICK;
> -                     if (i8253_channel[2].start)
> -                             i8253_channel[2].olatch =
> -                                 i8253_channel[2].start -
> -                                 ticks % i8253_channel[2].start;
> -                     else
> -                             i8253_channel[2].olatch = 0;
>               }
>       }
>  }
> @@ -188,7 +137,7 @@ vcpu_exit_i8253(struct vm_run_params *vr
>       uint32_t out_data;
>       uint8_t sel, rw, data, mode;
>       uint64_t ns, ticks;
> -     struct timeval now, delta;
> +     struct timespec now, delta;
>       union vm_exit *vei = vrp->vrp_exit;
>  
>       get_input_data(vei, &out_data);
> @@ -216,21 +165,9 @@ vcpu_exit_i8253(struct vm_run_params *vr
>                        * rate.
>                        */
>                       if (rw == TIMER_LATCH) {
> -                             gettimeofday(&now, NULL);
> -                             delta.tv_sec = now.tv_sec -
> -                                 i8253_channel[sel].tv.tv_sec;
> -                             delta.tv_usec = now.tv_usec -
> -                                 i8253_channel[sel].tv.tv_usec;
> -                             if (delta.tv_usec < 0) {
> -                                     delta.tv_sec--;
> -                                     delta.tv_usec += 1000000;
> -                             }
> -                             if (delta.tv_usec > 1000000) {
> -                                     delta.tv_sec++;
> -                                     delta.tv_usec -= 1000000;
> -                             }
> -                             ns = delta.tv_usec * 1000 +
> -                                 delta.tv_sec * 1000000000;
> +                             clock_gettime(CLOCK_MONOTONIC, &now);
> +                             timespecsub(&now, &i8253_channel[sel].ts, 
> &delta);
> +                             ns = delta.tv_sec * 1000000000 + delta.tv_nsec;
>                               ticks = ns / NS_PER_TICK;
>                               if (i8253_channel[sel].start) {
>                                       i8253_channel[sel].olatch =
> Index: usr.sbin/vmd/i8253.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/vmd/i8253.h,v
> retrieving revision 1.7
> diff -u -p -r1.7 i8253.h
> --- usr.sbin/vmd/i8253.h      9 Jul 2017 00:51:40 -0000       1.7
> +++ usr.sbin/vmd/i8253.h      18 Feb 2018 17:53:48 -0000
> @@ -29,7 +29,7 @@
>  
>  /* i8253 registers */
>  struct i8253_channel {
> -     struct timeval tv;      /* timer start time */
> +     struct timespec ts;     /* timer start time */
>       uint16_t start;         /* starting value */
>       uint16_t olatch;        /* output latch */
>       uint16_t ilatch;        /* input latch */

Reply via email to