]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge remote branch 'linus/master' into x86/cpu
authorH. Peter Anvin <hpa@linux.intel.com>
Wed, 28 Jul 2010 20:11:28 +0000 (13:11 -0700)
committerH. Peter Anvin <hpa@linux.intel.com>
Wed, 28 Jul 2010 20:11:28 +0000 (13:11 -0700)
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/required-features.h
arch/x86/kernel/cpu/Makefile
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/scattered.c [new file with mode: 0644]
arch/x86/kernel/cpu/topology.c [moved from arch/x86/kernel/cpu/addon_cpuid_features.c with 66% similarity]
arch/x86/kernel/xsave.c

index 468145914389942273f2d68c5b9d57b48bf84a8e..4be50ddd4d793e169d3db0712f137bd1c0a34b19 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <asm/required-features.h>
 
-#define NCAPINTS             /* N 32-bit words worth of info */
+#define NCAPINTS       10      /* N 32-bit words worth of info */
 
 /*
  * Note: If the comment begins with a quoted string, that string is used
 #define X86_FEATURE_XSAVE      (4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
 #define X86_FEATURE_OSXSAVE    (4*32+27) /* "" XSAVE enabled in the OS */
 #define X86_FEATURE_AVX                (4*32+28) /* Advanced Vector Extensions */
+#define X86_FEATURE_F16C       (4*32+29) /* 16-bit fp conversions */
+#define X86_FEATURE_RDRND      (4*32+30) /* The RDRAND instruction */
 #define X86_FEATURE_HYPERVISOR (4*32+31) /* Running on a hypervisor */
 
 /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
 
 /*
  * Auxiliary flags: Linux defined - For features scattered in various
- * CPUID levels like 0x6, 0xA etc
+ * CPUID levels like 0x6, 0xA etc, word 7
  */
 #define X86_FEATURE_IDA                (7*32+ 0) /* Intel Dynamic Acceleration */
 #define X86_FEATURE_ARAT       (7*32+ 1) /* Always Running APIC Timer */
 #define X86_FEATURE_CPB                (7*32+ 2) /* AMD Core Performance Boost */
+#define X86_FEATURE_EPB                (7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
+#define X86_FEATURE_XSAVEOPT   (7*32+ 4) /* Optimized Xsave */
 
-/* Virtualization flags: Linux defined */
+/* Virtualization flags: Linux defined, word 8 */
 #define X86_FEATURE_TPR_SHADOW  (8*32+ 0) /* Intel TPR Shadow */
 #define X86_FEATURE_VNMI        (8*32+ 1) /* Intel Virtual NMI */
 #define X86_FEATURE_FLEXPRIORITY (8*32+ 2) /* Intel FlexPriority */
 #define X86_FEATURE_EPT         (8*32+ 3) /* Intel Extended Page Table */
 #define X86_FEATURE_VPID        (8*32+ 4) /* Intel Virtual Processor ID */
