Beispiel #1
0
def test(residency_tests, residency_counter_msr, residency_counters):
    cpus = bits.cpus()
    for states, hint in residency_tests:
        with bits.mwait.use_hint(hint):
            delta = residency(residency_counters, residency_counter_msr)
            detail = False
            for state in states:
                for apic_id, r in sorted(delta.iteritems()):
                    state_residency = getattr(r, state)
                    testsuite.test(
                        "MWAIT hint {:#x}, socket {} {} residency {:4.0%} (expected >= 85%)"
                        .format(hint, bits.socket_index(apic_id),
                                state.upper(), state_residency),
                        state_residency >= 0.85)
                    detail = detail or testsuite.show_detail()
            if detail:
                print testsuite.format_detail(
                    "Full residency for MWAIT hint {:#x}:".format(hint))
                print testsuite.format_detail(" SKT  APIC" + "".join(
                    "{:>6s}".format(field.upper())
                    for field in residency_counters._fields))
                for apic_id, r in sorted(delta.iteritems()):
                    skt_index = bits.socket_index(apic_id)
                    print testsuite.format_detail(
                        "{:4d}  {:#04x}  ".format(skt_index, apic_id) +
                        "  ".join("{:4.0%}".format(field) for field in r))
Beispiel #2
0
def variable_mtrrs(apicid=bits.bsp_apicid()):
    assert apicid in bits.cpus()

    ia32_mtrrcap_msr = IA32_MTRRCAP( bits.rdmsr(apicid, IA32_MTRRCAP_REG) )
    ia32_mtrr_def_type_msr = IA32_MTRR_DEF_TYPE(bits.rdmsr(apicid, IA32_MTRR_DEF_TYPE_REG))

    with ttypager.page():
        print("Summary:")
        print("Default memory type: {}".format(_memory_type_str(ia32_mtrr_def_type_msr.type)))
        for i in range(ia32_mtrrcap_msr.VCNT):
            ia32_mtrr_physbase_msr = IA32_MTRR_PHYSBASE(bits.rdmsr(apicid, IA32_MTRR_PHYSBASEn_REG(i)))
            ia32_mtrr_physmask_msr = IA32_MTRR_PHYSMASK(bits.rdmsr(apicid, IA32_MTRR_PHYSMASKn_REG(i)))
            if (ia32_mtrr_physmask_msr.V):
                print("MTRR{}: type={:20}   base={:10}   size={:10}".format(i, _memory_type_str(ia32_mtrr_physbase_msr.Type), _physbase_str(ia32_mtrr_physbase_msr.PhysBase), _physmask_str(ia32_mtrr_physmask_msr.PhysMask)))
        print()
        print(ia32_mtrrcap_msr, end='\n\n')
        print(ia32_mtrr_def_type_msr, end='\n\n')
        for i in range(ia32_mtrrcap_msr.VCNT):
            msr_num = IA32_MTRR_PHYSBASEn_REG(i)
            ia32_mtrr_physbase_msr = IA32_MTRR_PHYSBASE( bits.rdmsr(apicid, msr_num) )
            print("IA32_MTRR_PHYSBASE[{}] MSR {:#x}".format(i, msr_num))
            print(ia32_mtrr_physbase_msr, end='\n\n')

            msr_num = IA32_MTRR_PHYSMASKn_REG(i)
            ia32_mtrr_physmask_msr = IA32_MTRR_PHYSMASK( bits.rdmsr(apicid, msr_num) )
            print("IA32_MTRR_PHYSMASK[{}] MSR {:#x}".format(i, msr_num))
            print(ia32_mtrr_physmask_msr, end='\n\n')
Beispiel #3
0
def rdmsr_consistent(msr_blacklist=set(), msr_masklist=dict()):
    """Rdmsr for all CPU and verify consistent value"""

    cpulist = sorted(bits.cpus())
    for r in [range(0, 0x1000), range(0xC0000000, 0xC0001000)]:
        for msr in r:
            if msr in msr_blacklist:
                continue
            mask = msr_masklist.get(msr, ~0)
            uniques = {}
            for cpu in cpulist:
                value = bits.rdmsr(cpu, msr)
                if value is not None:
                    value &= mask
                uniques.setdefault(value, []).append(cpu)
            testsuite.test("MSR 0x{0:x} consistent".format(msr), len(uniques) == 1)
            # Avoid doing any extra work formatting output when not necessary
            if testsuite.show_detail():
                testsuite.print_detail("{0} unique values".format(len(uniques)))
                for value, cpus in uniques.iteritems():
                    testsuite.print_detail("{0} CPUs: {1}".format(len(cpus), ",".join(str(c) for c in cpus)))
                    if value is None:
                        testsuite.print_detail("MSR 0x{0:x}: GPF".format(msr))
                    else:
                        testsuite.print_detail("MSR 0x{0:x}: 0x{1:x}".format(msr, value))
