[libvirt PATCH 0/3] cpu-data.py: Add support for kcpuid

Linux 5.13 introduces "kcpuid", a tool similar to cpuid, which we depend on for cpu-data collection with tests/cputestdata/cpu-data.py. This series adds support for kcpuid to cpu-data.py. See also https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tool... /arch/x86/kcpuid and https://lore.kernel.org/lkml/1614928878-86075-1-git-send-email-feng.tang@int... l.com/ Tim Wiederhake (3): cpu-data.py: Factor out cpuid parsing cpu-data.py: Parse kcpuid output cpu-data.py: Automatically adjust command line for kcpuid tests/cputestdata/cpu-data.py | 95 +++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 20 deletions(-) --=20 2.26.3

Preparation for next patch. Signed-off-by: Tim Wiederhake <twiederh@redhat.com> --- tests/cputestdata/cpu-data.py | 44 +++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/tests/cputestdata/cpu-data.py b/tests/cputestdata/cpu-data.py index df71132c25..ac4d0ff8e7 100755 --- a/tests/cputestdata/cpu-data.py +++ b/tests/cputestdata/cpu-data.py @@ -35,14 +35,7 @@ def gather_name(args): "Use '--model' to set a model name.") -def gather_cpuid_leaves(args): - def mask(regs, eax_in, ecx_in, eax_mask, ebx_mask, ecx_mask, edx_mask): - if regs["eax_in"] == eax_in and regs["ecx_in"] == ecx_in: - regs["eax"] &= eax_mask - regs["ebx"] &= ebx_mask - regs["ecx"] &= ecx_mask - regs["edx"] &= edx_mask - +def gather_cpuid_leaves_cpuid(output): leave_pattern = re.compile( "^\\s*" "(0x[0-9a-f]+)\\s*" @@ -52,22 +45,11 @@ def gather_cpuid_leaves(args): "ecx=(0x[0-9a-f]+)\\s*" "edx=(0x[0-9a-f]+)\\s*$") - cpuid = args.path_to_cpuid or "cpuid" - try: - output = subprocess.check_output( - [cpuid, "-1r"], - universal_newlines=True) - except FileNotFoundError as e: - exit("Error: '{}' not found.\n'cpuid' can be usually found in a " - "package named identically. If your distro does not provide such " - "package, you can find the sources or binary packages at " - "'http://www.etallen.com/cpuid.html'.".format(e.filename)) - for line in output.split("\n"): match = leave_pattern.match(line) if not match: continue - regs = { + yield { "eax_in": int(match.group(1), 0), "ecx_in": int(match.group(2), 0), "eax": int(match.group(3), 0), @@ -75,6 +57,28 @@ def gather_cpuid_leaves(args): "ecx": int(match.group(5), 0), "edx": int(match.group(6), 0)} + +def gather_cpuid_leaves(args): + def mask(regs, eax_in, ecx_in, eax_mask, ebx_mask, ecx_mask, edx_mask): + if regs["eax_in"] == eax_in and regs["ecx_in"] == ecx_in: + regs["eax"] &= eax_mask + regs["ebx"] &= ebx_mask + regs["ecx"] &= ecx_mask + regs["edx"] &= edx_mask + + cpuid = args.path_to_cpuid or "cpuid" + try: + output = subprocess.check_output( + [cpuid, "-1r"], + universal_newlines=True) + except FileNotFoundError as e: + exit("Error: '{}' not found.\n'cpuid' can be usually found in a " + "package named identically. If your distro does not provide such " + "package, you can find the sources or binary packages at " + "'http://www.etallen.com/cpuid.html'.".format(e.filename)) + + reglist = gather_cpuid_leaves_cpuid(output) + for regs in reglist: # local apic id. Pretend to always run on logical processor #0. mask(regs, 0x01, 0x00, 0xffffffff, 0x00ffffff, 0xffffffff, 0xffffffff) mask(regs, 0x0b, 0x00, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00) -- 2.26.3

Linux 5.13 introduces "kcpuid", a tool similar to "cpuid", see https://lore.kernel.org/lkml/1614928878-86075-1-git-send-email-feng.tang@int... Output formats of cpuid and kcpuid differ slightly. This adds support for the latter. Signed-off-by: Tim Wiederhake <twiederh@redhat.com> --- tests/cputestdata/cpu-data.py | 53 ++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/tests/cputestdata/cpu-data.py b/tests/cputestdata/cpu-data.py index ac4d0ff8e7..4305aacf35 100755 --- a/tests/cputestdata/cpu-data.py +++ b/tests/cputestdata/cpu-data.py @@ -58,6 +58,53 @@ def gather_cpuid_leaves_cpuid(output): "edx": int(match.group(6), 0)} +def gather_cpuid_leaves_kcpuid(output): + leave_pattern = re.compile( + "^(0x[0-9a-f]+): " + "EAX=(0x[0-9a-f]+), " + "EBX=(0x[0-9a-f]+), " + "ECX=(0x[0-9a-f]+), " + "EDX=(0x[0-9a-f]+)$") + branch_pattern_head = re.compile( + "^(0x[0-9a-f]+): " + "subleafs:$") + branch_pattern_body = re.compile( + "^\\s*([0-9]+): " + "EAX=(0x[0-9a-f]+), " + "EBX=(0x[0-9a-f]+), " + "ECX=(0x[0-9a-f]+), " + "EDX=(0x[0-9a-f]+)$") + + regs = list() + eax_in = 0 + for line in output.split("\n"): + match = branch_pattern_head.match(line) + if match: + eax_in = int(match.group(1), 0) + continue + match = branch_pattern_body.match(line) + if match: + regs.append({ + "eax_in": eax_in, + "ecx_in": int(match.group(1), 0), + "eax": int(match.group(2), 0), + "ebx": int(match.group(3), 0), + "ecx": int(match.group(4), 0), + "edx": int(match.group(5), 0)}) + continue + match = leave_pattern.match(line) + if match: + regs.append({ + "eax_in": int(match.group(1), 0), + "ecx_in": 0, + "eax": int(match.group(2), 0), + "ebx": int(match.group(3), 0), + "ecx": int(match.group(4), 0), + "edx": int(match.group(5), 0)}) + continue + return regs + + def gather_cpuid_leaves(args): def mask(regs, eax_in, ecx_in, eax_mask, ebx_mask, ecx_mask, edx_mask): if regs["eax_in"] == eax_in and regs["ecx_in"] == ecx_in: @@ -77,7 +124,11 @@ def gather_cpuid_leaves(args): "package, you can find the sources or binary packages at " "'http://www.etallen.com/cpuid.html'.".format(e.filename)) - reglist = gather_cpuid_leaves_cpuid(output) + if "=====" in output: + reglist = gather_cpuid_leaves_kcpuid(output) + else: + reglist = gather_cpuid_leaves_cpuid(output) + for regs in reglist: # local apic id. Pretend to always run on logical processor #0. mask(regs, 0x01, 0x00, 0xffffffff, 0x00ffffff, 0xffffffff, 0xffffffff) -- 2.26.3

kcpuid does not have a "-1" flag. Signed-off-by: Tim Wiederhake <twiederh@redhat.com> --- tests/cputestdata/cpu-data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cputestdata/cpu-data.py b/tests/cputestdata/cpu-data.py index 4305aacf35..d8a89ebc2a 100755 --- a/tests/cputestdata/cpu-data.py +++ b/tests/cputestdata/cpu-data.py @@ -116,7 +116,7 @@ def gather_cpuid_leaves(args): cpuid = args.path_to_cpuid or "cpuid" try: output = subprocess.check_output( - [cpuid, "-1r"], + [cpuid, "-r" if "kcpuid" in cpuid else "-1r"], universal_newlines=True) except FileNotFoundError as e: exit("Error: '{}' not found.\n'cpuid' can be usually found in a " -- 2.26.3

ping On Tue, 2021-04-27 at 10:25 +0200, Tim Wiederhake wrote:
Linux 5.13 introduces "kcpuid", a tool similar to cpuid, which we depend on for cpu-data collection with tests/cputestdata/cpu-data.py.
This series adds support for kcpuid to cpu-data.py.
See also https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tool... /arch/x86/kcpuid and https://lore.kernel.org/lkml/1614928878-86075-1-git-send-email-feng.tang@int... l.com/
Tim Wiederhake (3): cpu-data.py: Factor out cpuid parsing cpu-data.py: Parse kcpuid output cpu-data.py: Automatically adjust command line for kcpuid
tests/cputestdata/cpu-data.py | 95 +++++++++++++++++++++++++++---- ---- 1 file changed, 75 insertions(+), 20 deletions(-)
--=20 2.26.3

On 4/27/21 10:25 AM, Tim Wiederhake wrote:
Linux 5.13 introduces "kcpuid", a tool similar to cpuid, which we depend on for cpu-data collection with tests/cputestdata/cpu-data.py.
This series adds support for kcpuid to cpu-data.py.
See also https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tool... /arch/x86/kcpuid and https://lore.kernel.org/lkml/1614928878-86075-1-git-send-email-feng.tang@int... l.com/
Tim Wiederhake (3): cpu-data.py: Factor out cpuid parsing cpu-data.py: Parse kcpuid output cpu-data.py: Automatically adjust command line for kcpuid
tests/cputestdata/cpu-data.py | 95 +++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 20 deletions(-)
--=20 2.26.3
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> and pushed. Michal
participants (2)
-
Michal Prívozník
-
Tim Wiederhake