-#define X86_FEATURE_NPT                (8*32+5)  /* AMD Nested Page Table support */
-#define X86_FEATURE_LBRV       (8*32+6)  /* AMD LBR Virtualization support */
-#define X86_FEATURE_SVML       (8*32+7)  /* "svm_lock" AMD SVM locking MSR */
-#define X86_FEATURE_NRIPS      (8*32+8)  /* "nrip_save" AMD SVM next_rip save */
+#define X86_FEATURE_NPT                (8*32+ 5) /* AMD Nested Page Table support */
+#define X86_FEATURE_LBRV       (8*32+ 6) /* AMD LBR Virtualization support */
+#define X86_FEATURE_SVML       (8*32+ 7) /* "svm_lock" AMD SVM locking MSR */
+#define X86_FEATURE_NRIPS      (8*32+ 8) /* "nrip_save" AMD SVM next_rip save */
+
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
+#define X86_FEATURE_FSGSBASE   (9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 
@@ -194,7 +201,9 @@ extern const char * const x86_power_flags[32];
           (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||     \
           (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||     \
           (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||     \
-          (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) )      \
+          (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ||     \
+          (((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8)) ||     \
+          (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) )      \
          ? 1 :                                                         \
         test_cpu_cap(c, bit))
 
index 8c7ae4318629445f16b588e9535b0dc2a105836c..7cc4a026331cbaa532e25a420f8f2749f161f87a 100644 (file)
 
 #define MSR_IA32_TEMPERATURE_TARGET    0x000001a2
 
+#define MSR_IA32_ENERGY_PERF_BIAS      0x000001b0
+
 /* MISC_ENABLE bits: architectural */
 #define MSR_IA32_MISC_ENABLE_FAST_STRING       (1ULL << 0)
 #define MSR_IA32_MISC_ENABLE_TCC               (1ULL << 1)
index 64cf2d24fad1c2605c16b528cc10e8e37c9bc77c..6c7fc25f2c34a0eab822c2d6ab17c3b1cacbf0a0 100644 (file)
@@ -84,5 +84,7 @@
 #define REQUIRED_MASK5 0
 #define REQUIRED_MASK6 0
 #define REQUIRED_MASK7 0
+#define REQUIRED_MASK8 0
+#define REQUIRED_MASK9 0
 
 #endif /* _ASM_X86_REQUIRED_FEATURES_H */
index 3a785da34b6f981dd678f217c5f75f728a30d8ae..5e3a3512ba0511fc991e7721855dffdbecf68b14 100644 (file)
@@ -12,7 +12,7 @@ endif
 nostackp := $(call cc-option, -fno-stack-protector)
 CFLAGS_common.o                := $(nostackp)
 
-obj-y                  := intel_cacheinfo.o addon_cpuid_features.o
+obj-y                  := intel_cacheinfo.o scattered.o topology.o
 obj-y                  += proc.o capflags.o powerflags.o common.o
 obj-y                  += vmware.o hypervisor.o sched.o mshyperv.o
 
index e485825130d2c8ee9b5d278717deca21ae2116f4..12b9cff047c1c0085f0ac622dd3df5419ace2b36 100644 (file)
@@ -466,7 +466,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                }
 
        }
-       if (c->x86 == 0x10 || c->x86 == 0x11)
+       if (c->x86 >= 0x10)
                set_cpu_cap(c, X86_FEATURE_REP_GOOD);
 
        /* get apicid instead of initial apic id from cpuid */
@@ -529,7 +529,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                        num_cache_leaves = 3;
        }
 
-       if (c->x86 >= 0xf && c->x86 <= 0x11)
+       if (c->x86 >= 0xf)
                set_cpu_cap(c, X86_FEATURE_K8);
 
        if (cpu_has_xmm2) {
@@ -546,7 +546,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                fam10h_check_enable_mmcfg();
        }
 
-       if (c == &boot_cpu_data && c->x86 >= 0xf && c->x86 <= 0x11) {
+       if (c == &boot_cpu_data && c->x86 >= 0xf) {
                unsigned long long tseg;
 
                /*
index 68e4a6f2211e2e8ea52015e5c4a8861f4f5269d9..c7358303d8cdb44e8fd6ae279f1477f885168751 100644 (file)
@@ -551,6 +551,16 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
                c->x86_capability[4] = excap;
        }
 
+       /* Additional Intel-defined flags: level 0x00000007 */
+       if (c->cpuid_level >= 0x00000007) {
+               u32 eax, ebx, ecx, edx;
+
+               cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx);
+
+               if (eax > 0)
+                       c->x86_capability[9] = ebx;
+       }
+
        /* AMD-defined flags: level 0x80000001 */
        xlvl = cpuid_eax(0x80000000);
        c->extended_cpuid_level = xlvl;
index 33eae2062cf55b06c864ad8511062440f37f10fe..898c2f4eab88b28cb74719b943cad01ec06efa29 100644 (file)
@@ -347,8 +347,8 @@ static struct amd_l3_cache * __cpuinit amd_init_l3_cache(int node)
        return l3;
 }
 
