Commit b5075354 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86-misc-2024-09-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull misc x86 updates from Thomas Gleixner:

 - Rework kcpuid to handle the the autogenerated CSV file correctly and
   update the CSV file to cover the whole zoo of CPUID.

 - Avoid memcpy() for ia32 syscall_get_arguments() and use direct
   assignments as fortified memcpy() is unhappy about writing/reading
   beyond the end of the addresses destination/source struct member

 - A few new PCI IDs for AMD

 - Update MAINTAINERS to cover x86 specific selftests

* tag 'x86-misc-2024-09-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  MAINTAINERS: Add selftests/x86 entry
  x86/amd_nb: Add new PCI IDs for AMD family 1Ah model 60h-70h
  x86/syscall: Avoid memcpy() for ia32 syscall_get_arguments()
  MAINTAINERS: Add x86 cpuid database entry
  tools/x86/kcpuid: Introduce a complete cpuid bitfields CSV file
  tools/x86/kcpuid: Parse subleaf ranges if provided
  tools/x86/kcpuid: Recognize all leaves with subleaves
  tools/x86/kcpuid: Strip bitfield names leading/trailing whitespace
  tools/x86/kcpuid: Protect against faulty "max subleaf" values
  tools/x86/kcpuid: Set max possible subleaves count to 64
  tools/x86/kcpuid: Properly align long-description columns
  tools/x86/kcpuid: Remove unused variable
  x86/amd_nb: Add new PCI IDs for AMD family 1Ah model 60h
