Skip to content

Commit c14cab2

Browse files
committed
Merge tag 'x86-urgent-2020-05-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: "A set of fixes for x86: - Ensure that direct mapping alias is always flushed when changing page attributes. The optimization for small ranges failed to do so when the virtual address was in the vmalloc or module space. - Unbreak the trace event registration for syscalls without arguments caused by the refactoring of the SYSCALL_DEFINE0() macro. - Move the printk in the TSC deadline timer code to a place where it is guaranteed to only be called once during boot and cannot be rearmed by clearing warn_once after boot. If it's invoked post boot then lockdep rightfully complains about a potential deadlock as the calling context is different. - A series of fixes for objtool and the ORC unwinder addressing variety of small issues: - Stack offset tracking for indirect CFAs in objtool ignored subsequent pushs and pops - Repair the unwind hints in the register clearing entry ASM code - Make the unwinding in the low level exit to usermode code stop after switching to the trampoline stack. The unwind hint is no longer valid and the ORC unwinder emits a warning as it can't find the registers anymore. - Fix unwind hints in switch_to_asm() and rewind_stack_do_exit() which caused objtool to generate bogus ORC data. - Prevent unwinder warnings when dumping the stack of a non-current task as there is no way to be sure about the validity because the dumped stack can be a moving target. - Make the ORC unwinder behave the same way as the frame pointer unwinder when dumping an inactive tasks stack and do not skip the first frame. - Prevent ORC unwinding before ORC data has been initialized - Immediately terminate unwinding when a unknown ORC entry type is found. - Prevent premature stop of the unwinder caused by IRET frames. - Fix another infinite loop in objtool caused by a negative offset which was not catched. - Address a few build warnings in the ORC unwinder and add missing static/ro_after_init annotations" * tag 'x86-urgent-2020-05-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/unwind/orc: Move ORC sorting variables under !CONFIG_MODULES x86/apic: Move TSC deadline timer debug printk ftrace/x86: Fix trace event registration for syscalls without arguments x86/mm/cpa: Flush direct map alias during cpa objtool: Fix infinite loop in for_offset_range() x86/unwind/orc: Fix premature unwind stoppage due to IRET frames x86/unwind/orc: Fix error path for bad ORC entry type x86/unwind/orc: Prevent unwinding before ORC initialization x86/unwind/orc: Don't skip the first frame for inactive tasks x86/unwind: Prevent false warnings for non-current tasks x86/unwind/orc: Convert global variables to static x86/entry/64: Fix unwind hints in rewind_stack_do_exit() x86/entry/64: Fix unwind hints in __switch_to_asm() x86/entry/64: Fix unwind hints in kernel exit path x86/entry/64: Fix unwind hints in register clearing code objtool: Fix stack offset tracking for indirect CFAs
2 parents 8b00083 + fb9cbbc commit c14cab2

File tree

11 files changed

+138
-90
lines changed

11 files changed

+138
-90
lines changed

arch/x86/entry/calling.h

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,6 @@ For 32-bit we have the following conventions - kernel is built with
9898
#define SIZEOF_PTREGS 21*8
9999

100100
.macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax save_ret=0
101-
/*
102-
* Push registers and sanitize registers of values that a
103-
* speculation attack might otherwise want to exploit. The
104-
* lower registers are likely clobbered well before they
105-
* could be put to use in a speculative execution gadget.
106-
* Interleave XOR with PUSH for better uop scheduling:
107-
*/
108101
.if \save_ret
109102
pushq %rsi /* pt_regs->si */
110103
movq 8(%rsp), %rsi /* temporarily store the return address in %rsi */
@@ -114,34 +107,43 @@ For 32-bit we have the following conventions - kernel is built with
114107
pushq %rsi /* pt_regs->si */
115108
.endif
116109
pushq \rdx /* pt_regs->dx */
117-
xorl %edx, %edx /* nospec dx */
118110
pushq %rcx /* pt_regs->cx */
119-
xorl %ecx, %ecx /* nospec cx */
120111
pushq \rax /* pt_regs->ax */
121112
pushq %r8 /* pt_regs->r8 */
122-
xorl %r8d, %r8d /* nospec r8 */
123113
pushq %r9 /* pt_regs->r9 */
124-
xorl %r9d, %r9d /* nospec r9 */
125114
pushq %r10 /* pt_regs->r10 */
126-
xorl %r10d, %r10d /* nospec r10 */
127115
pushq %r11 /* pt_regs->r11 */
128-
xorl %r11d, %r11d /* nospec r11*/
129116
pushq %rbx /* pt_regs->rbx */
130-
xorl %ebx, %ebx /* nospec rbx*/
131117
pushq %rbp /* pt_regs->rbp */
132-
xorl %ebp, %ebp /* nospec rbp*/
133118
pushq %r12 /* pt_regs->r12 */
134-
xorl %r12d, %r12d /* nospec r12*/
135119
pushq %r13 /* pt_regs->r13 */
136-
xorl %r13d, %r13d /* nospec r13*/
137120
pushq %r14 /* pt_regs->r14 */
138-
xorl %r14d, %r14d /* nospec r14*/
139121
pushq %r15 /* pt_regs->r15 */
140-
xorl %r15d, %r15d /* nospec r15*/
141122
UNWIND_HINT_REGS
123+
142124
.if \save_ret
143125
pushq %rsi /* return address on top of stack */
144126
.endif
127+
128+
/*
129+
* Sanitize registers of values that a speculation attack might
130+
* otherwise want to exploit. The lower registers are likely clobbered
131+
* well before they could be put to use in a speculative execution
132+
* gadget.
133+
*/
134+
xorl %edx, %edx /* nospec dx */
135+
xorl %ecx, %ecx /* nospec cx */
136+
xorl %r8d, %r8d /* nospec r8 */
137+
xorl %r9d, %r9d /* nospec r9 */
138+
xorl %r10d, %r10d /* nospec r10 */
139+
xorl %r11d, %r11d /* nospec r11 */
140+
xorl %ebx, %ebx /* nospec rbx */
141+
xorl %ebp, %ebp /* nospec rbp */
142+
xorl %r12d, %r12d /* nospec r12 */
143+
xorl %r13d, %r13d /* nospec r13 */
144+
xorl %r14d, %r14d /* nospec r14 */
145+
xorl %r15d, %r15d /* nospec r15 */
146+
145147
.endm
146148

