def rdmsr_helper(msr, cpu=None, shift=0, mask=~0, highbit=63, lowbit=0): """Collate the unique values of an MSR across all CPUs. Returns a dict mapping MSR values to lists of APIC IDs, and a list of strings describing the unique values and the CPUs they occurred on. Each string in the list of descriptions works as an argument to testsuite.print_detail, and the first string also works as a test description for testsuite.test if no more specific description exists.""" if (highbit != 63 or lowbit != 0) and (shift != 0 or mask != ~0): raise ValueError('Input parameter usage is limited to \"highbit and lowbit\" OR \"shift and mask\".') if cpu is None: cpus = bits.cpus() else: cpus = [cpu] uniques = {} for cpu in cpus: value = bits.rdmsr(cpu, msr) if value is not None: if highbit != 63 or lowbit != 0: value = (value & ((1 << (highbit + 1)) - 1)) >> lowbit else: value = (value >> shift) & mask uniques.setdefault(value, []).append(cpu) msr_desc = "MSR {:#x}".format(msr) if shift == 0 and mask == ~0: if highbit == lowbit: msr_desc += " [{:d}]".format(highbit) else: msr_desc += " [{:d}:{:d}]".format(highbit, lowbit) else: if shift != 0: msr_desc += " >> {}".format(shift) if mask != ~0: msr_desc += " & {:#x}".format(mask) test_desc = msr_desc + " = " if len(uniques) > 1: test_desc += "Value Varies" elif value is None: test_desc += "GPF" else: test_desc += "{0:#x}".format(value) desc = [test_desc] if len(uniques) > 1 and (None not in uniques): mask = testutil.find_common_mask(uniques.iterkeys(), 64) desc.append('MSR value is not unique across all logical processors') desc.append("Common bits for all processors = {0:#018x}".format(uniques.keys()[0] & mask)) desc.append("Mask of common bits = {0:#018x}".format(mask)) for value in sorted(uniques.iterkeys()): cpus = uniques[value] desc.append(msr_desc + " = " + ("GPF" if value is None else "{0:#x}".format(value))) desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus))) return uniques, desc
def cmd_brandstring(args): uniques = {} for cpu in bits.cpus(): uniques.setdefault(bits.brandstring(cpu), []).append(cpu) for value in sorted(uniques.iterkeys()): cpus = uniques[value] print 'Brandstring: "{0}"'.format(value) print "On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus))
def cmd_brandstring(args): uniques = {} for cpu in each_apicid(args.cpu): brand = "" if bits.cpuid(cpu, 0x80000000).eax >= 0x80000004: brand = "".join(struct.pack("<LLLL", *bits.cpuid(cpu, func_num)) for func_num in range(0x80000002, 0x80000005)) brand = brand.rstrip('\0') uniques.setdefault(brand, []).append(cpu) for value in sorted(uniques.iterkeys()): cpus = uniques[value] print 'Brandstring: "{0}"'.format(value) print "On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus))
def rdmsr_helper(msr, shift=0, mask=~0, highbit=63, lowbit=0): """Collate the unique values of an MSR across all CPUs. Returns a dict mapping MSR values to lists of APIC IDs, and a list of strings describing the unique values and the CPUs they occurred on. Each string in the list of descriptions works as an argument to testsuite.print_detail, and the first string also works as a test description for testsuite.test if no more specific description exists.""" if (highbit != 63 or lowbit != 0) and (shift != 0 or mask != ~0): raise ValueError( 'Input parameter usage is limited to \"highbit and lowbit\" OR \"shift and mask\".' ) uniques = {} for cpu in bits.cpus(): value = bits.rdmsr(cpu, msr) if value is not None: if highbit != 63 or lowbit != 0: value = (value & ((1 << (highbit + 1)) - 1)) >> lowbit else: value = (value >> shift) & mask uniques.setdefault(value, []).append(cpu) msr_desc = "MSR {:#x}".format(msr) if shift == 0 and mask == ~0: if highbit == lowbit: msr_desc += " [{:d}]".format(highbit) else: msr_desc += " [{:d}:{:d}]".format(highbit, lowbit) else: if shift != 0: msr_desc += " >> {}".format(shift) if mask != ~0: msr_desc += " & {:#x}".format(mask) desc = [] if len(uniques) > 1 and (None not in uniques): mask = testutil.find_common_mask(uniques.iterkeys(), 64) desc.append('MSR value is not unique across all logical processors') desc.append("Common bits for all processors = {0:#018x}".format( uniques.keys()[0] & mask)) desc.append("Mask of common bits = {0:#018x}".format(mask)) for value in sorted(uniques.iterkeys()): cpus = uniques[value] desc.append(msr_desc + " = " + ("GPF" if value is None else "{0:#x}".format(value))) desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus))) return uniques, desc
def cmd_wrmsr(args): rd_fail = [] wr_fail = [] success = [] def process_wrmsr(apicid): wr_value = 0 if args.rmw: rd_value = bits.rdmsr(apicid, args.msr) if rd_value is None: rd_fail.append(apicid) return wr_value = rd_value & ~(args.mask << args.shift) wr_value |= (args.value & args.mask) << args.shift if bits.wrmsr(apicid, args.msr, wr_value): success.append(apicid) else: wr_fail.append(apicid) for apicid in bits.cpus(): process_wrmsr(apicid) if rd_fail or wr_fail: if args.rmw: op = "|=" else: op = "=" print "MSR {0:#x} {1} ({2:#x} & {3:#x}) << {4} ({5:#x})".format(args.msr, op, args.value, args.mask, args.shift, (args.value & args.mask) << args.shift) if rd_fail: print "Read MSR fail (GPF) on {} CPUs: {}".format(len(rd_fail), testutil.apicid_list(rd_fail)) if wr_fail: print "Write MSR fail (GPF) on {} CPUs: {}".format(len(wr_fail), testutil.apicid_list(wr_fail)) if success: print "Write MSR pass on {} CPUs: {}".format(len(success), testutil.apicid_list(success)) return not rd_fail and not wr_fail
def cpuid_helper(function, index=None, cpu=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0): if cpu is None: cpus = bits.cpus() else: cpus = [cpu] if index is None: index = 0 indexdesc = "" else: indexdesc = " index {0:#x}".format(index) def find_mask(m): if m == ~0: return mask return m masks = map(find_mask, [eax_mask, ebx_mask, ecx_mask, edx_mask]) uniques = {} for cpu in cpus: regs = bits.cpuid_result(*[(r >> shift) & m for r, m in zip(bits.cpuid(cpu, function, index), masks)]) uniques.setdefault(regs, []).append(cpu) desc = ["CPUID function {:#x}{}".format(function, indexdesc)] if shift != 0: desc.append("Register values have been shifted by {}".format(shift)) if mask != ~0 or eax_mask != ~0 or ebx_mask != ~0 or ecx_mask != ~0 or edx_mask != ~0: desc.append("Register values have been masked:") shifted_masks = bits.cpuid_result(*[m << shift for m in masks]) desc.append("Masks: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**shifted_masks._asdict())) if len(uniques) > 1: regvalues = zip(*uniques.iterkeys()) common_masks = bits.cpuid_result(*map(testutil.find_common_mask, regvalues)) common_values = bits.cpuid_result(*[v[0] & m for v, m in zip(regvalues, common_masks)]) desc.append('Register values are not unique across all logical processors') desc.append("Common bits: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**common_values._asdict())) desc.append("Mask of common bits: {eax:#010x} {ebx:#010x} {ecx:#010x} {edx:#010x}".format(**common_masks._asdict())) for regs in sorted(uniques.iterkeys()): cpus = uniques[regs] desc.append("Register value: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**regs._asdict())) desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus))) return uniques, desc
def cpuid_helper(function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0): if index is None: index = 0 indexdesc = "" else: indexdesc = " index {0:#x}".format(index) def find_mask(m): if m == ~0: return mask return m masks = map(find_mask, [eax_mask, ebx_mask, ecx_mask, edx_mask]) uniques = {} for cpu in bits.cpus(): regs = bits.cpuid_result(*[(r >> shift) & m for r, m in zip(bits.cpuid(cpu, function, index), masks)]) uniques.setdefault(regs, []).append(cpu) desc = ["CPUID function {:#x}{}".format(function, indexdesc)] if shift != 0: desc.append("Register values have been shifted by {}".format(shift)) if mask != ~0 or eax_mask != ~0 or ebx_mask != ~0 or ecx_mask != ~0 or edx_mask != ~0: desc.append("Register values have been masked:") shifted_masks = bits.cpuid_result(*[m << shift for m in masks]) desc.append("Masks: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**shifted_masks._asdict())) if len(uniques) > 1: regvalues = zip(*uniques.iterkeys()) common_masks = bits.cpuid_result(*map(testutil.find_common_mask, regvalues)) common_values = bits.cpuid_result(*[v[0] & m for v, m in zip(regvalues, common_masks)]) desc.append('Register values are not unique across all logical processors') desc.append("Common bits: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**common_values._asdict())) desc.append("Mask of common bits: {eax:#010x} {ebx:#010x} {ecx:#010x} {edx:#010x}".format(**common_masks._asdict())) for regs in sorted(uniques.iterkeys()): cpus = uniques[regs] desc.append("Register value: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**regs._asdict())) desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus))) return uniques, desc