lkml.org 
[lkml]   [2015]   [Nov]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH 1/3] x86/cpu: Unify CPU family, model, stepping calculation
    Date
    From: Borislav Petkov <bp@suse.de>

    Add generic functions which calc family, model and stepping from the
    CPUID_1.EAX leaf and stick them into the library we have.

    No functionality change.

    Signed-off-by: Borislav Petkov <bp@suse.de>
    ---
    arch/x86/include/asm/cpu.h | 3 +++
    arch/x86/include/asm/microcode.h | 31 +++----------------------------
    arch/x86/kernel/cpu/common.c | 11 +++--------
    arch/x86/kernel/cpu/microcode/core.c | 6 +++---
    arch/x86/kernel/cpu/microcode/intel.c | 16 ++++++----------
    arch/x86/lib/Makefile | 2 +-
    arch/x86/lib/cpu.c | 35 +++++++++++++++++++++++++++++++++++
    7 files changed, 54 insertions(+), 50 deletions(-)
    create mode 100644 arch/x86/lib/cpu.c

    diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
    index bf2caa1dedc5..678637ad7476 100644
    --- a/arch/x86/include/asm/cpu.h
    +++ b/arch/x86/include/asm/cpu.h
    @@ -36,4 +36,7 @@ extern int _debug_hotplug_cpu(int cpu, int action);

    int mwait_usable(const struct cpuinfo_x86 *);

    +unsigned int x86_family(unsigned int sig);
    +unsigned int x86_model(unsigned int sig);
    +unsigned int x86_stepping(unsigned int sig);
    #endif /* _ASM_X86_CPU_H */
    diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
    index 34e62b1dcfce..0419cc4ab4fd 100644
    --- a/arch/x86/include/asm/microcode.h
    +++ b/arch/x86/include/asm/microcode.h
    @@ -1,6 +1,7 @@
    #ifndef _ASM_X86_MICROCODE_H
    #define _ASM_X86_MICROCODE_H

    +#include <asm/cpu.h>
    #include <linux/earlycpio.h>

    #define native_rdmsr(msr, val1, val2) \
    @@ -118,40 +119,14 @@ static inline int x86_vendor(void)
    return X86_VENDOR_UNKNOWN;
    }

    -static inline unsigned int __x86_family(unsigned int sig)
    -{
    - unsigned int x86;
    -
    - x86 = (sig >> 8) & 0xf;
    -
    - if (x86 == 0xf)
    - x86 += (sig >> 20) & 0xff;
    -
    - return x86;
    -}
    -
    -static inline unsigned int x86_family(void)
    +static inline unsigned int x86_family_cpuid(void)
    {
    u32 eax = 0x00000001;
    u32 ebx, ecx = 0, edx;

    native_cpuid(&eax, &ebx, &ecx, &edx);

    - return __x86_family(eax);
    -}
    -
    -static inline unsigned int x86_model(unsigned int sig)
    -{
    - unsigned int x86, model;
    -
    - x86 = __x86_family(sig);
    -
    - model = (sig >> 4) & 0xf;
    -
    - if (x86 == 0x6 || x86 == 0xf)
    - model += ((sig >> 16) & 0xf) << 4;
    -
    - return model;
    + return x86_family(eax);
    }

    #ifdef CONFIG_MICROCODE
    diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
    index 4ddd780aeac9..c311b51efe15 100644
    --- a/arch/x86/kernel/cpu/common.c
    +++ b/arch/x86/kernel/cpu/common.c
    @@ -582,14 +582,9 @@ void cpu_detect(struct cpuinfo_x86 *c)
    u32 junk, tfms, cap0, misc;

    cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
    - c->x86 = (tfms >> 8) & 0xf;
    - c->x86_model = (tfms >> 4) & 0xf;
    - c->x86_mask = tfms & 0xf;
    -
    - if (c->x86 == 0xf)
    - c->x86 += (tfms >> 20) & 0xff;
    - if (c->x86 >= 0x6)
    - c->x86_model += ((tfms >> 16) & 0xf) << 4;
    + c->x86 = x86_family(tfms);
    + c->x86_model = x86_model(tfms);
    + c->x86_mask = x86_stepping(tfms);

    if (cap0 & (1<<19)) {
    c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
    diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
    index 7fc27f1cca58..e98c3487c9d3 100644
    --- a/arch/x86/kernel/cpu/microcode/core.c
    +++ b/arch/x86/kernel/cpu/microcode/core.c
    @@ -130,7 +130,7 @@ void __init load_ucode_bsp(void)
    return;

    vendor = x86_vendor();
    - family = x86_family();
    + family = x86_family_cpuid();

    switch (vendor) {
    case X86_VENDOR_INTEL:
    @@ -166,7 +166,7 @@ void load_ucode_ap(void)
    return;

    vendor = x86_vendor();
    - family = x86_family();
    + family = x86_family_cpuid();

    switch (vendor) {
    case X86_VENDOR_INTEL:
    @@ -207,7 +207,7 @@ void reload_early_microcode(void)
    int vendor, family;

    vendor = x86_vendor();
    - family = x86_family();
    + family = x86_family_cpuid();

    switch (vendor) {
    case X86_VENDOR_INTEL:
    diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
    index ce47402eb2f9..ee81c544ee0d 100644
    --- a/arch/x86/kernel/cpu/microcode/intel.c
    +++ b/arch/x86/kernel/cpu/microcode/intel.c
    @@ -145,10 +145,10 @@ matching_model_microcode(struct microcode_header_intel *mc_header,
    int ext_sigcount, i;
    struct extended_signature *ext_sig;

    - fam = __x86_family(sig);
    + fam = x86_family(sig);
    model = x86_model(sig);

    - fam_ucode = __x86_family(mc_header->sig);
    + fam_ucode = x86_family(mc_header->sig);
    model_ucode = x86_model(mc_header->sig);

    if (fam == fam_ucode && model == model_ucode)
    @@ -163,7 +163,7 @@ matching_model_microcode(struct microcode_header_intel *mc_header,
    ext_sigcount = ext_header->count;

    for (i = 0; i < ext_sigcount; i++) {
    - fam_ucode = __x86_family(ext_sig->sig);
    + fam_ucode = x86_family(ext_sig->sig);
    model_ucode = x86_model(ext_sig->sig);

    if (fam == fam_ucode && model == model_ucode)
    @@ -365,7 +365,7 @@ static int collect_cpu_info_early(struct ucode_cpu_info *uci)
    native_cpuid(&eax, &ebx, &ecx, &edx);
    csig.sig = eax;

    - family = __x86_family(csig.sig);
    + family = x86_family(csig.sig);
    model = x86_model(csig.sig);

    if ((model >= 5) || (family > 6)) {
    @@ -521,16 +521,12 @@ static bool __init load_builtin_intel_microcode(struct cpio_data *cp)
    {
    #ifdef CONFIG_X86_64
    unsigned int eax = 0x00000001, ebx, ecx = 0, edx;
    - unsigned int family, model, stepping;
    char name[30];

    native_cpuid(&eax, &ebx, &ecx, &edx);

    - family = __x86_family(eax);
    - model = x86_model(eax);
    - stepping = eax & 0xf;
    -
    - sprintf(name, "intel-ucode/%02x-%02x-%02x", family, model, stepping);
    + sprintf(name, "intel-ucode/%02x-%02x-%02x",
    + x86_family(eax), x86_model(eax), x86_stepping(eax));

    return get_builtin_firmware(cp, name);
    #else
    diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
    index f2587888d987..a501fa25da41 100644
    --- a/arch/x86/lib/Makefile
    +++ b/arch/x86/lib/Makefile
    @@ -16,7 +16,7 @@ clean-files := inat-tables.c

    obj-$(CONFIG_SMP) += msr-smp.o cache-smp.o

    -lib-y := delay.o misc.o cmdline.o
    +lib-y := delay.o misc.o cmdline.o cpu.o
    lib-y += usercopy_$(BITS).o usercopy.o getuser.o putuser.o
    lib-y += memcpy_$(BITS).o
    lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
    diff --git a/arch/x86/lib/cpu.c b/arch/x86/lib/cpu.c
    new file mode 100644
    index 000000000000..aa417a97511c
    --- /dev/null
    +++ b/arch/x86/lib/cpu.c
    @@ -0,0 +1,35 @@
    +#include <linux/module.h>
    +
    +unsigned int x86_family(unsigned int sig)
    +{
    + unsigned int x86;
    +
    + x86 = (sig >> 8) & 0xf;
    +
    + if (x86 == 0xf)
    + x86 += (sig >> 20) & 0xff;
    +
    + return x86;
    +}
    +EXPORT_SYMBOL_GPL(x86_family);
    +
    +unsigned int x86_model(unsigned int sig)
    +{
    + unsigned int fam, model;
    +
    + fam = x86_family(sig);
    +
    + model = (sig >> 4) & 0xf;
    +
    + if (fam >= 0x6)
    + model += ((sig >> 16) & 0xf) << 4;
    +
    + return model;
    +}
    +EXPORT_SYMBOL_GPL(x86_model);
    +
    +unsigned int x86_stepping(unsigned int sig)
    +{
    + return sig & 0xf;
    +}
    +EXPORT_SYMBOL_GPL(x86_stepping);
    --
    2.3.5


    \
     
     \ /
      Last update: 2015-11-14 12:01    [W:3.030 / U:0.340 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site