On Mon, Jun 14, 2021 at 01:19:21PM -0700, Chris Cappuccio wrote:
[..]
> If you're going to print flags for some unsupported features, why
> not print them all? 
> 
> The 'features3' line doesn't look clean
> 
> Typically uppercase flags like this are formatted like <FLAG,FLAG_2,ETC>

OK in this next patch (below) the flags are cleaned up and print as much info
as they can (as much as FreeBSD).  I don't have Microsoft docs so this relies
on the open sources from there.  It now looks like this:

pvbus0 at mainbus0: Hyper-V 10.0
hyperv0 at pvbus0: protocol 4.0, features 0x2e7f <VPRUNTIME,TIME_REFCNT,SYNIC,SY
NTIMER,APIC,HYPERCALL,VP_INDEX,REF_TSC,GUEST_IDLE,TM_FREQ>
hyperv0: pm features 0x2 <>
hyperv0: features3 0xbed7b2 <DEBUG,XMM_HYPERCALL,GUEST_IDLE,NUMA,TIME_FREQ,SYNCM
C,CRASH,NPIEP>
hyperv0: heartbeat, kvp, shutdown, timesync
hvs0 at hyperv0 channel 2: ide, protocol 6.2

In regards to features3 not looking "clean" do you mean the 3's that I had
initially put behind them to indicate that they are feature3?  Or do you mean
the register value?  For the former I cleaned that up.

> In any event, I'm not sure what benefit this brings. Doesn't 
> "hyperv0: heartbeat, kvp, shutdown, timesync" already show what features
> are in use?

This line is constructed in hv_guid_sprint() in hyperv.c, I haven't read into
them too much but I think they are general drivers that are enabled.  I don't
really know.

> I imagine it might be interesting to know what features are available but
> not in use. Is there a command-line utility that could be extended to show
> this info?

You mean in the Windows Host system or in the guest?  Either way I don't have
too much windows documentation.  I don't know any command-line utility to show 
this.

> 
> Chris