Beispiel #4
0
def rdmsr_consistent(msr_blacklist=set(), msr_masklist=dict()):
    """Rdmsr for all CPU and verify consistent value"""

    cpulist = sorted(bits.cpus())
    for r in [range(0, 0x1000), range(0xC0000000, 0xC0001000)]:
        for msr in r:
            if msr in msr_blacklist:
                continue
            mask = msr_masklist.get(msr, ~0)
            uniques = {}
            for cpu in cpulist:
                value = bits.rdmsr(cpu, msr)
                if value is not None:
                    value &= mask
                uniques.setdefault(value, []).append(cpu)
            testsuite.test("MSR 0x{0:x} consistent".format(msr),
                           len(uniques) == 1)
            # Avoid doing any extra work formatting output when not necessary
            if testsuite.show_detail():
                testsuite.print_detail("{0} unique values".format(
                    len(uniques)))
                for value, cpus in uniques.iteritems():
                    testsuite.print_detail("{0} CPUs: {1}".format(
                        len(cpus), ",".join(str(c) for c in cpus)))
                    if value is None:
                        testsuite.print_detail("MSR 0x{0:x}: GPF".format(msr))
                    else:
                        testsuite.print_detail("MSR 0x{0:x}: 0x{1:x}".format(
                            msr, value))
Beispiel #5
0
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
Beispiel #6
0
def mwait_callback(use_mwait, name="", hint=0):
    for cpu in bits.cpus():
        bits.set_mwait(cpu, use_mwait, hint, int_break_event)
    with ttypager.page():
        if use_mwait:
            print("MWAIT enabled: {}".format(name))
        else:
            print("MWAIT disabled")
Beispiel #7
0
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))
Beispiel #8
0
def dump():
    with ttypager.page():
        for num, apicid in enumerate(bits.cpus()):
            heading = "Processor {} -- APIC ID {:#x}".format(num, apicid)
            cpu = cpus[apicid]
            print "{}\n{}".format(heading, "="*len(heading))
            print "\n\n{}\n".format("".join(str(cpuid) for cpuid in cpu.cpuids))
            print "\n\n{}\n".format("".join(str(msr) for msr in cpu.msrs))
Beispiel #9
0
def mwait_callback(use_mwait, name="", hint=0):
    for cpu in bits.cpus():
        bits.set_mwait(cpu, use_mwait, hint, int_break_event)
    with ttypager.page():
        if use_mwait:
            print("MWAIT enabled: {}".format(name))
        else:
            print("MWAIT disabled")
Beispiel #10
0
def test_hardware_pstates(ratio_to_control_value):
    IA32_PERF_CTL = 0x199
    with bits.mwait.use_hint(), bits.preserve_msr(IA32_PERF_CTL):
        MSR_PLATFORM_INFO = 0xce
        min_ratio = testmsr.MSR("maximum efficiency ratio",
                                bits.bsp_apicid(),
                                MSR_PLATFORM_INFO,
                                highbit=47,
                                lowbit=40)[0]
        max_ratio = testmsr.MSR("max non-turbo ratio",
                                bits.bsp_apicid(),
                                MSR_PLATFORM_INFO,
                                highbit=15,
                                lowbit=8)[0]

        # Get the Turbo Mode Availability flag
        turbo_mode_available = bits.cpuid(bits.bsp_apicid(), 0).eax >= 6 and (
            bits.cpuid(bits.bsp_apicid(), 6).eax & 0x2)
        last_ratio = max_ratio
        if turbo_mode_available:
            last_ratio += 1

        bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0 / 12) * 1000000

        for ratio in range(min_ratio, last_ratio + 1):
            control_value = ratio_to_control_value(ratio, min_ratio, max_ratio)
            for apicid in bits.cpus():
                bits.wrmsr(apicid, IA32_PERF_CTL, control_value)

            turbo = (ratio == max_ratio + 1)
            if turbo:
                # Needs to busywait, not sleep
                start = time.time()
                while (time.time() - start < 2):
                    pass

            expected = int(ratio * bclk / 1000000)

            for duration in (0.1, 1.0):
                aperf = bits.cpu_frequency(duration)[1]
                aperf = testutil.adjust_to_nearest(aperf, bclk / 2)
                aperf = int(aperf / 1000000)
                if turbo:
                    if aperf >= expected:
                        break
                else:
                    if aperf == expected:
                        break

            if turbo:
                testsuite.test(
                    "Turbo measured frequency {} >= expected {} MHz".format(
                        aperf, expected), aperf >= expected)
            else:
                testsuite.test(
                    "Ratio {} measured frequency {} MHz == expected {} MHz".
                    format(ratio, aperf, expected), aperf == expected)
