Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 CPU features from Ingo Molnar: "Various CPU feature support related changes: in particular the /proc/cpuinfo model name sanitization change should be monitored, it has a chance to break stuff. (but really shouldn't and there are no regression reports)" * 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/cpu/amd: Give access to the number of nodes in a physical package x86/cpu: Trim model ID whitespace x86/cpu: Strip any /proc/cpuinfo model name field whitespace x86/cpu/amd: Set X86_FEATURE_EXTD_APICID for future processors x86/gart: Check for GART support before accessing GART registers
This commit is contained in:
commit
b3ba283d83
|
@ -98,11 +98,22 @@ static inline u16 amd_get_node_id(struct pci_dev *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline bool amd_gart_present(void)
|
||||
{
|
||||
/* GART present only on Fam15h, upto model 0fh */
|
||||
if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 ||
|
||||
(boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model < 0x10))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define amd_nb_num(x) 0
|
||||
#define amd_nb_has_feature(x) false
|
||||
#define node_to_amd_nb(x) NULL
|
||||
#define amd_gart_present(x) false
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -946,6 +946,7 @@ static inline int mpx_disable_management(struct task_struct *tsk)
|
|||
#endif /* CONFIG_X86_INTEL_MPX */
|
||||
|
||||
extern u16 amd_get_nb_id(int cpu);
|
||||
extern u32 amd_get_nodes_per_socket(void);
|
||||
|
||||
static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
|
||||
{
|
||||
|
|
|
@ -89,9 +89,7 @@ int amd_cache_northbridges(void)
|
|||
next_northbridge(link, amd_nb_link_ids);
|
||||
}
|
||||
|
||||
/* GART present only on Fam15h upto model 0fh */
|
||||
if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 ||
|
||||
(boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model < 0x10))
|
||||
if (amd_gart_present())
|
||||
amd_northbridges.flags |= AMD_NB_GART;
|
||||
|
||||
/*
|
||||
|
|
|
@ -262,6 +262,9 @@ void __init early_gart_iommu_check(void)
|
|||
u64 aper_base = 0, last_aper_base = 0;
|
||||
int aper_enabled = 0, last_aper_enabled = 0, last_valid = 0;
|
||||
|
||||
if (!amd_gart_present())
|
||||
return;
|
||||
|
||||
if (!early_pci_allowed())
|
||||
return;
|
||||
|
||||
|
@ -355,6 +358,9 @@ int __init gart_iommu_hole_init(void)
|
|||
int fix, slot, valid_agp = 0;
|
||||
int i, node;
|
||||
|
||||
if (!amd_gart_present())
|
||||
return -ENODEV;
|
||||
|
||||
if (gart_iommu_aperture_disabled || !fix_aperture ||
|
||||
!early_pci_allowed())
|
||||
return -ENODEV;
|
||||
|
@ -452,7 +458,7 @@ out:
|
|||
force_iommu ||
|
||||
valid_agp ||
|
||||
fallback_aper_force) {
|
||||
pr_info("Your BIOS doesn't leave a aperture memory hole\n");
|
||||
pr_info("Your BIOS doesn't leave an aperture memory hole\n");
|
||||
pr_info("Please enable the IOMMU option in the BIOS setup\n");
|
||||
pr_info("This costs you %dMB of RAM\n",
|
||||
32 << fallback_aper_order);
|
||||
|
|
|
@ -19,6 +19,13 @@
|
|||
|
||||
#include "cpu.h"
|
||||
|
||||
/*
|
||||
* nodes_per_socket: Stores the number of nodes per socket.
|
||||
* Refer to Fam15h Models 00-0fh BKDG - CPUID Fn8000_001E_ECX
|
||||
* Node Identifiers[10:8]
|
||||
*/
|
||||
static u32 nodes_per_socket = 1;
|
||||
|
||||
static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
|
||||
{
|
||||
u32 gprs[8] = { 0 };
|
||||
|
@ -291,7 +298,7 @@ static int nearby_node(int apicid)
|
|||
#ifdef CONFIG_X86_HT
|
||||
static void amd_get_topology(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 nodes, cores_per_cu = 1;
|
||||
u32 cores_per_cu = 1;
|
||||
u8 node_id;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
|
@ -300,7 +307,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
|
|||
u32 eax, ebx, ecx, edx;
|
||||
|
||||
cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
|
||||
nodes = ((ecx >> 8) & 7) + 1;
|
||||
nodes_per_socket = ((ecx >> 8) & 7) + 1;
|
||||
node_id = ecx & 7;
|
||||
|
||||
/* get compute unit information */
|
||||
|
@ -311,18 +318,18 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
|
|||
u64 value;
|
||||
|
||||
rdmsrl(MSR_FAM10H_NODE_ID, value);
|
||||
nodes = ((value >> 3) & 7) + 1;
|
||||
nodes_per_socket = ((value >> 3) & 7) + 1;
|
||||
node_id = value & 7;
|
||||
} else
|
||||
return;
|
||||
|
||||
/* fixup multi-node processor information */
|
||||
if (nodes > 1) {
|
||||
if (nodes_per_socket > 1) {
|
||||
u32 cores_per_node;
|
||||
u32 cus_per_node;
|
||||
|
||||
set_cpu_cap(c, X86_FEATURE_AMD_DCM);
|
||||
cores_per_node = c->x86_max_cores / nodes;
|
||||
cores_per_node = c->x86_max_cores / nodes_per_socket;
|
||||
cus_per_node = cores_per_node / cores_per_cu;
|
||||
|
||||
/* store NodeID, use llc_shared_map to store sibling info */
|
||||
|
@ -366,6 +373,12 @@ u16 amd_get_nb_id(int cpu)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(amd_get_nb_id);
|
||||
|
||||
u32 amd_get_nodes_per_socket(void)
|
||||
{
|
||||
return nodes_per_socket;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(amd_get_nodes_per_socket);
|
||||
|
||||
static void srat_detect_node(struct cpuinfo_x86 *c)
|
||||
{
|
||||
#ifdef CONFIG_NUMA
|
||||
|
@ -520,8 +533,16 @@ static void early_init_amd(struct cpuinfo_x86 *c)
|
|||
set_cpu_cap(c, X86_FEATURE_K6_MTRR);
|
||||
#endif
|
||||
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
|
||||
/* check CPU config space for extended APIC ID */
|
||||
if (cpu_has_apic && c->x86 >= 0xf) {
|
||||
/*
|
||||
* ApicID can always be treated as an 8-bit value for AMD APIC versions
|
||||
* >= 0x10, but even old K8s came out of reset with version 0x10. So, we
|
||||
* can safely set X86_FEATURE_EXTD_APICID unconditionally for families
|
||||
* after 16h.
|
||||
*/
|
||||
if (cpu_has_apic && c->x86 > 0x16) {
|
||||
set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
|
||||
} else if (cpu_has_apic && c->x86 >= 0xf) {
|
||||
/* check CPU config space for extended APIC ID */
|
||||
unsigned int val;
|
||||
val = read_pci_config(0, 24, 0, 0x68);
|
||||
if ((val & ((1 << 17) | (1 << 18))) == ((1 << 17) | (1 << 18)))
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -419,7 +420,7 @@ static const struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {};
|
|||
static void get_model_name(struct cpuinfo_x86 *c)
|
||||
{
|
||||
unsigned int *v;
|
||||
char *p, *q;
|
||||
char *p, *q, *s;
|
||||
|
||||
if (c->extended_cpuid_level < 0x80000004)
|
||||
return;
|
||||
|
@ -430,19 +431,21 @@ static void get_model_name(struct cpuinfo_x86 *c)
|
|||
cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
|
||||
c->x86_model_id[48] = 0;
|
||||
|
||||
/*
|
||||
* Intel chips right-justify this string for some dumb reason;
|
||||
* undo that brain damage:
|
||||
*/
|
||||
p = q = &c->x86_model_id[0];
|
||||
/* Trim whitespace */
|
||||
p = q = s = &c->x86_model_id[0];
|
||||
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
if (p != q) {
|
||||
while (*p)
|
||||
*q++ = *p++;
|
||||
while (q <= &c->x86_model_id[48])
|
||||
*q++ = '\0'; /* Zero-pad the rest */
|
||||
|
||||
while (*p) {
|
||||
/* Note the last non-whitespace index */
|
||||
if (!isspace(*p))
|
||||
s = q;
|
||||
|
||||
*q++ = *p++;
|
||||
}
|
||||
|
||||
*(s + 1) = '\0';
|
||||
}
|
||||
|
||||
void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
|
||||
|
@ -1122,7 +1125,7 @@ void print_cpu_info(struct cpuinfo_x86 *c)
|
|||
printk(KERN_CONT "%s ", vendor);
|
||||
|
||||
if (c->x86_model_id[0])
|
||||
printk(KERN_CONT "%s", strim(c->x86_model_id));
|
||||
printk(KERN_CONT "%s", c->x86_model_id);
|
||||
else
|
||||
printk(KERN_CONT "%d86", c->x86);
|
||||
|
||||
|
|
Loading…
Reference in New Issue