In the updated patch below I made one more change in that I moved the original
DPRINTF() into the print_hv_features() function.  Also interesting is that
hyperv0 features3 are showing "DEBUG", I wonder if it's just my machine with
this patch, and if I can turn that off somehow to gain speed.

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    15 Jun 2021 05:08:06 -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_REF_TSC,         "REF_TSC" },
+       { CPUID_HV_MSR_GUEST_IDLE,      "GUEST_IDLE" },
+       { CPUID_HV_MSR_TM_FREQ,         "TM_FREQ" },
+       { CPUID_HV_MSR_DEBUG,           "DEBUG" }
+}, hv_cpu_pm_features[] = {
+       { CPUPM_HV_C3_HPET,             "C3_HPET" }
+}, hv_cpu_features3[] = {
+       { CPUID3_HV_MWAIT,              "MWAIT" },
+       { CPUID3_HV_DEBUG,              "DEBUG" },
+       { CPUID3_HV_PERFMON,            "PERFMON" },
+       { CPUID3_HV_PCPUDPE,            "PCPUDPE" },
+       { CPUID3_HV_XMM_HYPERCALL,      "XMM_HYPERCALL" },
+       { CPUID3_HV_GUEST_IDLE,         "GUEST_IDLE" },
+       { CPUID3_HV_SLEEP,              "SLEEP" },
+       { CPUID3_HV_NUMA,               "NUMA" },
+       { CPUID3_HV_TIME_FREQ,          "TIME_FREQ" },
+       { CPUID3_HV_SYNCMC,             "SYNCMC" },
+       { CPUID3_HV_MSR_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,
@@ -314,11 +351,8 @@ hv_attach(struct device *parent, struct 
        if (hv_vmbus_connect(sc))
                return;
 
-       DPRINTF("%s", sc->sc_dev.dv_xname);
-       printf(": protocol %d.%d, features %#x\n",
-           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 +1864,32 @@ 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, j;
+
+       DPRINTF("%s", sc->sc_dev.dv_xname);
+       printf(": protocol %d.%d, features %#x <",
+           VMBUS_VERSION_MAJOR(sc->sc_proto),
+           VMBUS_VERSION_MINOR(sc->sc_proto),
+           hv->hv_features);
+
+       for (i = 0, j = 0; i < nitems(hv_cpu_features); i++)
+               if (hv->hv_features & hv_cpu_features[i].bit)
+                       printf("%s%s", j++ ? "," : "", hv_cpu_features[i].str);
+
+       printf(">\n%s: pm features %#x <", sc->sc_dev.dv_xname, 
hv->hv_pm_features);
+       for (i = 0, j = 0; i < nitems(hv_cpu_pm_features); i++)
+               if (hv->hv_pm_features & hv_cpu_pm_features[i].bit)
+                       printf("%s%s", j++ ? "," : "", 
hv_cpu_pm_features[i].str);
+       printf(">\n%s: features3 %#x <", sc->sc_dev.dv_xname, hv->hv_features3);
+
+       for (i = 0, j = 0; i < nitems(hv_cpu_features3); i++)
+               if (hv->hv_features3 & hv_cpu_features3[i].bit)
+                       printf("%s%s", j++ ? "," : "", hv_cpu_features3[i].str);
+
+       printf(">\n");
 }
Index: hypervreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pv/hypervreg.h,v
retrieving revision 1.10
diff -u -p -u -r1.10 hypervreg.h
--- hypervreg.h 5 Jan 2017 13:17:22 -0000       1.10
+++ hypervreg.h 15 Jun 2021 05:08:06 -0000
@@ -122,6 +122,7 @@ struct hv_guid {
 
 #define CPUID_LEAF_HV_FEATURES         0x40000003
 /* EAX: features */
+#define CPUID_HV_MSR_VP_RUNTIME                0x0001
 #define CPUID_HV_MSR_TIME_REFCNT       0x0002  /* MSR_HV_TIME_REF_COUNT */
 #define CPUID_HV_MSR_SYNIC             0x0004  /* MSRs for SynIC */
 #define CPUID_HV_MSR_SYNTIMER          0x0008  /* MSRs for SynTimer */
@@ -129,20 +130,33 @@ struct hv_guid {
 #define CPUID_HV_MSR_HYPERCALL         0x0020  /* MSR_HV_GUEST_OS_ID
                                                 * MSR_HV_HYPERCALL */
 #define CPUID_HV_MSR_VP_INDEX          0x0040  /* MSR_HV_VP_INDEX */
+#define        CPUID_HV_MSR_RESET              0x0080
+#define        CPUID_HV_MSR_STATS              0x0100
+#define CPUID_HV_MSR_REF_TSC           0x0200
 #define CPUID_HV_MSR_GUEST_IDLE                0x0400  /* MSR_HV_GUEST_IDLE */
+#define        CPUID_HV_MSR_TM_FREQ            0x0800
+#define CPUID_HV_MSR_DEBUG             0x1000
 /* ECX: power management features */
 #define CPUPM_HV_CSTATE_MASK           0x000f  /* deepest C-state */
 #define CPUPM_HV_C3_HPET               0x0010  /* C3 requires HPET */
 #define CPUPM_HV_CSTATE(f)             ((f) & CPUPM_HV_CSTATE_MASK)
 /* EDX: features3 */
 #define CPUID3_HV_MWAIT                        0x0001  /* MWAIT */
+#define CPUID3_HV_DEBUG                        0x0002
+#define CPUID3_HV_PERFMON              0x0004
+#define CPUID3_HV_PCPUDPE              0x0008
 #define CPUID3_HV_XMM_HYPERCALL                0x0010  /* Hypercall input 
through
                                                 * XMM regs */
 #define CPUID3_HV_GUEST_IDLE           0x0020  /* guest idle */
+#define CPUID3_HV_SLEEP                        0x0040
 #define CPUID3_HV_NUMA                 0x0080  /* NUMA distance query */
 #define CPUID3_HV_TIME_FREQ            0x0100  /* timer frequency query
                                                 * (TSC, LAPIC) */
+#define        CPUID3_HV_SYNCMC                0x0200
 #define CPUID3_HV_MSR_CRASH            0x0400  /* MSRs for guest crash */
+#define CPUID3_HV_DEBUGMSR             0x0800
+#define CPUID3_HV_NPIEP                        0x1000
+#define CPUID3_HV_HVDIS                        0x2000
 
 #define CPUID_LEAF_HV_RECOMMENDS       0x40000004
 #define CPUID_LEAF_HV_LIMITS           0x40000005
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     15 Jun 2021 05:08:06 -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     15 Jun 2021 05:08:06 -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