Beispiel #11
0
def dump():
    with ttypager.page():
        for num, apicid in enumerate(bits.cpus()):
            heading = "Processor {} -- APIC ID {:#x}".format(num, apicid)
            cpu = cpus[apicid]
            print "{}\n{}".format(heading, "=" * len(heading))
            print "\n\n{}\n".format("".join(
                str(cpuid) for cpuid in cpu.cpuids))
            print "\n\n{}\n".format("".join(str(msr) for msr in cpu.msrs))
Beispiel #12
0
def dump():
    s = ""
    for num, apicid in enumerate(bits.cpus()):
        heading = "Processor {} -- APIC ID {:#x}".format(num, apicid)
        cpu = cpus[apicid]
        s += heading + "\n" + "="*len(heading) + "\n\n"
        s += "\n\n".join(str(cpuid) for cpuid in cpu.cpuids) + "\n\n"
        s += "\n\n".join(str(msr) for msr in cpu.msrs) + "\n\n"
    ttypager.ttypager_wrap(s, indent=False)
Beispiel #13
0
def toggle_autodemotion():
    value = bits.rdmsr(bits.bsp_apicid(), 0xe2)
    if bitfields.getbits(value, 26, 25) == 0x3:
        fieldvalue = 0
    else:
        fieldvalue = 0x3
    value = bitfields.setbits(value, fieldvalue, 26, 25)
    for cpu in bits.cpus():
        bits.wrmsr(cpu, 0xe2, value)
    show_autodemotion()
Beispiel #14
0
def toggle_autodemotion():
    value = bits.rdmsr(bits.bsp_apicid(), 0xe2)
    if bitfields.getbits(value, 26, 25) == 0x3:
        fieldvalue = 0
    else:
        fieldvalue = 0x3
    value = bitfields.setbits(value, fieldvalue, 26, 25)
    for cpu in bits.cpus():
        bits.wrmsr(cpu, 0xe2, value)
    show_autodemotion()
Beispiel #15
0
def each_apicid(cpu):
    if cpu is None:
        cpu = os.environ.get("viewpoint", ALL_CPUS)
        if cpu != ALL_CPUS:
            cpu = int(cpu, 0)
    cpus = bits.cpus()
    if cpu == ALL_CPUS:
        for apicid in cpus:
            yield apicid
    else:
        yield cpus[cpu]
