Hi,

I may be interested in looking into hyperv since I have a MS Windows Server 2019
machine that has a hyper-v running OpenBSD (half the resources).  I have two
things that would need my attention 1. the time doesn't jump when I patch the
host OS and reboot, hyperv guest gets snapshotted at boot and sleeps while it's
off, when the system is back the time is usually off by a manner of 5 minutes
per reboot.  This I'd like to look into and I have asked Mike B. what I need
to do, his answer was that I should look at how FreeBSD do it.  2. The machine
is really slow on disk and the overlying OS uses an SSD.  I don't know the
reason but I'm wondering if it's an FS boundary issue.  Anyhow this is over
my head I think.

To start investigating the system I have added a flag for features much like
identcpu.c on amd64.  The FreeBSD equivalent is in 
sys/dev/hyperv/vmbus/hyperv.c in function hyperv_identify().

They have a lot more flags, but we don't need all until there is drivers is
what I gather, nontheless in my patch (below) I have commented out the flags
that FreeBSD has listed in their features list.  So here is how OpenBSD's
feature list looks like:

Before:
pvbus0 at mainbus0: Hyper-V 10.0
hyperv0 at pvbus0: protocol 4.0, features 0x2e7f
hyperv0: heartbeat, kvp, shutdown, timesync
hvs0 at hyperv0 channel 2: ide, protocol 6.2

After:

pvbus0 at mainbus0: Hyper-V 10.0
hyperv0 at pvbus0: protocol 4.0, features 0x2e7f TIME_REFCNT,SYNIC,SYNTIMER,APIC
,HYPERCALL,VP_INDEX,GUEST_IDLE
hyperv0: pm features 0x2 
hyperv0: features3 0xbed7b2 ,XMM_HYPERCALL3,GUEST_IDLE3,NUMA3,TIME_FREQ3
hyperv0: heartbeat, kvp, shutdown, timesync
hvs0 at hyperv0 channel 2: ide, protocol 6.2

Below is patch, what do you think?  Is it worthy?

Best Regards,
-peter

