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;