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);