Beispiel #16
0
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
Beispiel #17
0
def test_hardware_pstates(ratio_to_control_value):
    old_mwait = {}
    try:
        MSR_PLATFORM_INFO = 0xce
        IA32_PERF_CTL = 0x199
        min_ratio = testmsr.MSR("maximum efficiency ratio", bits.bsp_apicid(), MSR_PLATFORM_INFO, highbit=47, lowbit=40)[0]
        max_ratio = testmsr.MSR("max non-turbo ratio", bits.bsp_apicid(), MSR_PLATFORM_INFO, highbit=15, lowbit=8)[0]

        # Get the Turbo Mode Availability flag
        turbo_mode_available = bits.cpuid(bits.bsp_apicid(),0).eax >= 6 and (bits.cpuid(bits.bsp_apicid(),6).eax & 0x2)
        last_ratio = max_ratio
        if turbo_mode_available:
            last_ratio += 1

        duration = last_ratio - min_ratio + 1
        if turbo_mode_available:
            duration += 2
        print "Test duration is ~{} seconds...".format(duration)

        # Force use of MWAIT C3
        hint = 0x20
        cpus = bits.cpus()
        for apicid in cpus:
            old_mwait[apicid] = bits.get_mwait(apicid)
            bits.set_mwait(apicid, True, hint)

        bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000

        for ratio in range(min_ratio, last_ratio + 1):
            control_value = ratio_to_control_value(ratio, min_ratio, max_ratio)
            for apicid in cpus:
                bits.wrmsr(apicid, IA32_PERF_CTL, control_value)

            if ratio == max_ratio + 1:
                # Needs to busywait, not sleep
                start = time.time()
                while (time.time() - start < 2):
                    pass

            aperf = bits.cpu_frequency()[1]
            aperf = testutil.adjust_to_nearest(aperf, bclk/2)
            aperf = int(aperf / 1000000)

            expected = int(ratio * bclk / 1000000)

            if ratio == max_ratio + 1:
                testsuite.test("Turbo measured frequency {} >= expected {} MHz".format(aperf, expected), aperf >= expected)
            else:
                testsuite.test("Ratio {} measured frequency {} MHz == expected {} MHz".format(ratio, aperf, expected), aperf == expected)
    finally:
        for apicid, old_mwait_values in old_mwait.iteritems():
            bits.set_mwait(apicid, *old_mwait_values)
Beispiel #18
0
def cmd_cpuid32(args):
    if args.cpu is not None:
        args.cpu = bits.cpus()[args.cpu]
    uniques, desc = testcpuid.cpuid_helper(args.function, args.index, args.cpu, args.shift, args.mask, args.eax_mask, args.ebx_mask, args.ecx_mask, args.edx_mask)
    if args.env:
        if len(uniques) > 1:
            print "Setting environment vars eax,ebx,ecx,edx requested; but register values are not unique"
            return False
        for regname, regvalue in uniques.keys()[0]._asdict().iteritems():
            os.putenv(regname, "{:#x}".format(regvalue))
    if not args.quiet:
        print "\n".join(desc)
    return True
Beispiel #19
0
 def cpupath_apicid(cpupath):
     if procid_apicid is not None:
         procid = cpupath_procid.get(cpupath, None)
         if procid is not None:
             apicid = procid_apicid.get(procid, None)
             if apicid is not None:
                 return apicid
     if uid_x2apicid is not None:
         uid = cpupath_uid.get(cpupath, None)
         if uid is not None:
             apicid = uid_x2apicid.get(uid, None)
             if apicid is not None:
                 return apicid
     return bits.cpus()[0]
Beispiel #20
0
def use_hint(hint=None):
    """Context manager to temporarily set the mwait hint of all CPUs"""
    global default_hint
    if hint is None:
        hint = default_hint
    old_mwait = {}
    try:
        for apicid in bits.cpus():
            old_mwait[apicid] = bits.get_mwait(apicid)
            bits.set_mwait(apicid, True, hint)
        yield
    finally:
        for apicid, old_mwait_values in old_mwait.iteritems():
            bits.set_mwait(apicid, *old_mwait_values)
Beispiel #21
0
def use_hint(hint=None):
    """Context manager to temporarily set the mwait hint of all CPUs"""
    global default_hint
    if hint is None:
        hint = default_hint
    old_mwait = {}
    try:
        for apicid in bits.cpus():
            old_mwait[apicid] = bits.get_mwait(apicid)
            bits.set_mwait(apicid, True, hint)
        yield
    finally:
        for apicid, old_mwait_values in old_mwait.iteritems():
            bits.set_mwait(apicid, *old_mwait_values)
Beispiel #22
0
 def cpupath_apicid(cpupath):
     if procid_apicid is not None:
         procid = cpupath_procid.get(cpupath, None)
         if procid is not None:
             apicid = procid_apicid.get(procid, None)
             if apicid is not None:
                 return apicid
     if uid_x2apicid is not None:
         uid = cpupath_uid.get(cpupath, None)
         if uid is not None:
             apicid = uid_x2apicid.get(uid, None)
             if apicid is not None:
                 return apicid
     return bits.cpus()[0]
