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
F: Documentation/arch/x86/
F: Documentation/devicetree/bindings/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
M: Andy Lutomirski <luto@kernel.org>
......
......@@ -82,7 +82,12 @@ static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
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)
......
......@@ -26,6 +26,7 @@
#define PCI_DEVICE_ID_AMD_19H_M70H_ROOT 0x14e8
#define PCI_DEVICE_ID_AMD_1AH_M00H_ROOT 0x153a
#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_MI300_ROOT 0x14f8
......@@ -43,6 +44,8 @@
#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_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_MI300_DF_F4 0x152c
......@@ -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_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_M60H_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) },
{}
......@@ -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_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_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_MI200_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[] = {
{ 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_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_MI300_DF_F4) },
{}
......
......@@ -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_1AH_M00H_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) },
{}
};
......
......@@ -580,6 +580,7 @@
#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_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_MI200_DF_F3 0x14d3
#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.
......@@ -7,7 +7,8 @@
#include <string.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 long long u64;
......@@ -76,7 +77,6 @@ struct cpuid_range {
*/
struct cpuid_range *leafs_basic, *leafs_ext;
static int num_leafs;
static bool is_amd;
static bool show_details;
static bool show_raw;
......@@ -98,27 +98,17 @@ static inline void cpuid(u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
static inline bool has_subleafs(u32 f)
{
if (f == 0x7 || f == 0xd)
return true;
if (is_amd) {
if (f == 0x8000001d)
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 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)
......@@ -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)
{
u32 max_func, idx_func;
int subleaf;
u32 max_func, idx_func, subleaf, max_subleaf;
u32 eax, ebx, ecx, edx, f = input_eax;
struct cpuid_range *range;
u32 eax, ebx, ecx, edx;
u32 f = input_eax;
int max_subleaf;
bool allzero;
eax = 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);
if (allzero)
continue;
num_leafs++;
if (!has_subleafs(f))
continue;
......@@ -257,11 +243,18 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
* Some can provide the exact number of subleafs,
* others have to be tried (0xf)
*/
if (f == 0x7 || f == 0x14 || f == 0x17 || f == 0x18)
max_subleaf = (eax & 0xff) + 1;
if (f == 0x7 || f == 0x14 || f == 0x17 || f == 0x18 || f == 0x1d)
max_subleaf = min((eax & 0xff) + 1, max_subleaf);
if (f == 0xb)
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++) {
eax = f;
......@@ -272,7 +265,6 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
eax, ebx, ecx, edx);
if (allzero)
continue;
num_leafs++;
}
}
......@@ -313,6 +305,8 @@ static int parse_line(char *line)
struct bits_desc *bdesc;
int reg_index;
char *start, *end;
u32 subleaf_start, subleaf_end;
unsigned bit_start, bit_end;
/* Skip comments and NULL line */
if (line[0] == '#' || line[0] == '\n')
......@@ -351,13 +345,25 @@ static int parse_line(char *line)
return 0;
/* subleaf */
sub = strtoul(tokens[1], NULL, 0);
if ((int)sub > func->nr)
return -1;
buf = tokens[1];
end = strtok(buf, ":");
start = strtok(NULL, ":");
subleaf_end = strtoul(end, NULL, 0);
/* A subleaf range is given? */
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;
}
leaf = &func->leafs[sub];
/* register */
buf = tokens[2];
if (strcasestr(buf, "EAX"))
reg_index = R_EAX;
else if (strcasestr(buf, "EBX"))
......@@ -369,23 +375,23 @@ static int parse_line(char *line)
else
goto err_exit;
reg = &leaf->info[reg_index];
bdesc = &reg->descs[reg->nr++];
/* bit flag or bits field */
buf = tokens[3];
end = strtok(buf, ":");
bdesc->end = strtoul(end, NULL, 0);
bdesc->start = bdesc->end;
/* start != NULL means it is bit fields */
start = strtok(NULL, ":");
if (start)
bdesc->start = strtoul(start, NULL, 0);
strcpy(bdesc->simp, tokens[4]);
strcpy(bdesc->detail, tokens[5]);
bit_end = strtoul(end, NULL, 0);
bit_start = (start) ? strtoul(start, NULL, 0) : bit_end;
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]);
}
return 0;
err_exit:
......@@ -452,8 +458,9 @@ static void decode_bits(u32 value, struct reg_desc *rdesc, enum cpuid_reg reg)
if (start == end) {
/* single bit flag */
if (value & (1 << start))
printf("\t%-20s %s%s\n",
printf("\t%-20s %s%s%s\n",
bdesc->simp,
show_flags_only ? "" : "\t\t\t",
show_details ? "-" : "",
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