Skip to content

Commit

Permalink
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar:
 "Misc fixes:

   - unwinder fixes
   - AMD CPU topology enumeration fixes
   - microcode loader fixes
   - x86 embedded platform fixes
   - fix for a bootup crash that may trigger when clearcpuid= is used
     with invalid values"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mpx: Use compatible types in comparison to fix sparse error
  x86/tsc: Add the Intel Denverton Processor to native_calibrate_tsc()
  x86/entry: Fix the end of the stack for newly forked tasks
  x86/unwind: Include __schedule() in stack traces
  x86/unwind: Disable KASAN checks for non-current tasks
  x86/unwind: Silence warnings for non-current tasks
  x86/microcode/intel: Use correct buffer size for saving microcode data
  x86/microcode/intel: Fix allocation size of struct ucode_patch
  x86/microcode/intel: Add a helper which gives the microcode revision
  x86/microcode: Use native CPUID to tickle out microcode revision
  x86/CPU: Add native CPUID variants returning a single datum
  x86/boot: Add missing declaration of string functions
  x86/CPU/AMD: Fix Bulldozer topology
  x86/platform/intel-mid: Rename 'spidev' to 'mrfld_spidev'
  x86/cpu: Fix typo in the comment for Anniedale
  x86/cpu: Fix bootup crashes by sanitizing the argument of the 'clearcpuid=' command-line option
  • Loading branch information
Linus Torvalds committed Jan 15, 2017
2 parents a11ce3a + 4538286 commit 83346fb
Show file tree
Hide file tree
Showing 18 changed files with 129 additions and 100 deletions.
1 change: 1 addition & 0 deletions arch/x86/boot/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <linux/types.h>
#include "ctype.h"
#include "string.h"

int memcmp(const void *s1, const void *s2, size_t len)
{
Expand Down
9 changes: 9 additions & 0 deletions arch/x86/boot/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,13 @@ int memcmp(const void *s1, const void *s2, size_t len);
#define memset(d,c,l) __builtin_memset(d,c,l)
#define memcmp __builtin_memcmp

extern int strcmp(const char *str1, const char *str2);
extern int strncmp(const char *cs, const char *ct, size_t count);
extern size_t strlen(const char *s);
extern char *strstr(const char *s1, const char *s2);
extern size_t strnlen(const char *s, size_t maxlen);
extern unsigned int atou(const char *s);
extern unsigned long long simple_strtoull(const char *cp, char **endp,
unsigned int base);

#endif /* BOOT_STRING_H */
30 changes: 11 additions & 19 deletions arch/x86/entry/entry_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -254,23 +254,6 @@ ENTRY(__switch_to_asm)
jmp __switch_to
END(__switch_to_asm)

/*
* The unwinder expects the last frame on the stack to always be at the same
* offset from the end of the page, which allows it to validate the stack.
* Calling schedule_tail() directly would break that convention because its an
* asmlinkage function so its argument has to be pushed on the stack. This
* wrapper creates a proper "end of stack" frame header before the call.
*/
ENTRY(schedule_tail_wrapper)
FRAME_BEGIN

pushl %eax
call schedule_tail
popl %eax

FRAME_END
ret
ENDPROC(schedule_tail_wrapper)
/*
* A newly forked process directly context switches into this address.
*
Expand All @@ -279,15 +262,24 @@ ENDPROC(schedule_tail_wrapper)
* edi: kernel thread arg
*/
ENTRY(ret_from_fork)
call schedule_tail_wrapper
FRAME_BEGIN /* help unwinder find end of stack */

/*
* schedule_tail() is asmlinkage so we have to put its 'prev' argument
* on the stack.
*/
pushl %eax
call schedule_tail
popl %eax

testl %ebx, %ebx
jnz 1f /* kernel threads are uncommon */

2:
/* When we fork, we trace the syscall return in the child, too. */
movl %esp, %eax
leal FRAME_OFFSET(%esp), %eax
call syscall_return_slowpath
FRAME_END
jmp restore_all

/* kernel thread */
Expand Down
11 changes: 7 additions & 4 deletions arch/x86/entry/entry_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <asm/smap.h>
#include <asm/pgtable_types.h>
#include <asm/export.h>
#include <asm/frame.h>
#include <linux/err.h>

.code64
Expand Down Expand Up @@ -408,17 +409,19 @@ END(__switch_to_asm)
* r12: kernel thread arg
*/
ENTRY(ret_from_fork)
FRAME_BEGIN /* help unwinder find end of stack */
movq %rax, %rdi
call schedule_tail /* rdi: 'prev' task parameter */
call schedule_tail /* rdi: 'prev' task parameter */

testq %rbx, %rbx /* from kernel_thread? */
jnz 1f /* kernel threads are uncommon */
testq %rbx, %rbx /* from kernel_thread? */
jnz 1f /* kernel threads are uncommon */

2:
movq %rsp, %rdi
leaq FRAME_OFFSET(%rsp),%rdi /* pt_regs pointer */
call syscall_return_slowpath /* returns with IRQs disabled */
TRACE_IRQS_ON /* user mode is traced as IRQS on */
SWAPGS
FRAME_END
jmp restore_regs_and_iret

1:
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/include/asm/intel-family.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
#define INTEL_FAM6_ATOM_SILVERMONT2 0x4D /* Avaton/Rangely */
#define INTEL_FAM6_ATOM_AIRMONT 0x4C /* CherryTrail / Braswell */
#define INTEL_FAM6_ATOM_MERRIFIELD 0x4A /* Tangier */
#define INTEL_FAM6_ATOM_MOOREFIELD 0x5A /* Annidale */
#define INTEL_FAM6_ATOM_MOOREFIELD 0x5A /* Anniedale */
#define INTEL_FAM6_ATOM_GOLDMONT 0x5C
#define INTEL_FAM6_ATOM_DENVERTON 0x5F /* Goldmont Microserver */

Expand Down
15 changes: 15 additions & 0 deletions arch/x86/include/asm/microcode_intel.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ struct extended_sigtable {

#define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)

static inline u32 intel_get_microcode_revision(void)
{
u32 rev, dummy;

native_wrmsrl(MSR_IA32_UCODE_REV, 0);

/* As documented in the SDM: Do a CPUID 1 here */
native_cpuid_eax(1);

/* get the current revision from MSR 0x8B */
native_rdmsr(MSR_IA32_UCODE_REV, dummy, rev);

return rev;
}

#ifdef CONFIG_MICROCODE_INTEL
extern void __init load_ucode_intel_bsp(void);
extern void load_ucode_intel_ap(void);
Expand Down
18 changes: 18 additions & 0 deletions arch/x86/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,24 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
: "memory");
}