Beispiel #23
0
def cmd_rdmsr(args):
    if args.cpu is not None:
        args.cpu = bits.cpus()[args.cpu]
    uniques, desc = testmsr.rdmsr_helper(msr=args.msr, cpu=args.cpu, shift=args.shift, mask=args.mask)
    if not args.quiet:
        print "\n".join(desc)
    value = uniques.keys()[0]
    if args.varname is not None:
        if len(uniques) > 1:
            print "Variable setting requested but MSR value not unique"
            return False
        if value is None:
            print "Variable setting requested but MSR read caused GPF"
            return False
        os.putenv(args.varname, "{0:#x}".format(value))
    return len(uniques) == 1 and value is not None
Beispiel #24
0
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
Beispiel #25
0
def test(residency_tests, residency_counter_msr, residency_counters):
    cpus = bits.cpus()
    for states, hint in residency_tests:
        with bits.mwait.use_hint(hint):
            delta = residency(residency_counters, residency_counter_msr)
            detail = False
            for state in states:
                for apic_id, r in sorted(delta.iteritems()):
                    state_residency = getattr(r, state)
                    testsuite.test("MWAIT hint {:#x}, socket {} {} residency {:4.0%} (expected >= 85%)".format(hint, bits.socket_index(apic_id), state.upper(), state_residency), state_residency >= 0.85)
                    detail = detail or testsuite.show_detail()
            if detail:
                print testsuite.format_detail("Full residency for MWAIT hint {:#x}:".format(hint))
                print testsuite.format_detail(" SKT  APIC" + "".join("{:>6s}".format(field.upper()) for field in residency_counters._fields))
                for apic_id, r in sorted(delta.iteritems()):
                    skt_index = bits.socket_index(apic_id)
                    print testsuite.format_detail("{:4d}  {:#04x}  ".format(skt_index, apic_id) + "  ".join("{:4.0%}".format(field) for field in r))
Beispiel #26
0
def test_hardware_pstates(ratio_to_control_value):
    IA32_PERF_CTL = 0x199
    with bits.mwait.use_hint(), bits.preserve_msr(IA32_PERF_CTL):
        MSR_PLATFORM_INFO = 0xce
        min_ratio = testmsr.MSR("maximum efficiency ratio", bits.bsp_apicid(), MSR_PLATFORM_INFO, highbit=47, lowbit=40)[0]
        max_ratio = testmsr.MSR("max non-turbo ratio", bits.bsp_apicid(), MSR_PLATFORM_INFO, highbit=15, lowbit=8)[0]

        # Get the Turbo Mode Availability flag
        turbo_mode_available = bits.cpuid(bits.bsp_apicid(),0).eax >= 6 and (bits.cpuid(bits.bsp_apicid(),6).eax & 0x2)
        last_ratio = max_ratio
        if turbo_mode_available:
            last_ratio += 1

        bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000

        for ratio in range(min_ratio, last_ratio + 1):
            control_value = ratio_to_control_value(ratio, min_ratio, max_ratio)
            for apicid in bits.cpus():
                bits.wrmsr(apicid, IA32_PERF_CTL, control_value)

            turbo = (ratio == max_ratio + 1)
            if turbo:
                # Needs to busywait, not sleep
                start = time.time()
                while (time.time() - start < 2):
                    pass

            expected = int(ratio * bclk / 1000000)

            for duration in (0.1, 1.0):
                aperf = bits.cpu_frequency(duration)[1]
                aperf = testutil.adjust_to_nearest(aperf, bclk/2)
                aperf = int(aperf / 1000000)
                if turbo:
                    if aperf >= expected:
                        break
                else:
                    if aperf == expected:
                        break

            if turbo:
                testsuite.test("Turbo measured frequency {} >= expected {} MHz".format(aperf, expected), aperf >= expected)
            else:
                testsuite.test("Ratio {} measured frequency {} MHz == expected {} MHz".format(ratio, aperf, expected), aperf == expected)
Beispiel #27
0
def cmd_cpu(args):
    cpus = bits.cpus()
    ncpus = len(cpus)
    if args.num is not None:
        if args.num == ALL_CPUS:
            os.unsetenv("viewpoint")
        else:
            os.putenv("viewpoint", str(args.num))
    if args.list:
        print "{} CPUs: 0-{}".format(ncpus, ncpus-1)
        for i in range(ncpus):
            # print 4 per line
            print 'CPU{: <3d} = {: <#10x}'.format(i, cpus[i]),
            if i == (ncpus - 1) or (i % 4) == 3:
                print
    if not args.quiet:
        print "Assigned CPU number = {}".format(os.environ.get("viewpoint", 'all'))
    if args.env:
        os.putenv("apicid_list", " ".join("{:#x}".format(cpu) for cpu in sorted(cpus)))
