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;