-static void __cpuinit
-amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
+static void __cpuinit amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf,
+                                          int index)
 {
        int node;
 
@@ -396,20 +396,39 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
        this_leaf->l3 = l3_caches[node];
 }
 
+/*
+ * check whether a slot used for disabling an L3 index is occupied.
+ * @l3: L3 cache descriptor
+ * @slot: slot number (0..1)
+ *
+ * @returns: the disabled index if used or negative value if slot free.
+ */
+int amd_get_l3_disable_slot(struct amd_l3_cache *l3, unsigned slot)
+{
+       unsigned int reg = 0;
+
+       pci_read_config_dword(l3->dev, 0x1BC + slot * 4, &reg);
+
+       /* check whether this slot is activated already */
+       if (reg & (3UL << 30))
+               return reg & 0xfff;
+
+       return -1;
+}
+
 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
                                  unsigned int slot)
 {
-       struct pci_dev *dev = this_leaf->l3->dev;
-       unsigned int reg = 0;
+       int index;
 
        if (!this_leaf->l3 || !this_leaf->l3->can_disable)
                return -EINVAL;
 
-       if (!dev)
-               return -EINVAL;
+       index = amd_get_l3_disable_slot(this_leaf->l3, slot);
+       if (index >= 0)
+               return sprintf(buf, "%d\n", index);
 
-       pci_read_config_dword(dev, 0x1BC + slot * 4, &reg);
-       return sprintf(buf, "0x%08x\n", reg);
+       return sprintf(buf, "FREE\n");
 }
 
 #define SHOW_CACHE_DISABLE(slot)                                       \
@@ -451,37 +470,74 @@ static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu,
        }
 }
 
-
-static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
-                                  const char *buf, size_t count,
-                                  unsigned int slot)
+/*
+ * disable a L3 cache index by using a disable-slot
+ *
+ * @l3:    L3 cache descriptor
+ * @cpu:   A CPU on the node containing the L3 cache
+ * @slot:  slot number (0..1)
+ * @index: index to disable
+ *
+ * @return: 0 on success, error status on failure
+ */
+int amd_set_l3_disable_slot(struct amd_l3_cache *l3, int cpu, unsigned slot,
+                           unsigned long index)
 {
-       struct pci_dev *dev = this_leaf->l3->dev;
-       int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
-       unsigned long val = 0;
+       int ret = 0;
 
 #define SUBCACHE_MASK  (3UL << 20)
 #define SUBCACHE_INDEX 0xfff
 
-       if (!this_leaf->l3 || !this_leaf->l3->can_disable)
+       /*
+        * check whether this slot is already used or
+        * the index is already disabled
+        */
+       ret = amd_get_l3_disable_slot(l3, slot);
+       if (ret >= 0)
                return -EINVAL;
 
+       /*
+        * check whether the other slot has disabled the
+        * same index already
+        */
+       if (index == amd_get_l3_disable_slot(l3, !slot))
+               return -EINVAL;
+
+       /* do not allow writes outside of allowed bits */
+       if ((index & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
+           ((index & SUBCACHE_INDEX) > l3->indices))
+               return -EINVAL;
+
+       amd_l3_disable_index(l3, cpu, slot, index);
+
+       return 0;
+}
+
+static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
+                                 const char *buf, size_t count,
+                                 unsigned int slot)
+{
+       unsigned long val = 0;
+       int cpu, err = 0;
+
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       if (!dev)
+       if (!this_leaf->l3 || !this_leaf->l3->can_disable)
                return -EINVAL;
 
-       if (strict_strtoul(buf, 10, &val) < 0)
-               return -EINVAL;
+       cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
 
-       /* do not allow writes outside of allowed bits */
-       if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
-           ((val & SUBCACHE_INDEX) > this_leaf->l3->indices))
+       if (strict_strtoul(buf, 10, &val) < 0)
                return -EINVAL;
 