Beispiel #28
0
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
Beispiel #29
0
def topology():
    """Return a dictionary relating each socket APIC ID to its cores' APIC IDs, and each core to its threads' APIC IDs.

    Raises RuntimeError if CPUID leaf 0xb not supported."""
    socket_dict = OrderedDict()
    prev_socket_num = None

    for apicid in sorted(bits.cpus(), key=_apickey):
        current_socket_num, current_core_num, apicid = thread(apicid)

        if current_socket_num != prev_socket_num:
            core_dict = OrderedDict()
            socket_dict[apicid] = core_dict
            prev_core_num = None
        if current_core_num != prev_core_num:
            thread_list = []
            core_dict[apicid] = thread_list
        thread_list.append(apicid)
        prev_socket_num = current_socket_num
        prev_core_num = current_core_num
    return socket_dict
Beispiel #30
0
def topology():
    """Return a dictionary relating each socket APIC ID to its cores' APIC IDs, and each core to its threads' APIC IDs.
    
    Raises RuntimeError if CPUID leaf 0xb not supported."""
    socket_dict = OrderedDict()
    prev_socket_num = None

    for apicid in sorted(bits.cpus(), key=_apickey):
        current_socket_num, current_core_num, apicid = thread(apicid)

        if current_socket_num != prev_socket_num:
            core_dict = OrderedDict()
            socket_dict[apicid] = core_dict
            prev_core_num = None
        if current_core_num != prev_core_num:
            thread_list = []
            core_dict[apicid] = thread_list
        thread_list.append(apicid)
        prev_socket_num = current_socket_num
        prev_core_num = current_core_num
    return socket_dict
Beispiel #31
0
def test_smrr():
    """Test the SMRR-related configuration"""
    cpus = sorted(bits.cpus())
    if not testmsr.test_msr_consistency(
        text="IA32_MTRRCAP Bit [11] (SMRR Supported) must be consistent", first_msr=0xFE, shift=11, mask=1
    ):
        return
    ia32_mtrrcap = bits.rdmsr(cpus[0], 0xFE)
    if ia32_mtrrcap is not None and not ia32_mtrrcap & (1 << 11):
        return
    if testmsr.msr_available(0x1F2) and testmsr.msr_available(0x1F3):
        MSR_SMRR_PHYS_BASE = 0x1F2
        MSR_SMRR_PHYS_MASK = 0x1F3
    elif testmsr.msr_available(0xA0) and testmsr.msr_available(0xA1):
        MSR_SMRR_PHYS_BASE = 0xA0
        MSR_SMRR_PHYS_MASK = 0xA1
        return
    else:
        return
    testmsr.test_msr_consistency(
        text="SMRR must be consistent across all processors", first_msr=MSR_SMRR_PHYS_BASE, last_msr=MSR_SMRR_PHYS_MASK
    )
    for apicid in cpus:
        smrr_physbase, smrr_physbase_str = testmsr.MSR("SMRR Physbase", apicid, MSR_SMRR_PHYS_BASE, 31, 12)
        smrr_type, smrr_type_str = testmsr.MSR("SMRR Type", apicid, MSR_SMRR_PHYS_BASE, 2, 0)
        smrr_physmask, smrr_physmask_str = testmsr.MSR("SMRR Physmask", apicid, MSR_SMRR_PHYS_MASK, 31, 12)
        smrr_valid, smrr_valid_str = testmsr.MSR("SMRR Valid", apicid, MSR_SMRR_PHYS_MASK, 11, 11)
        testsuite.test("SMRR_PHYSBASE must be aligned on an 8MB boundary", (smrr_physbase % 0x800) == 0)
        testsuite.print_detail(smrr_physbase_str)
        testsuite.print_detail("SMRR_PHYSBASE % 0x800 must be 0")
        testsuite.test("SMRR Type must be Write-Back (Best performance)", smrr_type == 6)
        testsuite.print_detail(smrr_type_str)
        testsuite.print_detail("SMRR Type must be 6")
        testsuite.test("SMRR size must be at least 8MB", smrr_physmask >= 0x800)
        testsuite.print_detail(smrr_physmask_str)
        testsuite.print_detail("SMRR Physmask must be >= 0x800")
        testsuite.test("SMRR Valid bit must be 1", smrr_valid)
        testsuite.print_detail(smrr_valid_str)
