On Mon, Dec 03, 2018 at 04:56:10PM -0800, Chris Cappuccio wrote:
> Reyk Floeter [r...@openbsd.org] wrote:
> >
> > Yes, KVM???s stable bit is not a reliable indication as it is seems to 
> > depend on the capabilities of the KVM version and not the actual 
> > availability of the feature on the particular hardware. How annoying.
> >
> > As mentioned before: I???d like to disable pvclock for now and I can do 
> > that in the morning CET if nobody beats me to it.
> >
> > I have an idea how to deal with old platforms afterwards but this needs 
> > some more tests and thoughts.
> >
> 
> Perhaps the solution is as "simple" as checking the status of the bit
> after the presence of the bit is established ?
> 

The approach makes sense but it is not the right way to read the
value.  It only works if you don't hit a refresh cycle of the host.
Better diff below.

But I'm not sure if this is enough and if the "stable" flag mit appear
occasionally.  So I'd like to disable pvclock for now until we did
some more testing and tried different options.

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 12:09:06 -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);
+               panic(": unstable clock\n");
+               return;
+       }
 
        sc->sc_tc = &pvclock_timecounter;
        sc->sc_tc->tc_name = DEVNAME(sc);

Reply via email to