Index: hyperv.c
===================================================================
RCS file: /cvs/src/sys/dev/pv/hyperv.c,v
retrieving revision 1.48
diff -u -p -u -r1.48 hyperv.c
--- hyperv.c    23 Feb 2021 04:44:31 -0000      1.48
+++ hyperv.c    14 Jun 2021 17:17:31 -0000
@@ -108,6 +108,7 @@ uint        hv_channel_unpause(struct hv_channe
 uint   hv_channel_ready(struct hv_channel *);
 extern void hv_attach_icdevs(struct hv_softc *);
 int    hv_attach_devices(struct hv_softc *);
+void   print_hv_features(struct hv_softc *, struct pvbus_hv *);
 
 struct {
        int               hmd_response;
@@ -194,6 +195,42 @@ const struct hv_guid hv_guid_kvp = {
          0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x03, 0xe6 }
 };
 
+const struct {
+       uint32_t bit;
+       char str[16];
+} hv_cpu_features[] = {
+       /* { CPUID_HV_MSR_VP_RUNTIME,   "VPRUNTIME" }, */
+       { CPUID_HV_MSR_TIME_REFCNT,     "TIME_REFCNT" },
+       { CPUID_HV_MSR_SYNIC,           "SYNIC" },
+       { CPUID_HV_MSR_SYNTIMER,        "SYNTIMER" },
+       { CPUID_HV_MSR_APIC,            "APIC" },
+       { CPUID_HV_MSR_HYPERCALL,       "HYPERCALL" },
+       { CPUID_HV_MSR_VP_INDEX,        "VP_INDEX" },
+       /* { CPUID_HV_MSR_RESET,        "RESET" }, */
+       /* { CPUID_HV_MSR_STATS,        "STATS" }, */
+       /* { CPUID_HV_MSR_REFTSC,       "REFTSC" }, */
+       { CPUID_HV_MSR_GUEST_IDLE,      "GUEST_IDLE" },
+       /* { CPUID_HV_MSR_TMFREQ,       "TMFREQ" }, */
+       /* { CPUID_HV_MSR_DEBUG,        "DEBUG" } */
+}, hv_cpu_pm_features[] = {
+       { CPUPM_HV_C3_HPET,             "C3_HPET" }
+}, hv_cpu_features3[] = {
+       { CPUID3_HV_MWAIT,      "MWAIT3" },
+       /* { CPUID3_HV_DEBUG,   "DEBUG3" },*/
+       /* { CPUID3_HV_PERFMON, "PERFMON" }, */
+       /* { CPUID3_HV_PCPUDPE, "PCPUDPE" }, */
+       { CPUID3_HV_XMM_HYPERCALL, "XMM_HYPERCALL3" },
+       { CPUID3_HV_GUEST_IDLE, "GUEST_IDLE3" },
+       /* { CPUID3_HV_SLEEP,   "SLEEP" }, */
+       { CPUID3_HV_NUMA,       "NUMA3" },
+       { CPUID3_HV_TIME_FREQ,  "TIME_FREQ3" },
+       /* { CPUID3_HV__SYNCMC, "SYNCMC" }, */
+       /* { CPUID3_HV__CRASH,  "CRASH" }, */
+       /* { CPUID3_HV__DEBUGMSR,       "DEBUGMSR" }, */
+       /* { CPUID3_HV__NPIEP,  "NPIEP" }, */
+       /* { CPUID3_HV__HVDIS,  "HVDIS" } */
+};
+
 #ifdef HYPERV_DEBUG
 const struct hv_guid hv_guid_vss = {
        { 0x29, 0x2e, 0xfa, 0x35, 0x23, 0xea, 0x36, 0x42,
@@ -315,11 +352,13 @@ hv_attach(struct device *parent, struct 
                return;
 
        DPRINTF("%s", sc->sc_dev.dv_xname);
-       printf(": protocol %d.%d, features %#x\n",
+       printf(": protocol %d.%d, features %#x ",
            VMBUS_VERSION_MAJOR(sc->sc_proto),
            VMBUS_VERSION_MINOR(sc->sc_proto),
            hv->hv_features);
 
+       print_hv_features(sc, hv);
+
        if (hv_channel_scan(sc))
                return;
 
@@ -1830,4 +1869,26 @@ hv_evcount_attach(struct hv_channel *ch,
        struct hv_softc *sc = ch->ch_sc;
 
        evcount_attach(&ch->ch_evcnt, name, &sc->sc_idtvec);
+}
+
+void
+print_hv_features(struct hv_softc *sc, struct pvbus_hv *hv)
+{
+       int i;
+
+       for (i = 0; i < nitems(hv_cpu_features); i++)
+               if (hv->hv_features & hv_cpu_features[i].bit)
+                       printf("%s%s", i ? "," : "", hv_cpu_features[i].str);
+
+       printf("\n%s: pm features %#x ", sc->sc_dev.dv_xname, 
hv->hv_pm_features);
+       for (i = 0; i < nitems(hv_cpu_pm_features); i++)
+               if (hv->hv_pm_features & hv_cpu_pm_features[i].bit)
+                       printf("%s%s", i ? "," : "", hv_cpu_pm_features[i].str);
+       printf("\n%s: features3 %#x ", sc->sc_dev.dv_xname, hv->hv_features3);
+
+       for (i = 0; i < nitems(hv_cpu_features3); i++)
+               if (hv->hv_features3 & hv_cpu_features3[i].bit)
+                       printf("%s%s", i ? "," : "", hv_cpu_features3[i].str);
+
+       printf("\n");
 }
Index: pvbus.c
===================================================================
RCS file: /cvs/src/sys/dev/pv/pvbus.c,v
retrieving revision 1.22
diff -u -p -u -r1.22 pvbus.c
--- pvbus.c     26 Aug 2020 03:29:06 -0000      1.22
+++ pvbus.c     14 Jun 2021 17:17:31 -0000
@@ -305,6 +305,8 @@ pvbus_hyperv(struct pvbus_hv *hv)
        CPUID(hv->hv_base + CPUID_OFFSET_HYPERV_FEATURES,
            regs[0], regs[1], regs[2], regs[3]);
        hv->hv_features = regs[0];
+       hv->hv_pm_features = regs[2];
+       hv->hv_features3 = regs[3];
 
        CPUID(hv->hv_base + CPUID_OFFSET_HYPERV_VERSION,
            regs[0], regs[1], regs[2], regs[3]);
Index: pvvar.h
===================================================================
RCS file: /cvs/src/sys/dev/pv/pvvar.h,v
retrieving revision 1.10
diff -u -p -u -r1.10 pvvar.h
--- pvvar.h     22 Jun 2017 06:21:12 -0000      1.10
+++ pvvar.h     14 Jun 2021 17:17:31 -0000
@@ -51,6 +51,8 @@ enum {
 struct pvbus_hv {
        uint32_t                 hv_base;
        uint32_t                 hv_features;
+       uint32_t                 hv_pm_features;
+       uint32_t                 hv_features3;
        uint16_t                 hv_major;
        uint16_t                 hv_minor;
 

Reply via email to