On Tue, Dec 04, 2018 at 05:43:48AM -0800, Chris Cappuccio wrote:
> Of course printf instead of panic for testers 
> 

Oh, right, thanks!

@john:  Does this "slightly less simple" diff work for you?

@phessler, Chris: Maybe we should get this fix tested and in, wait for
reports, and I can use the time to think about my other option.  What
do you think?

Reyk

Index: sys/dev/pv/pvclock.c
===================================================================
RCS file: /cvs/src/sys/dev/pv/pvclock.c,v
retrieving revision 1.2
diff -u -p -u -p -r1.2 pvclock.c
--- sys/dev/pv/pvclock.c        24 Nov 2018 13:12:29 -0000      1.2
+++ sys/dev/pv/pvclock.c        4 Dec 2018 14:03:57 -0000
@@ -70,6 +70,11 @@ uint  pvclock_get_timecount(struct timec
 void    pvclock_read_time_info(struct pvclock_softc *,
            struct pvclock_time_info *);
 
+static inline uint32_t
+        pvclock_read_begin(const struct pvclock_time_info *);
+static inline int
+        pvclock_read_done(const struct pvclock_time_info *, uint32_t);
+
 struct cfattach pvclock_ca = {
        sizeof(struct pvclock_softc),
        pvclock_match,
@@ -127,8 +132,11 @@ pvclock_match(struct device *parent, voi
 void
 pvclock_attach(struct device *parent, struct device *self, void *aux)
 {
-       struct pvclock_softc    *sc = (struct pvclock_softc *)self;
-       paddr_t                  pa;
+       struct pvclock_softc            *sc = (struct pvclock_softc *)self;
+       struct pvclock_time_info        *ti;
+       paddr_t                          pa;
+       uint32_t                         version;
+       uint8_t                          flags;
 
        if ((sc->sc_time = km_alloc(PAGE_SIZE,
            &kv_any, &kp_zero, &kd_nowait)) == NULL) {
@@ -143,6 +151,19 @@ pvclock_attach(struct device *parent, st
 
        wrmsr(KVM_MSR_SYSTEM_TIME, pa | PVCLOCK_SYSTEM_TIME_ENABLE);
        sc->sc_paddr = pa;
+
+       ti = sc->sc_time;
+       do {
+               version = pvclock_read_begin(ti);
+               flags = ti->ti_flags;
+       } while (!pvclock_read_done(ti, version));
+
+       if ((flags & PVCLOCK_FLAG_TSC_STABLE) == 0) {
+               wrmsr(KVM_MSR_SYSTEM_TIME, pa & ~PVCLOCK_SYSTEM_TIME_ENABLE);
+               km_free(sc->sc_time, PAGE_SIZE, &kv_any, &kp_zero);
+               printf(": unstable clock\n");
+               return;
+       }
 
        sc->sc_tc = &pvclock_timecounter;
        sc->sc_tc->tc_name = DEVNAME(sc);

Reply via email to