[PATCH v3 33/44] x86/cpuid: Parse deterministic cache parameters CPUID leaves
"Ahmed S. Darwish" <[email protected]>
| Newsgroups | dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Add CPUID parser logic for Intel CPUID(0x4) and AMD CPUID(0x8000001d). Define a single cpuid_read_deterministic_cache() parsing function for both leaves, as both have the same subleaf cache enumeration logic. Introduce __define_cpuid_read_function() macro to avoid code duplication between cpuid_read_generic(), the CPUID parser's default read function, and the new cpuid_read_deterministic_cache() one. Signed-off-by: Ahmed S. Darwish <[email protected]> --- arch/x86/include/asm/cpuid/types.h | 2 ++ arch/x86/kernel/cpu/cpuid_parser.c | 37 +++++++++++++++++++++++++----- arch/x86/kernel/cpu/cpuid_parser.h | 4 +++- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/cpuid/types.h b/arch/x86/include/asm/cpuid/types.h index 7bbf0671cb95..89c399629e58 100644 --- a/arch/x86/include/asm/cpuid/types.h +++ b/arch/x86/include/asm/cpuid/types.h @@ -216,7 +216,9 @@ struct cpuid_leaves { CPUID_LEAF(0x0, 0, 1); CPUID_LEAF(0x1, 0, 1); CPUID_LEAF(0x2, 0, 1); + CPUID_LEAF(0x4, 0, 8); CPUID_LEAF(0x80000000, 0, 1); + CPUID_LEAF(0x8000001d, 0, 8); }; /* diff --git a/arch/x86/kernel/cpu/cpuid_parser.c b/arch/x86/kernel/cpu/cpuid_parser.c index 9bd68b150150..3d0fa1c12ad0 100644 --- a/arch/x86/kernel/cpu/cpuid_parser.c +++ b/arch/x86/kernel/cpu/cpuid_parser.c @@ -16,17 +16,42 @@ * Leaf read functions: */ -/* - * Default CPUID parser read function +/** + * __define_cpuid_parser_read_function() - Generate a CPUID parser leaf read function + * @suffix: Generated function name suffix (full name becomes: cpuid_read_@suffix()) + * @_leaf_t: Type to cast the CPUID query output storage pointer + * @_leaf: Name of the CPUID query storage pointer + * @_break_c: Condition to break the CPUID parsing loop, which may reference @_leaf, and + * where @_leaf stores each iteration's CPUID query output. * * Satisfies the requirements stated at 'struct cpuid_parse_entry'->read(). + * Define a CPUID parser read function according to the requirements stated at + * 'struct cpuid_parse_entry'->read(). */ -static void cpuid_read_generic(const struct cpuid_parse_entry *e, struct cpuid_read_output *output) -{ - for (int i = 0; i < e->maxcnt; i++, output->regs++, output->info->nr_entries++) - cpuid_read_subleaf(e->leaf, e->subleaf + i, output->regs); +#define __define_cpuid_parser_read_function(suffix, _leaf_t, _leaf, _break_c) \ +static void \ +cpuid_read_##suffix(const struct cpuid_parse_entry *e, struct cpuid_read_output *output) \ +{ \ + struct _leaf_t *_leaf = (struct _leaf_t *)output->regs; \ + \ + for (int i = 0; i < e->maxcnt; i++, _leaf++, output->info->nr_entries++) { \ + cpuid_read_subleaf(e->leaf, e->subleaf + i, _leaf); \ + if (_break_c) \ + break; \ + } \ } +/* + * Default CPUID parser read function + */ +__define_cpuid_parser_read_function(generic, cpuid_regs, ignored, false); + +/* + * Shared read function for Intel CPUID(0x4) and AMD CPUID(0x8000001d), as both have + * the same subleaf enumeration logic and registers output format. + */ +__define_cpuid_parser_read_function(deterministic_cache, leaf_0x4_0, l, l->cache_type == 0); + static void cpuid_read_0x2(const struct cpuid_parse_entry *e, struct cpuid_read_output *output) { union leaf_0x2_regs *regs = (union leaf_0x2_regs *)output->regs; diff --git a/arch/x86/kernel/cpu/cpuid_parser.h b/arch/x86/kernel/cpu/cpuid_parser.h index cf999e6a574d..be4ef64c48b6 100644 --- a/arch/x86/kernel/cpu/cpuid_parser.h +++ b/arch/x86/kernel/cpu/cpuid_parser.h @@ -97,7 +97,9 @@ struct cpuid_parse_entry { CPUID_PARSE_ENTRY(0x0, 0, generic), \ CPUID_PARSE_ENTRY(0x1, 0, generic), \ CPUID_PARSE_ENTRY(0x2, 0, 0x2), \ - CPUID_PARSE_ENTRY(0x80000000, 0, 0x80000000), + CPUID_PARSE_ENTRY(0x4, 0, deterministic_cache), \ + CPUID_PARSE_ENTRY(0x80000000, 0, 0x80000000), \ + CPUID_PARSE_ENTRY(0x8000001d, 0, deterministic_cache), extern const struct cpuid_parse_entry cpuid_common_parse_entries[]; extern const int cpuid_common_parse_entries_size; -- 2.49.0