@@ -58,8 +58,15 @@ struct msr_info msr_info[] =
{ .index = 0xc0000084, .name = "MSR_SYSCALL_MASK",
.val_pairs = {{ .valid = 1, .value = 0xffffffff, .expected = 0xffffffff}}
},
+ // MSR_IA32_DEBUGCTLMSR needs feature LBRV
+ { .index = 0x000001d9, .name = "MSR_IA32_DEBUGCTLMSR",
+ .val_pairs = {{ .valid = 1, .value = 0x801, .expected = 0x801}},
+ .val_pairs = {{ .valid = 1, .value = 0x803, .expected = 0x803}},
+ .val_pairs = {{ .valid = 1, .value = 0x1, .expected = 0x1}},
+ .val_pairs = {{ .valid = 1, .value = 0x2, .expected = 0x2}},
+ .val_pairs = {{ .valid = 1, .value = 0x3, .expected = 0x3}}
+ },
-// MSR_IA32_DEBUGCTLMSR needs svm feature LBRV
// MSR_VM_HSAVE_PA only AMD host
};
@@ -77,14 +84,93 @@ static int find_msr_info(int msr_index)
static void test_msr_rw(int msr_index, unsigned long long input, unsigned long long expected)
{
unsigned long long r = 0;
+ int lbr_supported = 0;
+ u32 eax;
+ u8 family;
+ u8 model;
int index;
char *sptr;
+
if ((index = find_msr_info(msr_index)) != -1) {
sptr = msr_info[index].name;
} else {
printf("couldn't find name for msr # 0x%x, skipping\n", msr_index);
return;
}
+
+ if (msr_index == MSR_IA32_DEBUGCTLMSR) {
+ eax = raw_cpuid(0x1, 0).a;
+ family = (eax >> 8) & 0xf;
+ model = (eax >> 4) & 0xf;
+
+ if (family == 15)
+ family += (eax >> 20) & 0xff;
+ if (family >= 6)
+ model += ((eax >> 16) & 0xf) << 4;
+ // test for Intel CPUs
+ if (family == 6) {
+ switch (model)
+ {
+ case 15: /* 65nm Core2 "Merom" */
+ case 22: /* 65nm Core2 "Merom-L" */
+ case 23: /* 45nm Core2 "Penryn" */
+ case 29: /* 45nm Core2 "Dunnington (MP) */
+ case 28: /* 45nm Atom "Pineview" */
+ case 38: /* 45nm Atom "Lincroft" */
+ case 39: /* 32nm Atom "Penwell" */
+ case 53: /* 32nm Atom "Cloverview" */
+ case 54: /* 32nm Atom "Cedarview" */
+ case 55: /* 22nm Atom "Silvermont" */
+ case 76: /* 14nm Atom "Airmont" */
+ case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
+ case 30: /* 45nm Nehalem */
+ case 26: /* 45nm Nehalem-EP */
+ case 46: /* 45nm Nehalem-EX */
+ case 37: /* 32nm Westmere */
+ case 44: /* 32nm Westmere-EP */
+ case 47: /* 32nm Westmere-EX */
+ case 42: /* 32nm SandyBridge */
+ case 45: /* 32nm SandyBridge-E/EN/EP */
+ case 58: /* 22nm IvyBridge */
+ case 62: /* 22nm IvyBridge-EP/EX */
+ case 60: /* 22nm Haswell Core */
+ case 63: /* 22nm Haswell Server */
+ case 69: /* 22nm Haswell ULT */
+ case 70: /* 22nm Haswell + GT3e */
+ case 61: /* 14nm Broadwell Core-M */
+ case 86: /* 14nm Broadwell Xeon D */
+ case 71: /* 14nm Broadwell + GT3e */
+ case 79: /* 14nm Broadwell Server */
+ case 78: /* 14nm Skylake Mobile */
+ case 94: /* 14nm Skylake Desktop */
+ lbr_supported = 1;
+ break;
+ }
+ }
+ if (family == 15) {
+ switch (model)
+ {
+ /* Pentium4/Xeon(based on NetBurst) */
+ case 3:
+ case 4:
+ case 6:
+ /* don't support bit 11, skipping */
+ if (input & (1 << 11)) {
+ return;
+ break;
+ }
+ lbr_supported = 1;
+ break;
+ }
+ }
+
+ if(!lbr_supported) {
+ printf("WARNING: LBR does't support, add a specific CPU(-cpu ...) model to support it."
+ " Skipping for %s test.\n", sptr);
+ return;
+ }
+ }
+
wrmsr(msr_index, input);
r = rdmsr(msr_index);
if (expected != r) {
Test bit 0(LBR), bit 1(BTF) and bit 11(FREEZE_LBRS_ON_PMI) of MSR_IA32_DEBUGCTLMSR register. Bit 11 depends on bit 0, so I tested five combinations: (1) bit 0 (2) bit 1 (3) bit 0 | bit 1 (4) bit 0 | bit 11 (5) bit 0 | bit 1 | bit 11 Pentium4, Atom and Skylake are not defined in Qemu. I have tested core2duo, Nehalem, Westmere, SandyBridge, IvyBridge, Haswell and Broadwell. Because LBR depends on the CPU model, it needs to add '-cpu ...' in the command line of x86-run bash script. Signed-off-by: Jian Zhou <jianjay.zhou@huawei.com> --- x86/msr.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) -- 1.7.12.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html