parents a3233da6 4460e853
...@@ -24915,6 +24915,17 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core ...@@ -24915,6 +24915,17 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
F: Documentation/arch/x86/ F: Documentation/arch/x86/
F: Documentation/devicetree/bindings/x86/ F: Documentation/devicetree/bindings/x86/
F: arch/x86/ F: arch/x86/
F: tools/testing/selftests/x86
X86 CPUID DATABASE
M: Borislav Petkov <bp@alien8.de>
M: Thomas Gleixner <tglx@linutronix.de>
M: x86@kernel.org
R: Ahmed S. Darwish <darwi@linutronix.de>
L: x86-cpuid@lists.linux.dev
S: Maintained
W: https://x86-cpuid.org
F: tools/arch/x86/kcpuid/cpuid.csv
X86 ENTRY CODE X86 ENTRY CODE
M: Andy Lutomirski <luto@kernel.org> M: Andy Lutomirski <luto@kernel.org>
......
...@@ -82,7 +82,12 @@ static inline void syscall_get_arguments(struct task_struct *task, ...@@ -82,7 +82,12 @@ static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs, struct pt_regs *regs,
unsigned long *args) unsigned long *args)
{ {
memcpy(args, &regs->bx, 6 * sizeof(args[0])); args[0] = regs->bx;
args[1] = regs->cx;
args[2] = regs->dx;
args[3] = regs->si;
args[4] = regs->di;
args[5] = regs->bp;
} }
static inline int syscall_get_arch(struct task_struct *task) static inline int syscall_get_arch(struct task_struct *task)
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define PCI_DEVICE_ID_AMD_19H_M70H_ROOT 0x14e8 #define PCI_DEVICE_ID_AMD_19H_M70H_ROOT 0x14e8
#define PCI_DEVICE_ID_AMD_1AH_M00H_ROOT 0x153a #define PCI_DEVICE_ID_AMD_1AH_M00H_ROOT 0x153a
#define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507 #define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507
#define PCI_DEVICE_ID_AMD_1AH_M60H_ROOT 0x1122
#define PCI_DEVICE_ID_AMD_MI200_ROOT 0x14bb #define PCI_DEVICE_ID_AMD_MI200_ROOT 0x14bb
#define PCI_DEVICE_ID_AMD_MI300_ROOT 0x14f8 #define PCI_DEVICE_ID_AMD_MI300_ROOT 0x14f8
...@@ -43,6 +44,8 @@ ...@@ -43,6 +44,8 @@
#define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4 #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4
#define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc
#define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4 0x12c4 #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4 0x12c4
#define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4 0x124c
#define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4 0x12bc
#define PCI_DEVICE_ID_AMD_MI200_DF_F4 0x14d4 #define PCI_DEVICE_ID_AMD_MI200_DF_F4 0x14d4
#define PCI_DEVICE_ID_AMD_MI300_DF_F4 0x152c #define PCI_DEVICE_ID_AMD_MI300_DF_F4 0x152c
...@@ -63,6 +66,7 @@ static const struct pci_device_id amd_root_ids[] = { ...@@ -63,6 +66,7 @@ static const struct pci_device_id amd_root_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_ROOT) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_ROOT) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_ROOT) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_ROOT) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_ROOT) },
{} {}
...@@ -95,6 +99,7 @@ static const struct pci_device_id amd_nb_misc_ids[] = { ...@@ -95,6 +99,7 @@ static const struct pci_device_id amd_nb_misc_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F3) },
...@@ -122,6 +127,8 @@ static const struct pci_device_id amd_nb_link_ids[] = { ...@@ -122,6 +127,8 @@ static const struct pci_device_id amd_nb_link_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F4) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F4) },
{} {}
......
...@@ -548,6 +548,7 @@ static const struct pci_device_id k10temp_id_table[] = { ...@@ -548,6 +548,7 @@ static const struct pci_device_id k10temp_id_table[] = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F3) },
{ PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) }, { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
{} {}
}; };
......
...@@ -580,6 +580,7 @@ ...@@ -580,6 +580,7 @@
#define PCI_DEVICE_ID_AMD_19H_M78H_DF_F3 0x12fb #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F3 0x12fb
#define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3 0x12c3 #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3 0x12c3
#define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3 0x16fb #define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3 0x16fb
#define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F3 0x124b
#define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3 0x12bb #define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3 0x12bb
#define PCI_DEVICE_ID_AMD_MI200_DF_F3 0x14d3 #define PCI_DEVICE_ID_AMD_MI200_DF_F3 0x14d3
#define PCI_DEVICE_ID_AMD_MI300_DF_F3 0x152b #define PCI_DEVICE_ID_AMD_MI300_DF_F3 0x152b
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <getopt.h> #include <getopt.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define min(a, b) (((a) < (b)) ? (a) : (b))
typedef unsigned int u32; typedef unsigned int u32;
typedef unsigned long long u64; typedef unsigned long long u64;
...@@ -76,7 +77,6 @@ struct cpuid_range { ...@@ -76,7 +77,6 @@ struct cpuid_range {
*/ */
struct cpuid_range *leafs_basic, *leafs_ext; struct cpuid_range *leafs_basic, *leafs_ext;
static int num_leafs;
static bool is_amd; static bool is_amd;
static bool show_details; static bool show_details;
static bool show_raw; static bool show_raw;
...@@ -98,27 +98,17 @@ static inline void cpuid(u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) ...@@ -98,27 +98,17 @@ static inline void cpuid(u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
static inline bool has_subleafs(u32 f) static inline bool has_subleafs(u32 f)
{ {
if (f == 0x7 || f == 0xd) u32 with_subleaves[] = {
0x4, 0x7, 0xb, 0xd, 0xf, 0x10, 0x12,
0x14, 0x17, 0x18, 0x1b, 0x1d, 0x1f, 0x23,
0x8000001d, 0x80000020, 0x80000026,
};
for (unsigned i = 0; i < ARRAY_SIZE(with_subleaves); i++)
if (f == with_subleaves[i])
return true; return true;
if (is_amd) {
if (f == 0x8000001d)
return true;
return false;
}
switch (f) {
case 0x4:
case 0xb:
case 0xf:
case 0x10:
case 0x14:
case 0x18:
case 0x1f:
return true;
default:
return false; return false;
}
} }
static void leaf_print_raw(struct subleaf *leaf) static void leaf_print_raw(struct subleaf *leaf)
...@@ -204,15 +194,12 @@ static void raw_dump_range(struct cpuid_range *range) ...@@ -204,15 +194,12 @@ static void raw_dump_range(struct cpuid_range *range)
} }
} }
#define MAX_SUBLEAF_NUM 32 #define MAX_SUBLEAF_NUM 64
struct cpuid_range *setup_cpuid_range(u32 input_eax) struct cpuid_range *setup_cpuid_range(u32 input_eax)
{ {
u32 max_func, idx_func; u32 max_func, idx_func, subleaf, max_subleaf;
int subleaf; u32 eax, ebx, ecx, edx, f = input_eax;
struct cpuid_range *range; struct cpuid_range *range;
u32 eax, ebx, ecx, edx;
u32 f = input_eax;
int max_subleaf;
bool allzero; bool allzero;
eax = input_eax; eax = input_eax;
...@@ -246,7 +233,6 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax) ...@@ -246,7 +233,6 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
allzero = cpuid_store(range, f, subleaf, eax, ebx, ecx, edx); allzero = cpuid_store(range, f, subleaf, eax, ebx, ecx, edx);
if (allzero) if (allzero)
continue; continue;
num_leafs++;
if (!has_subleafs(f)) if (!has_subleafs(f))
continue; continue;
...@@ -257,11 +243,18 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax) ...@@ -257,11 +243,18 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
* Some can provide the exact number of subleafs, * Some can provide the exact number of subleafs,
* others have to be tried (0xf) * others have to be tried (0xf)
*/ */
if (f == 0x7 || f == 0x14 || f == 0x17 || f == 0x18) if (f == 0x7 || f == 0x14 || f == 0x17 || f == 0x18 || f == 0x1d)
max_subleaf = (eax & 0xff) + 1; max_subleaf = min((eax & 0xff) + 1, max_subleaf);
if (f == 0xb) if (f == 0xb)
max_subleaf = 2; max_subleaf = 2;
if (f == 0x1f)
max_subleaf = 6;
if (f == 0x23)
max_subleaf = 4;
if (f == 0x80000020)
max_subleaf = 4;
if (f == 0x80000026)
max_subleaf = 5;
for (subleaf = 1; subleaf < max_subleaf; subleaf++) { for (subleaf = 1; subleaf < max_subleaf; subleaf++) {
eax = f; eax = f;
...@@ -272,7 +265,6 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax) ...@@ -272,7 +265,6 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
eax, ebx, ecx, edx); eax, ebx, ecx, edx);
if (allzero) if (allzero)
continue; continue;
num_leafs++;
} }
} }
...@@ -313,6 +305,8 @@ static int parse_line(char *line) ...@@ -313,6 +305,8 @@ static int parse_line(char *line)
struct bits_desc *bdesc; struct bits_desc *bdesc;
int reg_index; int reg_index;
char *start, *end; char *start, *end;
u32 subleaf_start, subleaf_end;
unsigned bit_start, bit_end;
/* Skip comments and NULL line */ /* Skip comments and NULL line */
if (line[0] == '#' || line[0] == '\n') if (line[0] == '#' || line[0] == '\n')
...@@ -351,13 +345,25 @@ static int parse_line(char *line) ...@@ -351,13 +345,25 @@ static int parse_line(char *line)
return 0; return 0;
/* subleaf */ /* subleaf */
sub = strtoul(tokens[1], NULL, 0); buf = tokens[1];
if ((int)sub > func->nr) end = strtok(buf, ":");
return -1; start = strtok(NULL, ":");
subleaf_end = strtoul(end, NULL, 0);
leaf = &func->leafs[sub]; /* A subleaf range is given? */
buf = tokens[2]; if (start) {
subleaf_start = strtoul(start, NULL, 0);
subleaf_end = min(subleaf_end, (u32)(func->nr - 1));
if (subleaf_start > subleaf_end)
return 0;
} else {
subleaf_start = subleaf_end;
if (subleaf_start > (u32)(func->nr - 1))
return 0;
}
/* register */
buf = tokens[2];
if (strcasestr(buf, "EAX")) if (strcasestr(buf, "EAX"))
reg_index = R_EAX; reg_index = R_EAX;
else if (strcasestr(buf, "EBX")) else if (strcasestr(buf, "EBX"))
...@@ -369,23 +375,23 @@ static int parse_line(char *line) ...@@ -369,23 +375,23 @@ static int parse_line(char *line)
else else
goto err_exit; goto err_exit;
reg = &leaf->info[reg_index];
bdesc = &reg->descs[reg->nr++];
/* bit flag or bits field */ /* bit flag or bits field */
buf = tokens[3]; buf = tokens[3];
end = strtok(buf, ":"); end = strtok(buf, ":");
bdesc->end = strtoul(end, NULL, 0);
bdesc->start = bdesc->end;
/* start != NULL means it is bit fields */
start = strtok(NULL, ":"); start = strtok(NULL, ":");
if (start) bit_end = strtoul(end, NULL, 0);
bdesc->start = strtoul(start, NULL, 0); bit_start = (start) ? strtoul(start, NULL, 0) : bit_end;
strcpy(bdesc->simp, tokens[4]); for (sub = subleaf_start; sub <= subleaf_end; sub++) {
leaf = &func->leafs[sub];
reg = &leaf->info[reg_index];
bdesc = &reg->descs[reg->nr++];
bdesc->end = bit_end;
bdesc->start = bit_start;
strcpy(bdesc->simp, strtok(tokens[4], " \t"));
strcpy(bdesc->detail, tokens[5]); strcpy(bdesc->detail, tokens[5]);
}
return 0; return 0;
err_exit: err_exit:
...@@ -452,8 +458,9 @@ static void decode_bits(u32 value, struct reg_desc *rdesc, enum cpuid_reg reg) ...@@ -452,8 +458,9 @@ static void decode_bits(u32 value, struct reg_desc *rdesc, enum cpuid_reg reg)
if (start == end) { if (start == end) {
/* single bit flag */ /* single bit flag */
if (value & (1 << start)) if (value & (1 << start))
printf("\t%-20s %s%s\n", printf("\t%-20s %s%s%s\n",
bdesc->simp, bdesc->simp,
show_flags_only ? "" : "\t\t\t",
show_details ? "-" : "", show_details ? "-" : "",
show_details ? bdesc->detail : "" show_details ? bdesc->detail : ""
); );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment