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;