-       amd_l3_disable_index(this_leaf->l3, cpu, slot, val);
-
+       err = amd_set_l3_disable_slot(this_leaf->l3, cpu, slot, val);
+       if (err) {
+               if (err == -EEXIST)
+                       printk(KERN_WARNING "L3 disable slot %d in use!\n",
+                                           slot);
+               return err;
+       }
        return count;
 }
 
@@ -502,7 +558,7 @@ static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
 
 #else  /* CONFIG_CPU_SUP_AMD */
 static void __cpuinit
-amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
+amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf, int index)
 {
 };
 #endif /* CONFIG_CPU_SUP_AMD */
@@ -518,7 +574,7 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
 
        if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
                amd_cpuid4(index, &eax, &ebx, &ecx);
-               amd_check_l3_disable(index, this_leaf);
+               amd_check_l3_disable(this_leaf, index);
        } else {
                cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
        }
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
new file mode 100644 (file)
index 0000000..9815364
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *     Routines to indentify additional cpu features that are scattered in
+ *     cpuid space.
+ */
+#include <linux/cpu.h>
+
+#include <asm/pat.h>
+#include <asm/processor.h>
+
+#include <asm/apic.h>
+
+struct cpuid_bit {
+       u16 feature;
+       u8 reg;
+       u8 bit;
+       u32 level;
+       u32 sub_leaf;
+};
+
+enum cpuid_regs {
+       CR_EAX = 0,
+       CR_ECX,
+       CR_EDX,
+       CR_EBX
+};
+
+void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
+{
+       u32 max_level;
+       u32 regs[4];
+       const struct cpuid_bit *cb;
+
+       static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
+               { X86_FEATURE_IDA,              CR_EAX, 1, 0x00000006, 0 },
+               { X86_FEATURE_ARAT,             CR_EAX, 2, 0x00000006, 0 },
+               { X86_FEATURE_APERFMPERF,       CR_ECX, 0, 0x00000006, 0 },
+               { X86_FEATURE_EPB,              CR_ECX, 3, 0x00000006, 0 },
+               { X86_FEATURE_XSAVEOPT,         CR_EAX, 0, 0x0000000d, 1 },
+               { X86_FEATURE_CPB,              CR_EDX, 9, 0x80000007, 0 },
+               { X86_FEATURE_NPT,              CR_EDX, 0, 0x8000000a, 0 },
+               { X86_FEATURE_LBRV,             CR_EDX, 1, 0x8000000a, 0 },
+               { X86_FEATURE_SVML,             CR_EDX, 2, 0x8000000a, 0 },
+               { X86_FEATURE_NRIPS,            CR_EDX, 3, 0x8000000a, 0 },
+               { 0, 0, 0, 0, 0 }
+       };
+
+       for (cb = cpuid_bits; cb->feature; cb++) {
+
+               /* Verify that the level is valid */
+               max_level = cpuid_eax(cb->level & 0xffff0000);
+               if (max_level < cb->level ||
+                   max_level > (cb->level | 0xffff))
+                       continue;
+
+               cpuid_count(cb->level, cb->sub_leaf, &regs[CR_EAX],
+                           &regs[CR_EBX], &regs[CR_ECX], &regs[CR_EDX]);
+
+               if (regs[cb->reg] & (1 << cb->bit))
+                       set_cpu_cap(c, cb->feature);
+       }
+}
similarity index 66%
rename from arch/x86/kernel/cpu/addon_cpuid_features.c
rename to arch/x86/kernel/cpu/topology.c
index 10fa5684a6628e5e095a698d8bc8065748bc4534..4397e987a1cfbc062dbf087e7d6a5b6577abeafb 100644 (file)
@@ -1,62 +1,14 @@
 /*
- *     Routines to indentify additional cpu features that are scattered in
- *     cpuid space.
+ * Check for extended topology enumeration cpuid leaf 0xb and if it
+ * exists, use it for populating initial_apicid and cpu topology
+ * detection.
  */