147149
.macro POP_REGS pop_rdi=1 skip_r11rcx=0

arch/x86/entry/entry_64.S

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,6 @@ SYM_INNER_LABEL(entry_SYSCALL_64_after_hwframe, SYM_L_GLOBAL)
249249
*/
250250
syscall_return_via_sysret:
251251
/* rcx and r11 are already restored (see code above) */
252-
UNWIND_HINT_EMPTY
253252
POP_REGS pop_rdi=0 skip_r11rcx=1
254253

255254
/*
@@ -258,6 +257,7 @@ syscall_return_via_sysret:
258257
*/
259258
movq %rsp, %rdi
260259
movq PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %rsp
260+
UNWIND_HINT_EMPTY
261261

262262
pushq RSP-RDI(%rdi) /* RSP */
263263
pushq (%rdi) /* RDI */
@@ -279,8 +279,7 @@ SYM_CODE_END(entry_SYSCALL_64)
279279
* %rdi: prev task
280280
* %rsi: next task
281281
*/
282-
SYM_CODE_START(__switch_to_asm)
283-
UNWIND_HINT_FUNC
282+
SYM_FUNC_START(__switch_to_asm)
284283
/*
285284
* Save callee-saved registers
286285
* This must match the order in inactive_task_frame
@@ -321,7 +320,7 @@ SYM_CODE_START(__switch_to_asm)
321320
popq %rbp
322321

323322
jmp __switch_to
324-
SYM_CODE_END(__switch_to_asm)
323+
SYM_FUNC_END(__switch_to_asm)
325324

326325
/*
327326
* A newly forked process directly context switches into this address.
@@ -512,7 +511,7 @@ SYM_CODE_END(spurious_entries_start)
512511
* +----------------------------------------------------+
513512
*/
514513
SYM_CODE_START(interrupt_entry)
515-
UNWIND_HINT_FUNC
514+
UNWIND_HINT_IRET_REGS offset=16
516515
ASM_CLAC
517516
cld
518517

@@ -544,9 +543,9 @@ SYM_CODE_START(interrupt_entry)
544543
pushq 5*8(%rdi) /* regs->eflags */
545544
pushq 4*8(%rdi) /* regs->cs */
546545
pushq 3*8(%rdi) /* regs->ip */
546+
UNWIND_HINT_IRET_REGS
547547
pushq 2*8(%rdi) /* regs->orig_ax */
548548
pushq 8(%rdi) /* return address */
549-
UNWIND_HINT_FUNC
550549

551550
movq (%rdi), %rdi
552551
jmp 2f
@@ -637,6 +636,7 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL)
637636
*/
638637
movq %rsp, %rdi
639638
movq PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %rsp
639+
UNWIND_HINT_EMPTY
640640

641641
/* Copy the IRET frame to the trampoline stack. */
642642
pushq 6*8(%rdi) /* SS */
@@ -1739,7 +1739,7 @@ SYM_CODE_START(rewind_stack_do_exit)
17391739

17401740
movq PER_CPU_VAR(cpu_current_top_of_stack), %rax
17411741
leaq -PTREGS_SIZE(%rax), %rsp
1742-
UNWIND_HINT_FUNC sp_offset=PTREGS_SIZE
1742+
UNWIND_HINT_REGS
17431743

17441744
call do_exit
17451745
SYM_CODE_END(rewind_stack_do_exit)

arch/x86/include/asm/ftrace.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,12 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name
6161
{
6262
/*
6363
* Compare the symbol name with the system call name. Skip the
64-
* "__x64_sys", "__ia32_sys" or simple "sys" prefix.
64+
* "__x64_sys", "__ia32_sys", "__do_sys" or simple "sys" prefix.
6565
*/
6666
return !strcmp(sym + 3, name + 3) ||
6767
(!strncmp(sym, "__x64_", 6) && !strcmp(sym + 9, name + 3)) ||
68-
(!strncmp(sym, "__ia32_", 7) && !strcmp(sym + 10, name + 3));
68+
(!strncmp(sym, "__ia32_", 7) && !strcmp(sym + 10, name + 3)) ||
69+
(!strncmp(sym, "__do_sys", 8) && !strcmp(sym + 8, name + 3));
6970
}
7071