Beispiel #32
0
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
Beispiel #33
0
def test_pstates():
    """Execute and verify frequency for each Pstate in the _PSS"""
    old_mwait = {}
    try:
        IA32_PERF_CTL = 0x199

        # Force use of MWAIT C3
        hint = 0x20
        cpus = bits.cpus()
        for apicid in cpus:
            old_mwait[apicid] = bits.get_mwait(apicid)
            bits.set_mwait(apicid, True, hint)

        cpupath_procid = acpi.find_procid()
        cpupath_uid = acpi.find_uid()
        procid_apicid, uid_x2apicid = acpi.parse_apic()
        def cpupath_apicid(cpupath):
            if procid_apicid is not None:
                procid = cpupath_procid.get(cpupath, None)
                if procid is not None:
                    apicid = procid_apicid.get(procid, None)
                    if apicid is not None:
                        return apicid
            if uid_x2apicid is not None:
                uid = cpupath_uid.get(cpupath, None)
                if uid is not None:
                    apicid = uid_x2apicid.get(uid, None)
                    if apicid is not None:
                        return apicid
            return bits.cpus()[0]

        bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000

        uniques = acpi.parse_cpu_method("_PSS")
        for pss, cpupaths in uniques.iteritems():
            if not testsuite.test("_PSS must exist", pss is not None):
                testsuite.print_detail(acpi.factor_commonprefix(cpupaths))
                testsuite.print_detail('No _PSS exists')
                continue

            print "Test duration is ~{} seconds...".format(len(pss.pstates) + 2)

            for n, pstate in enumerate(pss.pstates):
                for cpupath in cpupaths:
                    apicid = cpupath_apicid(cpupath)
                    if apicid is None:
                        print 'Failed to find apicid for cpupath {}'.format(cpupath)
                        continue
                    bits.wrmsr(apicid, IA32_PERF_CTL, pstate.control)

                # Detecting Turbo frequency requires at least 2 pstates
                # since turbo frequency = max non-turbo frequency + 1
                turbo = False
                if len(pss.pstates) >= 2:
                    turbo = (n == 0 and pstate.core_frequency == (pss.pstates[1].core_frequency + 1))
                    if turbo:
                        # Needs to busywait, not sleep
                        start = time.time()
                        while (time.time() - start < 2):
                            pass

                # Abort the test if no cpu frequency is not available
                if bits.cpu_frequency() is None:
                    continue
                aperf = bits.cpu_frequency()[1]

                aperf = testutil.adjust_to_nearest(aperf, bclk/2)
                aperf = int(aperf / 1000000)

                if turbo:
                    testsuite.test("P{}: Turbo measured frequency {} >= expected {} MHz".format(n, aperf, pstate.core_frequency), aperf >= pstate.core_frequency)
                else:
                    testsuite.test("P{}: measured frequency {} MHz == expected {} MHz".format(n, aperf, pstate.core_frequency), aperf == pstate.core_frequency)
    finally:
        for apicid, old_mwait_values in old_mwait.iteritems():
            bits.set_mwait(apicid, *old_mwait_values)
Beispiel #34
0
def apicid_list(apicids):
    if len(apicids) == len(bits.cpus()):
        return "all"
    else:
        return " ".join("{0:#x}".format(cpu) for cpu in sorted(apicids))