-#include <linux/cpu.h>
 
+#include <linux/cpu.h>
+#include <asm/apic.h>
 #include <asm/pat.h>
 #include <asm/processor.h>
 
-#include <asm/apic.h>
-
-struct cpuid_bit {
-       u16 feature;
-       u8 reg;
-       u8 bit;
-       u32 level;
-};
-
-enum cpuid_regs {
-       CR_EAX = 0,
-       CR_ECX,
-       CR_EDX,
-       CR_EBX
-};
-
-void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
-{
-       u32 max_level;
-       u32 regs[4];
-       const struct cpuid_bit *cb;
-
-       static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
-               { X86_FEATURE_IDA,              CR_EAX, 1, 0x00000006 },
-               { X86_FEATURE_ARAT,             CR_EAX, 2, 0x00000006 },
-               { X86_FEATURE_APERFMPERF,       CR_ECX, 0, 0x00000006 },
-               { X86_FEATURE_CPB,              CR_EDX, 9, 0x80000007 },
-               { X86_FEATURE_NPT,              CR_EDX, 0, 0x8000000a },
-               { X86_FEATURE_LBRV,             CR_EDX, 1, 0x8000000a },
-               { X86_FEATURE_SVML,             CR_EDX, 2, 0x8000000a },
-               { X86_FEATURE_NRIPS,            CR_EDX, 3, 0x8000000a },
-               { 0, 0, 0, 0 }
-       };
-
-       for (cb = cpuid_bits; cb->feature; cb++) {
-
-               /* Verify that the level is valid */
-               max_level = cpuid_eax(cb->level & 0xffff0000);
-               if (max_level < cb->level ||
-                   max_level > (cb->level | 0xffff))
-                       continue;
-
-               cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
-                       &regs[CR_ECX], &regs[CR_EDX]);
-
-               if (regs[cb->reg] & (1 << cb->bit))
-                       set_cpu_cap(c, cb->feature);
-       }
-}
-
 /* leaf 0xb SMT level */
 #define SMT_LEVEL      0
 
index 37e68fc5e24a4daa33bcb6c730162a0969c91430..980149867a1910db07040aed05537ecd66e3752e 100644 (file)
@@ -36,15 +36,14 @@ int check_for_xstate(struct i387_fxsave_struct __user *buf,
 
        err = __copy_from_user(fx_sw_user, &buf->sw_reserved[0],
                               sizeof(struct _fpx_sw_bytes));
-
        if (err)
-               return err;
+               return -EFAULT;
 
        /*
         * First Magic check failed.
         */
        if (fx_sw_user->magic1 != FP_XSTATE_MAGIC1)
-               return -1;
+               return -EINVAL;
 
        /*
         * Check for error scenarios.
@@ -52,19 +51,21 @@ int check_for_xstate(struct i387_fxsave_struct __user *buf,
        if (fx_sw_user->xstate_size < min_xstate_size ||
            fx_sw_user->xstate_size > xstate_size ||
            fx_sw_user->xstate_size > fx_sw_user->extended_size)
-               return -1;
+               return -EINVAL;
 
        err = __get_user(magic2, (__u32 *) (((void *)fpstate) +
                                            fx_sw_user->extended_size -
                                            FP_XSTATE_MAGIC2_SIZE));
+       if (err)
+               return err;
        /*
         * Check for the presence of second magic word at the end of memory
         * layout. This detects the case where the user just copied the legacy
         * fpstate layout with out copying the extended state information
         * in the memory layout.
         */
-       if (err || magic2 != FP_XSTATE_MAGIC2)
-               return -1;
+       if (magic2 != FP_XSTATE_MAGIC2)
+               return -EFAULT;
 
        return 0;
 }