7172
#ifndef COMPILE_OFFSETS

arch/x86/include/asm/unwind.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct unwind_state {
1919
#if defined(CONFIG_UNWINDER_ORC)
2020
bool signal, full_regs;
2121
unsigned long sp, bp, ip;
22-
struct pt_regs *regs;
22+
struct pt_regs *regs, *prev_regs;
2323
#elif defined(CONFIG_UNWINDER_FRAME_POINTER)
2424
bool got_irq;
2525
unsigned long *bp, *orig_sp, ip;

arch/x86/kernel/apic/apic.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,6 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
352352
* According to Intel, MFENCE can do the serialization here.
353353
*/
354354
asm volatile("mfence" : : : "memory");
355-
356-
printk_once(KERN_DEBUG "TSC deadline timer enabled\n");
357355
return;
358356
}
359357

@@ -546,7 +544,7 @@ static struct clock_event_device lapic_clockevent = {
546544
};
547545
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
548546

549-
static u32 hsx_deadline_rev(void)
547+
static __init u32 hsx_deadline_rev(void)
550548
{
551549
switch (boot_cpu_data.x86_stepping) {
552550
case 0x02: return 0x3a; /* EP */
@@ -556,7 +554,7 @@ static u32 hsx_deadline_rev(void)
556554
return ~0U;
557555
}
558556

559-
static u32 bdx_deadline_rev(void)
557+
static __init u32 bdx_deadline_rev(void)
560558
{
561559
switch (boot_cpu_data.x86_stepping) {
562560
case 0x02: return 0x00000011;
@@ -568,7 +566,7 @@ static u32 bdx_deadline_rev(void)
568566
return ~0U;
569567
}
570568

571-
static u32 skx_deadline_rev(void)
569+
static __init u32 skx_deadline_rev(void)
572570
{
573571
switch (boot_cpu_data.x86_stepping) {
574572
case 0x03: return 0x01000136;
@@ -581,7 +579,7 @@ static u32 skx_deadline_rev(void)
581579
return ~0U;
582580
}
583581

584-
static const struct x86_cpu_id deadline_match[] = {
582+
static const struct x86_cpu_id deadline_match[] __initconst = {
585583
X86_MATCH_INTEL_FAM6_MODEL( HASWELL_X, &hsx_deadline_rev),
586584
X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X, 0x0b000020),
587585
X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_D, &bdx_deadline_rev),
@@ -603,18 +601,19 @@ static const struct x86_cpu_id deadline_match[] = {
603601
{},
604602
};
605603

606-
static void apic_check_deadline_errata(void)
604+
static __init bool apic_validate_deadline_timer(void)
607605
{
608606
const struct x86_cpu_id *m;
609607
u32 rev;
610608

611-
if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER) ||
612-
boot_cpu_has(X86_FEATURE_HYPERVISOR))
613-
return;
609+
if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
610+
return false;
611+
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
612+
return true;
614613

615614
m = x86_match_cpu(deadline_match);
616615
if (!m)
617-
return;
616+
return true;
618617

619618
/*
620619
* Function pointers will have the MSB set due to address layout,
@@ -626,11 +625,12 @@ static void apic_check_deadline_errata(void)
626625
rev = (u32)m->driver_data;
627626

628627
if (boot_cpu_data.microcode >= rev)
629-
return;
628+
return true;
630629

631630
setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER);
632631
pr_err(FW_BUG "TSC_DEADLINE disabled due to Errata; "
633632
"please update microcode to version: 0x%x (or later)\n", rev);
633+
return false;
634634
}
635635

636636
/*
@@ -2092,7 +2092,8 @@ void __init init_apic_mappings(void)
20922092
{
20932093
unsigned int new_apicid;
20942094

2095-
apic_check_deadline_errata();
2095+
if (apic_validate_deadline_timer())
2096+
pr_debug("TSC deadline timer available\n");
20962097

20972098
if (x2apic_mode) {
20982099
boot_cpu_physical_apicid = read_apic_id();

arch/x86/kernel/dumpstack_64.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ int get_stack_info(unsigned long *stack, struct task_struct *task,
183183
*/
184184
if (visit_mask) {
185185
if (*visit_mask & (1UL << info->type)) {
186-
printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type);
186+
if (task == current)
187+
printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type);
187188
goto unknown;
188189
}
189190
*visit_mask |= 1UL << info->type;

arch/x86/kernel/unwind_frame.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ bool unwind_next_frame(struct unwind_state *state)
344344
if (IS_ENABLED(CONFIG_X86_32))
345345
goto the_end;
346346

347+
if (state->task != current)
348+
goto the_end;
349+
347350
if (state->regs) {
348351
printk_deferred_once(KERN_WARNING
349352
"WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n",

0 commit comments

Comments
 (0)