Beispiel #35
0
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""testing module."""

import bits
from cpudetect import cpulib
import testsuite
import unittest

def f(x):
    """Test function in a test module."""
    for i in range(x):
        print ("Hello from a function in a module, for the %dth time" % i)

# Save the list of CPUs
cpulist = bits.cpus()

# Build a reverse mapping from APIC ID to CPU number
apicid_index = dict([(apicid, i) for (i, apicid) in enumerate(cpulist)])

def rdmsr_test():
    """Test the rdmsr function"""
    for cpu in cpulist:
        for msr in [0x10, 0x40000000]:
            value = bits.rdmsr(cpu, msr)
            if value is None:
                print "CPU 0x%x MSR 0x%x: GPF" % (cpu, msr)
            else:
                print "CPU 0x%x MSR 0x%x: 0x%x" % (cpu, msr, value)

def ppm_test1():
Beispiel #36
0
def parse_cpu(s):
    if s.lower() == 'all':
        return ALL_CPUS
    return parse_int(s, "CPU", max_bound = len(bits.cpus())-1)
Beispiel #37
0
"""testing module."""

import bits
from cpudetect import cpulib
import testsuite
import unittest


def f(x):
    """Test function in a test module."""
    for i in range(x):
        print("Hello from a function in a module, for the %dth time" % i)


# Save the list of CPUs
cpulist = bits.cpus()

# Build a reverse mapping from APIC ID to CPU number
apicid_index = dict([(apicid, i) for (i, apicid) in enumerate(cpulist)])


def rdmsr_test():
    """Test the rdmsr function"""
    for cpu in cpulist:
        for msr in [0x10, 0x40000000]:
            value = bits.rdmsr(cpu, msr)
            if value is None:
                print "CPU 0x%x MSR 0x%x: GPF" % (cpu, msr)
            else:
                print "CPU 0x%x MSR 0x%x: 0x%x" % (cpu, msr, value)
Beispiel #38
0
import bits
from bits.cpuids import generate_cpuids
from bits.msrs import sample_msrs
import bits.platformbase
import ttypager

MSRS = bits.platformbase.make_MSRS(sample_msrs())


class CPU(object):
    def __init__(self, apicid):
        self.apicid = apicid
        self.msrs = MSRS(apicid)
        CPUIDS = bits.platformbase.make_CPUIDS(generate_cpuids(apicid))
        self.cpuids = CPUIDS(apicid)


cpus = dict((n, CPU(n)) for n in bits.cpus())


def dump():
    with ttypager.page():
        for num, apicid in enumerate(bits.cpus()):
            heading = "Processor {} -- APIC ID {:#x}".format(num, apicid)
            cpu = cpus[apicid]
            print "{}\n{}".format(heading, "=" * len(heading))
            print "\n\n{}\n".format("".join(
                str(cpuid) for cpuid in cpu.cpuids))
            print "\n\n{}\n".format("".join(str(msr) for msr in cpu.msrs))
Beispiel #39
0
def apicid_list(apicids):
    if len(apicids) == len(bits.cpus()):
        return "all"
    else:
        return " ".join("{0:#x}".format(cpu) for cpu in sorted(apicids))
Beispiel #40
0
def msr_available(msr):
    """Return True if the specified MSR exists on all CPUs"""
    return all(bits.rdmsr(cpu_num, msr) is not None for cpu_num in bits.cpus())
Beispiel #41
0
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Hierarchical object-based CPU register (CPUID and MSR) decoding"""

import bits
from cpuids import generate_cpuids
from msrs import sample_msrs
import platformbase
import ttypager

MSRS = platformbase.make_MSRS(sample_msrs())

class CPU(object):
    def __init__(self, apicid):
        self.apicid = apicid
        self.msrs = MSRS(apicid)
        CPUIDS = platformbase.make_CPUIDS(generate_cpuids(apicid))
        self.cpuids = CPUIDS(apicid)

cpus = dict((n, CPU(n)) for n in bits.cpus())

def dump():
    s = ""
    for num, apicid in enumerate(bits.cpus()):
        heading = "Processor {} -- APIC ID {:#x}".format(num, apicid)
        cpu = cpus[apicid]
        s += heading + "\n" + "="*len(heading) + "\n\n"
        s += "\n\n".join(str(cpuid) for cpuid in cpu.cpuids) + "\n\n"
        s += "\n\n".join(str(msr) for msr in cpu.msrs) + "\n\n"
    ttypager.ttypager_wrap(s, indent=False)
Beispiel #42
0
def cmd_test_msr(args):
    if args.cpu is not None:
        args.cpu = bits.cpus()[args.cpu]
    return testmsr.test_msr(**vars(args))
Beispiel #43
0
def msr_available(msr):
    """Return True if the specified MSR exists on all CPUs"""
    return all(bits.rdmsr(cpu_num, msr) is not None for cpu_num in bits.cpus())