#define native_cpuid_reg(reg) \
static inline unsigned int native_cpuid_##reg(unsigned int op) \
{ \
unsigned int eax = op, ebx, ecx = 0, edx; \
\
native_cpuid(&eax, &ebx, &ecx, &edx); \
\
return reg; \
}

/*
* Native CPUID functions returning a single datum.
*/
native_cpuid_reg(eax)
native_cpuid_reg(ebx)
native_cpuid_reg(ecx)
native_cpuid_reg(edx)

static inline void load_cr3(pgd_t *pgdir)
{
write_cr3(__pa(pgdir));
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/include/asm/stacktrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
if (task == current)
return __builtin_frame_address(0);

return (unsigned long *)((struct inactive_task_frame *)task->thread.sp)->bp;
return &((struct inactive_task_frame *)task->thread.sp)->bp;
}
#else
static inline unsigned long *
Expand Down
10 changes: 9 additions & 1 deletion arch/x86/include/asm/switch_to.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ static inline void prepare_switch_to(struct task_struct *prev,

asmlinkage void ret_from_fork(void);

/* data that is pointed to by thread.sp */
/*
* This is the structure pointed to by thread.sp for an inactive task. The
* order of the fields must match the code in __switch_to_asm().
*/
struct inactive_task_frame {
#ifdef CONFIG_X86_64
unsigned long r15;
Expand All @@ -48,6 +51,11 @@ struct inactive_task_frame {
unsigned long di;
#endif
unsigned long bx;

/*
* These two fields must be together. They form a stack frame header,
* needed by get_frame_pointer().
*/
unsigned long bp;
unsigned long ret_addr;
};
Expand Down
9 changes: 1 addition & 8 deletions arch/x86/kernel/cpu/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,15 +309,8 @@ static void amd_get_topology(struct cpuinfo_x86 *c)

/* get information required for multi-node processors */
if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
u32 eax, ebx, ecx, edx;

cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
node_id = ecx & 7;

/* get compute unit information */
smp_num_siblings = ((ebx >> 8) & 3) + 1;
c->x86_max_cores /= smp_num_siblings;
c->cpu_core_id = ebx & 0xff;
node_id = cpuid_ecx(0x8000001e) & 7;

/*
* We may have multiple LLCs if L3 caches exist, so check if we
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/cpu/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1221,7 +1221,7 @@ static __init int setup_disablecpuid(char *arg)
{
int bit;

if (get_option(&arg, &bit) && bit < NCAPINTS*32)
if (get_option(&arg, &bit) && bit >= 0 && bit < NCAPINTS * 32)
setup_clear_cpu_cap(bit);
else
return 0;
Expand Down
11 changes: 3 additions & 8 deletions arch/x86/kernel/cpu/intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <asm/bugs.h>
#include <asm/cpu.h>
#include <asm/intel-family.h>
#include <asm/microcode_intel.h>

#ifdef CONFIG_X86_64
#include <linux/topology.h>
Expand Down Expand Up @@ -78,14 +79,8 @@ static void early_init_intel(struct cpuinfo_x86 *c)
(c->x86 == 0x6 && c->x86_model >= 0x0e))
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);

if (c->x86 >= 6 && !cpu_has(c, X86_FEATURE_IA64)) {
unsigned lower_word;

wrmsr(MSR_IA32_UCODE_REV, 0, 0);
/* Required by the SDM */
sync_core();
rdmsr(MSR_IA32_UCODE_REV, lower_word, c->microcode);
}
if (c->x86 >= 6 && !cpu_has(c, X86_FEATURE_IA64))
c->microcode = intel_get_microcode_revision();

/*
* Atom erratum AAE44/AAF40/AAG38/AAH41:
Expand Down
Loading

0 comments on commit 83346fb

Please sign in to comment.