diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-12 16:49:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-12 16:49:57 -0500 |
commit | 5645688f9d0d5a32f030f9c5429e1a58bedca23b (patch) | |
tree | 0b576ba953fb26d521c6b8c3364848acb00ceef3 | |
parent | 4ade5b2268b9ff05e48a9cb99689c4fd15fbe9c3 (diff) | |
parent | 53938ee427bf27525a63721b7e25d86b8f31f161 (diff) |
Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 asm updates from Ingo Molnar:
"The main changes in this development cycle were:
- a large number of call stack dumping/printing improvements: higher
robustness, better cross-context dumping, improved output, etc.
(Josh Poimboeuf)
- vDSO getcpu() performance improvement for future Intel CPUs with
the RDPID instruction (Andy Lutomirski)
- add two new Intel AVX512 features and the CPUID support
infrastructure for it: AVX512IFMA and AVX512VBMI. (Gayatri Kammela,
He Chen)
- more copy-user unification (Borislav Petkov)
- entry code assembly macro simplifications (Alexander Kuleshov)
- vDSO C/R support improvements (Dmitry Safonov)
- misc fixes and cleanups (Borislav Petkov, Paul Bolle)"
* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (40 commits)
scripts/decode_stacktrace.sh: Fix address line detection on x86
x86/boot/64: Use defines for page size
x86/dumpstack: Make stack name tags more comprehensible
selftests/x86: Add test_vdso to test getcpu()
x86/vdso: Use RDPID in preference to LSL when available
x86/dumpstack: Handle NULL stack pointer in show_trace_log_lvl()
x86/cpufeatures: Enable new AVX512 cpu features
x86/cpuid: Provide get_scattered_cpuid_leaf()
x86/cpuid: Cleanup cpuid_regs definitions
x86/copy_user: Unify the code by removing the 64-bit asm _copy_*_user() variants
x86/unwind: Ensure stack grows down
x86/vdso: Set vDSO pointer only after success
x86/prctl/uapi: Remove #ifdef for CHECKPOINT_RESTORE
x86/unwind: Detect bad stack return address
x86/dumpstack: Warn on stack recursion
x86/unwind: Warn on bad frame pointer
x86/decoder: Use stderr if insn sanity test fails
x86/decoder: Use stdout if insn decoder test is successful
mm/page_alloc: Remove kernel address exposure in free_reserved_area()
x86/dumpstack: Remove raw stack dump
...
41 files changed, 703 insertions, 497 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 86a31dfc036e..7c817dc45d45 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1963,9 +1963,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1963 | kmemcheck=2 (one-shot mode) | 1963 | kmemcheck=2 (one-shot mode) |
1964 | Default: 2 (one-shot mode) | 1964 | Default: 2 (one-shot mode) |
1965 | 1965 | ||
1966 | kstack=N [X86] Print N words from the kernel stack | ||
1967 | in oops dumps. | ||
1968 | |||
1969 | kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs. | 1966 | kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs. |
1970 | Default is 0 (don't ignore, but inject #GP) | 1967 | Default is 0 (don't ignore, but inject #GP) |
1971 | 1968 | ||
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index ffab8b5caa60..065f18478c1c 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt | |||
@@ -40,7 +40,6 @@ show up in /proc/sys/kernel: | |||
40 | - hung_task_warnings | 40 | - hung_task_warnings |
41 | - kexec_load_disabled | 41 | - kexec_load_disabled |
42 | - kptr_restrict | 42 | - kptr_restrict |
43 | - kstack_depth_to_print [ X86 only ] | ||
44 | - l2cr [ PPC only ] | 43 | - l2cr [ PPC only ] |
45 | - modprobe ==> Documentation/debugging-modules.txt | 44 | - modprobe ==> Documentation/debugging-modules.txt |
46 | - modules_disabled | 45 | - modules_disabled |
@@ -395,13 +394,6 @@ When kptr_restrict is set to (2), kernel pointers printed using | |||
395 | 394 | ||
396 | ============================================================== | 395 | ============================================================== |
397 | 396 | ||
398 | kstack_depth_to_print: (X86 only) | ||
399 | |||
400 | Controls the number of words to print when dumping the raw | ||
401 | kernel stack. | ||
402 | |||
403 | ============================================================== | ||
404 | |||
405 | l2cr: (PPC only) | 397 | l2cr: (PPC only) |
406 | 398 | ||
407 | This flag controls the L2 cache of G3 processor boards. If | 399 | This flag controls the L2 cache of G3 processor boards. If |
diff --git a/Documentation/x86/x86_64/boot-options.txt b/Documentation/x86/x86_64/boot-options.txt index 0965a71f9942..61b611e9eeaf 100644 --- a/Documentation/x86/x86_64/boot-options.txt +++ b/Documentation/x86/x86_64/boot-options.txt | |||
@@ -277,10 +277,6 @@ IOMMU (input/output memory management unit) | |||
277 | space might stop working. Use this option if you have devices that | 277 | space might stop working. Use this option if you have devices that |
278 | are accessed from userspace directly on some PCI host bridge. | 278 | are accessed from userspace directly on some PCI host bridge. |
279 | 279 | ||
280 | Debugging | ||
281 | |||
282 | kstack=N Print N words from the kernel stack in oops dumps. | ||
283 | |||
284 | Miscellaneous | 280 | Miscellaneous |
285 | 281 | ||
286 | nogbpages | 282 | nogbpages |
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index 9a9e5884066c..05ed3d393da7 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h | |||
@@ -90,8 +90,8 @@ For 32-bit we have the following conventions - kernel is built with | |||
90 | 90 | ||
91 | #define SIZEOF_PTREGS 21*8 | 91 | #define SIZEOF_PTREGS 21*8 |
92 | 92 | ||
93 | .macro ALLOC_PT_GPREGS_ON_STACK addskip=0 | 93 | .macro ALLOC_PT_GPREGS_ON_STACK |
94 | addq $-(15*8+\addskip), %rsp | 94 | addq $-(15*8), %rsp |
95 | .endm | 95 | .endm |
96 | 96 | ||
97 | .macro SAVE_C_REGS_HELPER offset=0 rax=1 rcx=1 r8910=1 r11=1 | 97 | .macro SAVE_C_REGS_HELPER offset=0 rax=1 rcx=1 r8910=1 r11=1 |
@@ -147,15 +147,6 @@ For 32-bit we have the following conventions - kernel is built with | |||
147 | movq 5*8+\offset(%rsp), %rbx | 147 | movq 5*8+\offset(%rsp), %rbx |
148 | .endm | 148 | .endm |
149 | 149 | ||
150 | .macro ZERO_EXTRA_REGS | ||
151 | xorl %r15d, %r15d | ||
152 | xorl %r14d, %r14d | ||
153 | xorl %r13d, %r13d | ||
154 | xorl %r12d, %r12d | ||
155 | xorl %ebp, %ebp | ||
156 | xorl %ebx, %ebx | ||
157 | .endm | ||
158 | |||
159 | .macro RESTORE_C_REGS_HELPER rstor_rax=1, rstor_rcx=1, rstor_r11=1, rstor_r8910=1, rstor_rdx=1 | 150 | .macro RESTORE_C_REGS_HELPER rstor_rax=1, rstor_rcx=1, rstor_r11=1, rstor_r8910=1, rstor_rdx=1 |
160 | .if \rstor_r11 | 151 | .if \rstor_r11 |
161 | movq 6*8(%rsp), %r11 | 152 | movq 6*8(%rsp), %r11 |
@@ -201,6 +192,26 @@ For 32-bit we have the following conventions - kernel is built with | |||
201 | .byte 0xf1 | 192 | .byte 0xf1 |
202 | .endm | 193 | .endm |
203 | 194 | ||
195 | /* | ||
196 | * This is a sneaky trick to help the unwinder find pt_regs on the stack. The | ||
197 | * frame pointer is replaced with an encoded pointer to pt_regs. The encoding | ||
198 | * is just setting the LSB, which makes it an invalid stack address and is also | ||
199 | * a signal to the unwinder that it's a pt_regs pointer in disguise. | ||
200 | * | ||
201 | * NOTE: This macro must be used *after* SAVE_EXTRA_REGS because it corrupts | ||
202 | * the original rbp. | ||
203 | */ | ||
204 | .macro ENCODE_FRAME_POINTER ptregs_offset=0 | ||
205 | #ifdef CONFIG_FRAME_POINTER | ||
206 | .if \ptregs_offset | ||
207 | leaq \ptregs_offset(%rsp), %rbp | ||
208 | .else | ||
209 | mov %rsp, %rbp | ||
210 | .endif | ||
211 | orq $0x1, %rbp | ||
212 | #endif | ||
213 | .endm | ||
214 | |||
204 | #endif /* CONFIG_X86_64 */ | 215 | #endif /* CONFIG_X86_64 */ |
205 | 216 | ||
206 | /* | 217 | /* |
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index 21b352a11b49..acc0c6f36f3f 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/asm.h> | 45 | #include <asm/asm.h> |
46 | #include <asm/smap.h> | 46 | #include <asm/smap.h> |
47 | #include <asm/export.h> | 47 | #include <asm/export.h> |
48 | #include <asm/frame.h> | ||
48 | 49 | ||
49 | .section .entry.text, "ax" | 50 | .section .entry.text, "ax" |
50 | 51 | ||
@@ -175,6 +176,22 @@ | |||
175 | SET_KERNEL_GS %edx | 176 | SET_KERNEL_GS %edx |
176 | .endm | 177 | .endm |
177 | 178 | ||
179 | /* | ||
180 | * This is a sneaky trick to help the unwinder find pt_regs on the stack. The | ||
181 | * frame pointer is replaced with an encoded pointer to pt_regs. The encoding | ||
182 | * is just setting the LSB, which makes it an invalid stack address and is also | ||
183 | * a signal to the unwinder that it's a pt_regs pointer in disguise. | ||
184 | * | ||
185 | * NOTE: This macro must be used *after* SAVE_ALL because it corrupts the | ||
186 | * original rbp. | ||
187 | */ | ||
188 | .macro ENCODE_FRAME_POINTER | ||
189 | #ifdef CONFIG_FRAME_POINTER | ||
190 | mov %esp, %ebp | ||
191 | orl $0x1, %ebp | ||
192 | #endif | ||
193 | .endm | ||
194 | |||
178 | .macro RESTORE_INT_REGS | 195 | .macro RESTORE_INT_REGS |
179 | popl %ebx | 196 | popl %ebx |
180 | popl %ecx | 197 | popl %ecx |
@@ -238,6 +255,23 @@ ENTRY(__switch_to_asm) | |||
238 | END(__switch_to_asm) | 255 | END(__switch_to_asm) |
239 | 256 | ||
240 | /* | 257 | /* |
258 | * The unwinder expects the last frame on the stack to always be at the same | ||
259 | * offset from the end of the page, which allows it to validate the stack. | ||
260 | * Calling schedule_tail() directly would break that convention because its an | ||
261 | * asmlinkage function so its argument has to be pushed on the stack. This | ||
262 | * wrapper creates a proper "end of stack" frame header before the call. | ||
263 | */ | ||
264 | ENTRY(schedule_tail_wrapper) | ||
265 | FRAME_BEGIN | ||
266 | |||
267 | pushl %eax | ||
268 | call schedule_tail | ||
269 | popl %eax | ||
270 | |||
271 | FRAME_END | ||
272 | ret | ||
273 | ENDPROC(schedule_tail_wrapper) | ||
274 | /* | ||
241 | * A newly forked process directly context switches into this address. | 275 | * A newly forked process directly context switches into this address. |
242 | * | 276 | * |
243 | * eax: prev task we switched from | 277 | * eax: prev task we switched from |
@@ -245,9 +279,7 @@ END(__switch_to_asm) | |||
245 | * edi: kernel thread arg | 279 | * edi: kernel thread arg |
246 | */ | 280 | */ |
247 | ENTRY(ret_from_fork) | 281 | ENTRY(ret_from_fork) |
248 | pushl %eax | 282 | call schedule_tail_wrapper |
249 | call schedule_tail | ||
250 | popl %eax | ||
251 | 283 | ||
252 | testl %ebx, %ebx | 284 | testl %ebx, %ebx |
253 | jnz 1f /* kernel threads are uncommon */ | 285 | jnz 1f /* kernel threads are uncommon */ |
@@ -307,13 +339,13 @@ END(ret_from_exception) | |||
307 | #ifdef CONFIG_PREEMPT | 339 | #ifdef CONFIG_PREEMPT |
308 | ENTRY(resume_kernel) | 340 | ENTRY(resume_kernel) |
309 | DISABLE_INTERRUPTS(CLBR_ANY) | 341 | DISABLE_INTERRUPTS(CLBR_ANY) |
310 | need_resched: | 342 | .Lneed_resched: |
311 | cmpl $0, PER_CPU_VAR(__preempt_count) | 343 | cmpl $0, PER_CPU_VAR(__preempt_count) |
312 | jnz restore_all | 344 | jnz restore_all |
313 | testl $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off (exception path) ? | 345 | testl $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off (exception path) ? |
314 | jz restore_all | 346 | jz restore_all |
315 | call preempt_schedule_irq | 347 | call preempt_schedule_irq |
316 | jmp need_resched | 348 | jmp .Lneed_resched |
317 | END(resume_kernel) | 349 | END(resume_kernel) |
318 | #endif | 350 | #endif |
319 | 351 | ||
@@ -334,7 +366,7 @@ GLOBAL(__begin_SYSENTER_singlestep_region) | |||
334 | */ | 366 | */ |
335 | ENTRY(xen_sysenter_target) | 367 | ENTRY(xen_sysenter_target) |
336 | addl $5*4, %esp /* remove xen-provided frame */ | 368 | addl $5*4, %esp /* remove xen-provided frame */ |
337 | jmp sysenter_past_esp | 369 | jmp .Lsysenter_past_esp |
338 | #endif | 370 | #endif |
339 | 371 | ||
340 | /* | 372 | /* |
@@ -371,7 +403,7 @@ ENTRY(xen_sysenter_target) | |||
371 | */ | 403 | */ |
372 | ENTRY(entry_SYSENTER_32) | 404 | ENTRY(entry_SYSENTER_32) |
373 | movl TSS_sysenter_sp0(%esp), %esp | 405 | movl TSS_sysenter_sp0(%esp), %esp |
374 | sysenter_past_esp: | 406 | .Lsysenter_past_esp: |
375 | pushl $__USER_DS /* pt_regs->ss */ | 407 | pushl $__USER_DS /* pt_regs->ss */ |
376 | pushl %ebp /* pt_regs->sp (stashed in bp) */ | 408 | pushl %ebp /* pt_regs->sp (stashed in bp) */ |
377 | pushfl /* pt_regs->flags (except IF = 0) */ | 409 | pushfl /* pt_regs->flags (except IF = 0) */ |
@@ -504,9 +536,9 @@ ENTRY(entry_INT80_32) | |||
504 | 536 | ||
505 | restore_all: | 537 | restore_all: |
506 | TRACE_IRQS_IRET | 538 | TRACE_IRQS_IRET |
507 | restore_all_notrace: | 539 | .Lrestore_all_notrace: |
508 | #ifdef CONFIG_X86_ESPFIX32 | 540 | #ifdef CONFIG_X86_ESPFIX32 |
509 | ALTERNATIVE "jmp restore_nocheck", "", X86_BUG_ESPFIX | 541 | ALTERNATIVE "jmp .Lrestore_nocheck", "", X86_BUG_ESPFIX |
510 | 542 | ||
511 | movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS | 543 | movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS |
512 | /* | 544 | /* |
@@ -518,22 +550,23 @@ restore_all_notrace: | |||
518 | movb PT_CS(%esp), %al | 550 | movb PT_CS(%esp), %al |
519 | andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax | 551 | andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax |
520 | cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax | 552 | cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax |
521 | je ldt_ss # returning to user-space with LDT SS | 553 | je .Lldt_ss # returning to user-space with LDT SS |
522 | #endif | 554 | #endif |
523 | restore_nocheck: | 555 | .Lrestore_nocheck: |
524 | RESTORE_REGS 4 # skip orig_eax/error_code | 556 | RESTORE_REGS 4 # skip orig_eax/error_code |
525 | irq_return: | 557 | .Lirq_return: |
526 | INTERRUPT_RETURN | 558 | INTERRUPT_RETURN |
559 | |||
527 | .section .fixup, "ax" | 560 | .section .fixup, "ax" |
528 | ENTRY(iret_exc ) | 561 | ENTRY(iret_exc ) |
529 | pushl $0 # no error code | 562 | pushl $0 # no error code |
530 | pushl $do_iret_error | 563 | pushl $do_iret_error |
531 | jmp error_code | 564 | jmp common_exception |
532 | .previous | 565 | .previous |
533 | _ASM_EXTABLE(irq_return, iret_exc) | 566 | _ASM_EXTABLE(.Lirq_return, iret_exc) |
534 | 567 | ||
535 | #ifdef CONFIG_X86_ESPFIX32 | 568 | #ifdef CONFIG_X86_ESPFIX32 |
536 | ldt_ss: | 569 | .Lldt_ss: |
537 | /* | 570 | /* |
538 | * Setup and switch to ESPFIX stack | 571 | * Setup and switch to ESPFIX stack |
539 | * | 572 | * |
@@ -562,7 +595,7 @@ ldt_ss: | |||
562 | */ | 595 | */ |
563 | DISABLE_INTERRUPTS(CLBR_EAX) | 596 | DISABLE_INTERRUPTS(CLBR_EAX) |
564 | lss (%esp), %esp /* switch to espfix segment */ | 597 | lss (%esp), %esp /* switch to espfix segment */ |
565 | jmp restore_nocheck | 598 | jmp .Lrestore_nocheck |
566 | #endif | 599 | #endif |
567 | ENDPROC(entry_INT80_32) | 600 | ENDPROC(entry_INT80_32) |
568 | 601 | ||
@@ -624,6 +657,7 @@ common_interrupt: | |||
624 | ASM_CLAC | 657 | ASM_CLAC |
625 | addl $-0x80, (%esp) /* Adjust vector into the [-256, -1] range */ | 658 | addl $-0x80, (%esp) /* Adjust vector into the [-256, -1] range */ |
626 | SAVE_ALL | 659 | SAVE_ALL |
660 | ENCODE_FRAME_POINTER | ||
627 | TRACE_IRQS_OFF | 661 | TRACE_IRQS_OFF |
628 | movl %esp, %eax | 662 | movl %esp, %eax |
629 | call do_IRQ | 663 | call do_IRQ |
@@ -635,6 +669,7 @@ ENTRY(name) \ | |||
635 | ASM_CLAC; \ | 669 | ASM_CLAC; \ |
636 | pushl $~(nr); \ | 670 | pushl $~(nr); \ |
637 | SAVE_ALL; \ | 671 | SAVE_ALL; \ |
672 | ENCODE_FRAME_POINTER; \ | ||
638 | TRACE_IRQS_OFF \ | 673 | TRACE_IRQS_OFF \ |
639 | movl %esp, %eax; \ | 674 | movl %esp, %eax; \ |
640 | call fn; \ | 675 | call fn; \ |
@@ -659,7 +694,7 @@ ENTRY(coprocessor_error) | |||
659 | ASM_CLAC | 694 | ASM_CLAC |
660 | pushl $0 | 695 | pushl $0 |
661 | pushl $do_coprocessor_error | 696 | pushl $do_coprocessor_error |
662 | jmp error_code | 697 | jmp common_exception |
663 | END(coprocessor_error) | 698 | END(coprocessor_error) |
664 | 699 | ||
665 | ENTRY(simd_coprocessor_error) | 700 | ENTRY(simd_coprocessor_error) |
@@ -673,14 +708,14 @@ ENTRY(simd_coprocessor_error) | |||
673 | #else | 708 | #else |
674 | pushl $do_simd_coprocessor_error | 709 | pushl $do_simd_coprocessor_error |
675 | #endif | 710 | #endif |
676 | jmp error_code | 711 | jmp common_exception |
677 | END(simd_coprocessor_error) | 712 | END(simd_coprocessor_error) |
678 | 713 | ||
679 | ENTRY(device_not_available) | 714 | ENTRY(device_not_available) |
680 | ASM_CLAC | 715 | ASM_CLAC |
681 | pushl $-1 # mark this as an int | 716 | pushl $-1 # mark this as an int |
682 | pushl $do_device_not_available | 717 | pushl $do_device_not_available |
683 | jmp error_code | 718 | jmp common_exception |
684 | END(device_not_available) | 719 | END(device_not_available) |
685 | 720 | ||
686 | #ifdef CONFIG_PARAVIRT | 721 | #ifdef CONFIG_PARAVIRT |
@@ -694,59 +729,59 @@ ENTRY(overflow) | |||
694 | ASM_CLAC | 729 | ASM_CLAC |
695 | pushl $0 | 730 | pushl $0 |
696 | pushl $do_overflow | 731 | pushl $do_overflow |
697 | jmp error_code | 732 | jmp common_exception |
698 | END(overflow) | 733 | END(overflow) |
699 | 734 | ||
700 | ENTRY(bounds) | 735 | ENTRY(bounds) |
701 | ASM_CLAC | 736 | ASM_CLAC |
702 | pushl $0 | 737 | pushl $0 |
703 | pushl $do_bounds | 738 | pushl $do_bounds |
704 | jmp error_code | 739 | jmp common_exception |
705 | END(bounds) | 740 | END(bounds) |
706 | 741 | ||
707 | ENTRY(invalid_op) | 742 | ENTRY(invalid_op) |
708 | ASM_CLAC | 743 | ASM_CLAC |
709 | pushl $0 | 744 | pushl $0 |
710 | pushl $do_invalid_op | 745 | pushl $do_invalid_op |
711 | jmp error_code | 746 | jmp common_exception |
712 | END(invalid_op) | 747 | END(invalid_op) |
713 | 748 | ||
714 | ENTRY(coprocessor_segment_overrun) | 749 | ENTRY(coprocessor_segment_overrun) |
715 | ASM_CLAC | 750 | ASM_CLAC |
716 | pushl $0 | 751 | pushl $0 |
717 | pushl $do_coprocessor_segment_overrun | 752 | pushl $do_coprocessor_segment_overrun |
718 | jmp error_code | 753 | jmp common_exception |
719 | END(coprocessor_segment_overrun) | 754 | END(coprocessor_segment_overrun) |
720 | 755 | ||
721 | ENTRY(invalid_TSS) | 756 | ENTRY(invalid_TSS) |
722 | ASM_CLAC | 757 | ASM_CLAC |
723 | pushl $do_invalid_TSS | 758 | pushl $do_invalid_TSS |
724 | jmp error_code | 759 | jmp common_exception |
725 | END(invalid_TSS) | 760 | END(invalid_TSS) |
726 | 761 | ||
727 | ENTRY(segment_not_present) | 762 | ENTRY(segment_not_present) |
728 | ASM_CLAC | 763 | ASM_CLAC |
729 | pushl $do_segment_not_present | 764 | pushl $do_segment_not_present |
730 | jmp error_code | 765 | jmp common_exception |
731 | END(segment_not_present) | 766 | END(segment_not_present) |
732 | 767 | ||
733 | ENTRY(stack_segment) | 768 | ENTRY(stack_segment) |
734 | ASM_CLAC | 769 | ASM_CLAC |
735 | pushl $do_stack_segment | 770 | pushl $do_stack_segment |
736 | jmp error_code | 771 | jmp common_exception |
737 | END(stack_segment) | 772 | END(stack_segment) |
738 | 773 | ||
739 | ENTRY(alignment_check) | 774 | ENTRY(alignment_check) |
740 | ASM_CLAC | 775 | ASM_CLAC |
741 | pushl $do_alignment_check | 776 | pushl $do_alignment_check |
742 | jmp error_code | 777 | jmp common_exception |
743 | END(alignment_check) | 778 | END(alignment_check) |
744 | 779 | ||
745 | ENTRY(divide_error) | 780 | ENTRY(divide_error) |
746 | ASM_CLAC | 781 | ASM_CLAC |
747 | pushl $0 # no error code | 782 | pushl $0 # no error code |
748 | pushl $do_divide_error | 783 | pushl $do_divide_error |
749 | jmp error_code | 784 | jmp common_exception |
750 | END(divide_error) | 785 | END(divide_error) |
751 | 786 | ||
752 | #ifdef CONFIG_X86_MCE | 787 | #ifdef CONFIG_X86_MCE |
@@ -754,7 +789,7 @@ ENTRY(machine_check) | |||
754 | ASM_CLAC | 789 | ASM_CLAC |
755 | pushl $0 | 790 | pushl $0 |
756 | pushl machine_check_vector | 791 | pushl machine_check_vector |
757 | jmp error_code | 792 | jmp common_exception |
758 | END(machine_check) | 793 | END(machine_check) |
759 | #endif | 794 | #endif |
760 | 795 | ||
@@ -762,13 +797,14 @@ ENTRY(spurious_interrupt_bug) | |||
762 | ASM_CLAC | 797 | ASM_CLAC |
763 | pushl $0 | 798 | pushl $0 |
764 | pushl $do_spurious_interrupt_bug | 799 | pushl $do_spurious_interrupt_bug |
765 | jmp error_code | 800 | jmp common_exception |
766 | END(spurious_interrupt_bug) | 801 | END(spurious_interrupt_bug) |
767 | 802 | ||
768 | #ifdef CONFIG_XEN | 803 | #ifdef CONFIG_XEN |
769 | ENTRY(xen_hypervisor_callback) | 804 | ENTRY(xen_hypervisor_callback) |
770 | pushl $-1 /* orig_ax = -1 => not a system call */ | 805 | pushl $-1 /* orig_ax = -1 => not a system call */ |
771 | SAVE_ALL | 806 | SAVE_ALL |
807 | ENCODE_FRAME_POINTER | ||
772 | TRACE_IRQS_OFF | 808 | TRACE_IRQS_OFF |
773 | 809 | ||
774 | /* | 810 | /* |
@@ -823,6 +859,7 @@ ENTRY(xen_failsafe_callback) | |||
823 | jmp iret_exc | 859 | jmp iret_exc |
824 | 5: pushl $-1 /* orig_ax = -1 => not a system call */ | 860 | 5: pushl $-1 /* orig_ax = -1 => not a system call */ |
825 | SAVE_ALL | 861 | SAVE_ALL |
862 | ENCODE_FRAME_POINTER | ||
826 | jmp ret_from_exception | 863 | jmp ret_from_exception |
827 | 864 | ||
828 | .section .fixup, "ax" | 865 | .section .fixup, "ax" |
@@ -882,7 +919,7 @@ ftrace_call: | |||
882 | popl %edx | 919 | popl %edx |
883 | popl %ecx | 920 | popl %ecx |
884 | popl %eax | 921 | popl %eax |
885 | ftrace_ret: | 922 | .Lftrace_ret: |
886 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 923 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
887 | .globl ftrace_graph_call | 924 | .globl ftrace_graph_call |
888 | ftrace_graph_call: | 925 | ftrace_graph_call: |
@@ -952,7 +989,7 @@ GLOBAL(ftrace_regs_call) | |||
952 | popl %gs | 989 | popl %gs |
953 | addl $8, %esp /* Skip orig_ax and ip */ | 990 | addl $8, %esp /* Skip orig_ax and ip */ |
954 | popf /* Pop flags at end (no addl to corrupt flags) */ | 991 | popf /* Pop flags at end (no addl to corrupt flags) */ |
955 | jmp ftrace_ret | 992 | jmp .Lftrace_ret |
956 | 993 | ||
957 | popf | 994 | popf |
958 | jmp ftrace_stub | 995 | jmp ftrace_stub |
@@ -963,7 +1000,7 @@ ENTRY(mcount) | |||
963 | jb ftrace_stub /* Paging not enabled yet? */ | 1000 | jb ftrace_stub /* Paging not enabled yet? */ |
964 | 1001 | ||
965 | cmpl $ftrace_stub, ftrace_trace_function | 1002 | cmpl $ftrace_stub, ftrace_trace_function |
966 | jnz trace | 1003 | jnz .Ltrace |
967 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 1004 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
968 | cmpl $ftrace_stub, ftrace_graph_return | 1005 | cmpl $ftrace_stub, ftrace_graph_return |
969 | jnz ftrace_graph_caller | 1006 | jnz ftrace_graph_caller |
@@ -976,7 +1013,7 @@ ftrace_stub: | |||
976 | ret | 1013 | ret |
977 | 1014 | ||
978 | /* taken from glibc */ | 1015 | /* taken from glibc */ |
979 | trace: | 1016 | .Ltrace: |
980 | pushl %eax | 1017 | pushl %eax |
981 | pushl %ecx | 1018 | pushl %ecx |
982 | pushl %edx | 1019 | pushl %edx |
@@ -1027,7 +1064,7 @@ return_to_handler: | |||
1027 | ENTRY(trace_page_fault) | 1064 | ENTRY(trace_page_fault) |
1028 | ASM_CLAC | 1065 | ASM_CLAC |
1029 | pushl $trace_do_page_fault | 1066 | pushl $trace_do_page_fault |
1030 | jmp error_code | 1067 | jmp common_exception |
1031 | END(trace_page_fault) | 1068 | END(trace_page_fault) |
1032 | #endif | 1069 | #endif |
1033 | 1070 | ||
@@ -1035,7 +1072,10 @@ ENTRY(page_fault) | |||
1035 | ASM_CLAC | 1072 | ASM_CLAC |
1036 | pushl $do_page_fault | 1073 | pushl $do_page_fault |
1037 | ALIGN | 1074 | ALIGN |
1038 | error_code: | 1075 | jmp common_exception |
1076 | END(page_fault) | ||
1077 | |||
1078 | common_exception: | ||
1039 | /* the function address is in %gs's slot on the stack */ | 1079 | /* the function address is in %gs's slot on the stack */ |
1040 | pushl %fs | 1080 | pushl %fs |
1041 | pushl %es | 1081 | pushl %es |
@@ -1047,6 +1087,7 @@ error_code: | |||
1047 | pushl %edx | 1087 | pushl %edx |
1048 | pushl %ecx | 1088 | pushl %ecx |
1049 | pushl %ebx | 1089 | pushl %ebx |
1090 | ENCODE_FRAME_POINTER | ||
1050 | cld | 1091 | cld |
1051 | movl $(__KERNEL_PERCPU), %ecx | 1092 | movl $(__KERNEL_PERCPU), %ecx |
1052 | movl %ecx, %fs | 1093 | movl %ecx, %fs |
@@ -1064,7 +1105,7 @@ error_code: | |||
1064 | movl %esp, %eax # pt_regs pointer | 1105 | movl %esp, %eax # pt_regs pointer |
1065 | call *%edi | 1106 | call *%edi |
1066 | jmp ret_from_exception | 1107 | jmp ret_from_exception |
1067 | END(page_fault) | 1108 | END(common_exception) |
1068 | 1109 | ||
1069 | ENTRY(debug) | 1110 | ENTRY(debug) |
1070 | /* | 1111 | /* |
@@ -1079,6 +1120,7 @@ ENTRY(debug) | |||
1079 | ASM_CLAC | 1120 | ASM_CLAC |
1080 | pushl $-1 # mark this as an int | 1121 | pushl $-1 # mark this as an int |
1081 | SAVE_ALL | 1122 | SAVE_ALL |
1123 | ENCODE_FRAME_POINTER | ||
1082 | xorl %edx, %edx # error code 0 | 1124 | xorl %edx, %edx # error code 0 |
1083 | movl %esp, %eax # pt_regs pointer | 1125 | movl %esp, %eax # pt_regs pointer |
1084 | 1126 | ||
@@ -1094,11 +1136,11 @@ ENTRY(debug) | |||
1094 | 1136 | ||
1095 | .Ldebug_from_sysenter_stack: | 1137 | .Ldebug_from_sysenter_stack: |
1096 | /* We're on the SYSENTER stack. Switch off. */ | 1138 | /* We're on the SYSENTER stack. Switch off. */ |
1097 | movl %esp, %ebp | 1139 | movl %esp, %ebx |
1098 | movl PER_CPU_VAR(cpu_current_top_of_stack), %esp | 1140 | movl PER_CPU_VAR(cpu_current_top_of_stack), %esp |
1099 | TRACE_IRQS_OFF | 1141 | TRACE_IRQS_OFF |
1100 | call do_debug | 1142 | call do_debug |
1101 | movl %ebp, %esp | 1143 | movl %ebx, %esp |
1102 | jmp ret_from_exception | 1144 | jmp ret_from_exception |
1103 | END(debug) | 1145 | END(debug) |
1104 | 1146 | ||
@@ -1116,11 +1158,12 @@ ENTRY(nmi) | |||
1116 | movl %ss, %eax | 1158 | movl %ss, %eax |
1117 | cmpw $__ESPFIX_SS, %ax | 1159 | cmpw $__ESPFIX_SS, %ax |
1118 | popl %eax | 1160 | popl %eax |
1119 | je nmi_espfix_stack | 1161 | je .Lnmi_espfix_stack |
1120 | #endif | 1162 | #endif |
1121 | 1163 | ||
1122 | pushl %eax # pt_regs->orig_ax | 1164 | pushl %eax # pt_regs->orig_ax |
1123 | SAVE_ALL | 1165 | SAVE_ALL |
1166 | ENCODE_FRAME_POINTER | ||
1124 | xorl %edx, %edx # zero error code | 1167 | xorl %edx, %edx # zero error code |
1125 | movl %esp, %eax # pt_regs pointer | 1168 | movl %esp, %eax # pt_regs pointer |
1126 | 1169 | ||
@@ -1132,21 +1175,21 @@ ENTRY(nmi) | |||
1132 | 1175 | ||
1133 | /* Not on SYSENTER stack. */ | 1176 | /* Not on SYSENTER stack. */ |
1134 | call do_nmi | 1177 | call do_nmi |
1135 | jmp restore_all_notrace | 1178 | jmp .Lrestore_all_notrace |
1136 | 1179 | ||
1137 | .Lnmi_from_sysenter_stack: | 1180 | .Lnmi_from_sysenter_stack: |
1138 | /* | 1181 | /* |
1139 | * We're on the SYSENTER stack. Switch off. No one (not even debug) | 1182 | * We're on the SYSENTER stack. Switch off. No one (not even debug) |
1140 | * is using the thread stack right now, so it's safe for us to use it. | 1183 | * is using the thread stack right now, so it's safe for us to use it. |
1141 | */ | 1184 | */ |
1142 | movl %esp, %ebp | 1185 | movl %esp, %ebx |
1143 | movl PER_CPU_VAR(cpu_current_top_of_stack), %esp | 1186 | movl PER_CPU_VAR(cpu_current_top_of_stack), %esp |
1144 | call do_nmi | 1187 | call do_nmi |
1145 | movl %ebp, %esp | 1188 | movl %ebx, %esp |
1146 | jmp restore_all_notrace | 1189 | jmp .Lrestore_all_notrace |
1147 | 1190 | ||
1148 | #ifdef CONFIG_X86_ESPFIX32 | 1191 | #ifdef CONFIG_X86_ESPFIX32 |
1149 | nmi_espfix_stack: | 1192 | .Lnmi_espfix_stack: |
1150 | /* | 1193 | /* |
1151 | * create the pointer to lss back | 1194 | * create the pointer to lss back |
1152 | */ | 1195 | */ |
@@ -1159,12 +1202,13 @@ nmi_espfix_stack: | |||
1159 | .endr | 1202 | .endr |
1160 | pushl %eax | 1203 | pushl %eax |
1161 | SAVE_ALL | 1204 | SAVE_ALL |
1205 | ENCODE_FRAME_POINTER | ||
1162 | FIXUP_ESPFIX_STACK # %eax == %esp | 1206 | FIXUP_ESPFIX_STACK # %eax == %esp |
1163 | xorl %edx, %edx # zero error code | 1207 | xorl %edx, %edx # zero error code |
1164 | call do_nmi | 1208 | call do_nmi |
1165 | RESTORE_REGS | 1209 | RESTORE_REGS |
1166 | lss 12+4(%esp), %esp # back to espfix stack | 1210 | lss 12+4(%esp), %esp # back to espfix stack |
1167 | jmp irq_return | 1211 | jmp .Lirq_return |
1168 | #endif | 1212 | #endif |
1169 | END(nmi) | 1213 | END(nmi) |
1170 | 1214 | ||
@@ -1172,6 +1216,7 @@ ENTRY(int3) | |||
1172 | ASM_CLAC | 1216 | ASM_CLAC |
1173 | pushl $-1 # mark this as an int | 1217 | pushl $-1 # mark this as an int |
1174 | SAVE_ALL | 1218 | SAVE_ALL |
1219 | ENCODE_FRAME_POINTER | ||
1175 | TRACE_IRQS_OFF | 1220 | TRACE_IRQS_OFF |
1176 | xorl %edx, %edx # zero error code | 1221 | xorl %edx, %edx # zero error code |
1177 | movl %esp, %eax # pt_regs pointer | 1222 | movl %esp, %eax # pt_regs pointer |
@@ -1181,14 +1226,14 @@ END(int3) | |||
1181 | 1226 | ||
1182 | ENTRY(general_protection) | 1227 | ENTRY(general_protection) |
1183 | pushl $do_general_protection | 1228 | pushl $do_general_protection |
1184 | jmp error_code | 1229 | jmp common_exception |
1185 | END(general_protection) | 1230 | END(general_protection) |
1186 | 1231 | ||
1187 | #ifdef CONFIG_KVM_GUEST | 1232 | #ifdef CONFIG_KVM_GUEST |
1188 | ENTRY(async_page_fault) | 1233 | ENTRY(async_page_fault) |
1189 | ASM_CLAC | 1234 | ASM_CLAC |
1190 | pushl $do_async_page_fault | 1235 | pushl $do_async_page_fault |
1191 | jmp error_code | 1236 | jmp common_exception |
1192 | END(async_page_fault) | 1237 | END(async_page_fault) |
1193 | #endif | 1238 | #endif |
1194 | 1239 | ||
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index ef766a358b37..5b219707c2f2 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S | |||
@@ -38,12 +38,6 @@ | |||
38 | #include <asm/export.h> | 38 | #include <asm/export.h> |
39 | #include <linux/err.h> | 39 | #include <linux/err.h> |
40 | 40 | ||
41 | /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ | ||
42 | #include <linux/elf-em.h> | ||
43 | #define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) | ||
44 | #define __AUDIT_ARCH_64BIT 0x80000000 | ||
45 | #define __AUDIT_ARCH_LE 0x40000000 | ||
46 | |||
47 | .code64 | 41 | .code64 |
48 | .section .entry.text, "ax" | 42 | .section .entry.text, "ax" |
49 | 43 | ||
@@ -469,6 +463,7 @@ END(irq_entries_start) | |||
469 | ALLOC_PT_GPREGS_ON_STACK | 463 | ALLOC_PT_GPREGS_ON_STACK |
470 | SAVE_C_REGS | 464 | SAVE_C_REGS |
471 | SAVE_EXTRA_REGS | 465 | SAVE_EXTRA_REGS |
466 | ENCODE_FRAME_POINTER | ||
472 | 467 | ||
473 | testb $3, CS(%rsp) | 468 | testb $3, CS(%rsp) |
474 | jz 1f | 469 | jz 1f |
@@ -985,6 +980,7 @@ ENTRY(xen_failsafe_callback) | |||
985 | ALLOC_PT_GPREGS_ON_STACK | 980 | ALLOC_PT_GPREGS_ON_STACK |
986 | SAVE_C_REGS | 981 | SAVE_C_REGS |
987 | SAVE_EXTRA_REGS | 982 | SAVE_EXTRA_REGS |
983 | ENCODE_FRAME_POINTER | ||
988 | jmp error_exit | 984 | jmp error_exit |
989 | END(xen_failsafe_callback) | 985 | END(xen_failsafe_callback) |
990 | 986 | ||
@@ -1028,6 +1024,7 @@ ENTRY(paranoid_entry) | |||
1028 | cld | 1024 | cld |
1029 | SAVE_C_REGS 8 | 1025 | SAVE_C_REGS 8 |
1030 | SAVE_EXTRA_REGS 8 | 1026 | SAVE_EXTRA_REGS 8 |
1027 | ENCODE_FRAME_POINTER 8 | ||
1031 | movl $1, %ebx | 1028 | movl $1, %ebx |
1032 | movl $MSR_GS_BASE, %ecx | 1029 | movl $MSR_GS_BASE, %ecx |
1033 | rdmsr | 1030 | rdmsr |
@@ -1075,6 +1072,7 @@ ENTRY(error_entry) | |||
1075 | cld | 1072 | cld |
1076 | SAVE_C_REGS 8 | 1073 | SAVE_C_REGS 8 |
1077 | SAVE_EXTRA_REGS 8 | 1074 | SAVE_EXTRA_REGS 8 |
1075 | ENCODE_FRAME_POINTER 8 | ||
1078 | xorl %ebx, %ebx | 1076 | xorl %ebx, %ebx |
1079 | testb $3, CS+8(%rsp) | 1077 | testb $3, CS+8(%rsp) |
1080 | jz .Lerror_kernelspace | 1078 | jz .Lerror_kernelspace |
@@ -1257,6 +1255,7 @@ ENTRY(nmi) | |||
1257 | pushq %r13 /* pt_regs->r13 */ | 1255 | pushq %r13 /* pt_regs->r13 */ |
1258 | pushq %r14 /* pt_regs->r14 */ | 1256 | pushq %r14 /* pt_regs->r14 */ |
1259 | pushq %r15 /* pt_regs->r15 */ | 1257 | pushq %r15 /* pt_regs->r15 */ |
1258 | ENCODE_FRAME_POINTER | ||
1260 | 1259 | ||
1261 | /* | 1260 | /* |
1262 | * At this point we no longer need to worry about stack damage | 1261 | * At this point we no longer need to worry about stack damage |
@@ -1270,11 +1269,10 @@ ENTRY(nmi) | |||
1270 | 1269 | ||
1271 | /* | 1270 | /* |
1272 | * Return back to user mode. We must *not* do the normal exit | 1271 | * Return back to user mode. We must *not* do the normal exit |
1273 | * work, because we don't want to enable interrupts. Fortunately, | 1272 | * work, because we don't want to enable interrupts. |
1274 | * do_nmi doesn't modify pt_regs. | ||
1275 | */ | 1273 | */ |
1276 | SWAPGS | 1274 | SWAPGS |
1277 | jmp restore_c_regs_and_iret | 1275 | jmp restore_regs_and_iret |
1278 | 1276 | ||
1279 | .Lnmi_from_kernel: | 1277 | .Lnmi_from_kernel: |
1280 | /* | 1278 | /* |
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 23c881caabd1..e739002427ed 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c | |||
@@ -161,8 +161,6 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr) | |||
161 | } | 161 | } |
162 | 162 | ||
163 | text_start = addr - image->sym_vvar_start; | 163 | text_start = addr - image->sym_vvar_start; |
164 | current->mm->context.vdso = (void __user *)text_start; | ||
165 | current->mm->context.vdso_image = image; | ||
166 | 164 | ||
167 | /* | 165 | /* |
168 | * MAYWRITE to allow gdb to COW and set breakpoints | 166 | * MAYWRITE to allow gdb to COW and set breakpoints |
@@ -189,14 +187,12 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr) | |||
189 | if (IS_ERR(vma)) { | 187 | if (IS_ERR(vma)) { |
190 | ret = PTR_ERR(vma); | 188 | ret = PTR_ERR(vma); |
191 | do_munmap(mm, text_start, image->size); | 189 | do_munmap(mm, text_start, image->size); |
190 | } else { | ||
191 | current->mm->context.vdso = (void __user *)text_start; | ||
192 | current->mm->context.vdso_image = image; | ||
192 | } | 193 | } |
193 | 194 | ||
194 | up_fail: | 195 | up_fail: |
195 | if (ret) { | ||
196 | current->mm->context.vdso = NULL; | ||
197 | current->mm->context.vdso_image = NULL; | ||
198 | } | ||
199 | |||
200 | up_write(&mm->mmap_sem); | 196 | up_write(&mm->mmap_sem); |
201 | return ret; | 197 | return ret; |
202 | } | 198 | } |
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index c5047b8f777b..1c1b9fe705c8 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c | |||
@@ -36,13 +36,6 @@ static DEFINE_PER_CPU(struct pt, pt_ctx); | |||
36 | 36 | ||
37 | static struct pt_pmu pt_pmu; | 37 | static struct pt_pmu pt_pmu; |
38 | 38 | ||
39 | enum cpuid_regs { | ||
40 | CR_EAX = 0, | ||
41 | CR_ECX, | ||
42 | CR_EDX, | ||
43 | CR_EBX | ||
44 | }; | ||
45 | |||
46 | /* | 39 | /* |
47 | * Capabilities of Intel PT hardware, such as number of address bits or | 40 | * Capabilities of Intel PT hardware, such as number of address bits or |
48 | * supported output schemes, are cached and exported to userspace as "caps" | 41 | * supported output schemes, are cached and exported to userspace as "caps" |
@@ -64,21 +57,21 @@ static struct pt_cap_desc { | |||
64 | u8 reg; | 57 | u8 reg; |
65 | u32 mask; | 58 | u32 mask; |
66 | } pt_caps[] = { | 59 | } pt_caps[] = { |
67 | PT_CAP(max_subleaf, 0, CR_EAX, 0xffffffff), | 60 | PT_CAP(max_subleaf, 0, CPUID_EAX, 0xffffffff), |
68 | PT_CAP(cr3_filtering, 0, CR_EBX, BIT(0)), | 61 | PT_CAP(cr3_filtering, 0, CPUID_EBX, BIT(0)), |
69 | PT_CAP(psb_cyc, 0, CR_EBX, BIT(1)), | 62 | PT_CAP(psb_cyc, 0, CPUID_EBX, BIT(1)), |
70 | PT_CAP(ip_filtering, 0, CR_EBX, BIT(2)), | 63 | PT_CAP(ip_filtering, 0, CPUID_EBX, BIT(2)), |
71 | PT_CAP(mtc, 0, CR_EBX, BIT(3)), | 64 | PT_CAP(mtc, 0, CPUID_EBX, BIT(3)), |
72 | PT_CAP(ptwrite, 0, CR_EBX, BIT(4)), | 65 | PT_CAP(ptwrite, 0, CPUID_EBX, BIT(4)), |
73 | PT_CAP(power_event_trace, 0, CR_EBX, BIT(5)), | 66 | PT_CAP(power_event_trace, 0, CPUID_EBX, BIT(5)), |
74 | PT_CAP(topa_output, 0, CR_ECX, BIT(0)), | 67 | PT_CAP(topa_output, 0, CPUID_ECX, BIT(0)), |
75 | PT_CAP(topa_multiple_entries, 0, CR_ECX, BIT(1)), | 68 | PT_CAP(topa_multiple_entries, 0, CPUID_ECX, BIT(1)), |
76 | PT_CAP(single_range_output, 0, CR_ECX, BIT(2)), | 69 | PT_CAP(single_range_output, 0, CPUID_ECX, BIT(2)), |
77 | PT_CAP(payloads_lip, 0, CR_ECX, BIT(31)), | 70 | PT_CAP(payloads_lip, 0, CPUID_ECX, BIT(31)), |
78 | PT_CAP(num_address_ranges, 1, CR_EAX, 0x3), | 71 | PT_CAP(num_address_ranges, 1, CPUID_EAX, 0x3), |
79 | PT_CAP(mtc_periods, 1, CR_EAX, 0xffff0000), | 72 | PT_CAP(mtc_periods, 1, CPUID_EAX, 0xffff0000), |
80 | PT_CAP(cycle_thresholds, 1, CR_EBX, 0xffff), | 73 | PT_CAP(cycle_thresholds, 1, CPUID_EBX, 0xffff), |
81 | PT_CAP(psb_periods, 1, CR_EBX, 0xffff0000), | 74 | PT_CAP(psb_periods, 1, CPUID_EBX, 0xffff0000), |
82 | }; | 75 | }; |
83 | 76 | ||
84 | static u32 pt_cap_get(enum pt_capabilities cap) | 77 | static u32 pt_cap_get(enum pt_capabilities cap) |
@@ -213,10 +206,10 @@ static int __init pt_pmu_hw_init(void) | |||
213 | 206 | ||
214 | for (i = 0; i < PT_CPUID_LEAVES; i++) { | 207 | for (i = 0; i < PT_CPUID_LEAVES; i++) { |
215 | cpuid_count(20, i, | 208 | cpuid_count(20, i, |
216 | &pt_pmu.caps[CR_EAX + i*PT_CPUID_REGS_NUM], | 209 | &pt_pmu.caps[CPUID_EAX + i*PT_CPUID_REGS_NUM], |
217 | &pt_pmu.caps[CR_EBX + i*PT_CPUID_REGS_NUM], | 210 | &pt_pmu.caps[CPUID_EBX + i*PT_CPUID_REGS_NUM], |
218 | &pt_pmu.caps[CR_ECX + i*PT_CPUID_REGS_NUM], | 211 | &pt_pmu.caps[CPUID_ECX + i*PT_CPUID_REGS_NUM], |
219 | &pt_pmu.caps[CR_EDX + i*PT_CPUID_REGS_NUM]); | 212 | &pt_pmu.caps[CPUID_EDX + i*PT_CPUID_REGS_NUM]); |
220 | } | 213 | } |
221 | 214 | ||
222 | ret = -ENOMEM; | 215 | ret = -ENOMEM; |
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index d625b651e526..4dba597c5807 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h | |||
@@ -227,6 +227,7 @@ | |||
227 | #define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */ | 227 | #define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */ |
228 | #define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */ | 228 | #define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */ |
229 | #define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */ | 229 | #define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */ |
230 | #define X86_FEATURE_AVX512IFMA ( 9*32+21) /* AVX-512 Integer Fused Multiply-Add instructions */ | ||
230 | #define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */ | 231 | #define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */ |
231 | #define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */ | 232 | #define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */ |
232 | #define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */ | 233 | #define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */ |
@@ -280,8 +281,10 @@ | |||
280 | #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ | 281 | #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ |
281 | 282 | ||
282 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ | 283 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ |
284 | #define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/ | ||
283 | #define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */ | 285 | #define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */ |
284 | #define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */ | 286 | #define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */ |
287 | #define X86_FEATURE_RDPID (16*32+ 22) /* RDPID instruction */ | ||
285 | 288 | ||
286 | /* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */ | 289 | /* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */ |
287 | #define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */ | 290 | #define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */ |
diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h index d31881188431..29a594a3b82a 100644 --- a/arch/x86/include/asm/kdebug.h +++ b/arch/x86/include/asm/kdebug.h | |||
@@ -21,7 +21,6 @@ enum die_val { | |||
21 | DIE_NMIUNKNOWN, | 21 | DIE_NMIUNKNOWN, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | extern void printk_address(unsigned long address); | ||
25 | extern void die(const char *, struct pt_regs *,long); | 24 | extern void die(const char *, struct pt_regs *,long); |
26 | extern int __must_check __die(const char *, struct pt_regs *, long); | 25 | extern int __must_check __die(const char *, struct pt_regs *, long); |
27 | extern void show_stack_regs(struct pt_regs *regs); | 26 | extern void show_stack_regs(struct pt_regs *regs); |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index c84605bb2a15..1f6a92903b09 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -137,6 +137,17 @@ struct cpuinfo_x86 { | |||
137 | u32 microcode; | 137 | u32 microcode; |
138 | }; | 138 | }; |
139 | 139 | ||
140 | struct cpuid_regs { | ||
141 | u32 eax, ebx, ecx, edx; | ||
142 | }; | ||
143 | |||
144 | enum cpuid_regs_idx { | ||
145 | CPUID_EAX = 0, | ||
146 | CPUID_EBX, | ||
147 | CPUID_ECX, | ||
148 | CPUID_EDX, | ||
149 | }; | ||
150 | |||
140 | #define X86_VENDOR_INTEL 0 | 151 | #define X86_VENDOR_INTEL 0 |
141 | #define X86_VENDOR_CYRIX 1 | 152 | #define X86_VENDOR_CYRIX 1 |
142 | #define X86_VENDOR_AMD 2 | 153 | #define X86_VENDOR_AMD 2 |
@@ -178,6 +189,9 @@ extern void identify_secondary_cpu(struct cpuinfo_x86 *); | |||
178 | extern void print_cpu_info(struct cpuinfo_x86 *); | 189 | extern void print_cpu_info(struct cpuinfo_x86 *); |
179 | void print_cpu_msr(struct cpuinfo_x86 *); | 190 | void print_cpu_msr(struct cpuinfo_x86 *); |
180 | extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); | 191 | extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); |
192 | extern u32 get_scattered_cpuid_leaf(unsigned int level, | ||
193 | unsigned int sub_leaf, | ||
194 | enum cpuid_regs_idx reg); | ||
181 | extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); | 195 | extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); |
182 | extern void init_amd_cacheinfo(struct cpuinfo_x86 *c); | 196 | extern void init_amd_cacheinfo(struct cpuinfo_x86 *c); |
183 | 197 | ||
diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h index 37f2e0b377ad..a3269c897ec5 100644 --- a/arch/x86/include/asm/stacktrace.h +++ b/arch/x86/include/asm/stacktrace.h | |||
@@ -30,8 +30,7 @@ bool in_task_stack(unsigned long *stack, struct task_struct *task, | |||
30 | int get_stack_info(unsigned long *stack, struct task_struct *task, | 30 | int get_stack_info(unsigned long *stack, struct task_struct *task, |
31 | struct stack_info *info, unsigned long *visit_mask); | 31 | struct stack_info *info, unsigned long *visit_mask); |
32 | 32 | ||
33 | void stack_type_str(enum stack_type type, const char **begin, | 33 | const char *stack_type_name(enum stack_type type); |
34 | const char **end); | ||
35 | 34 | ||
36 | static inline bool on_stack(struct stack_info *info, void *addr, size_t len) | 35 | static inline bool on_stack(struct stack_info *info, void *addr, size_t len) |
37 | { | 36 | { |
@@ -43,8 +42,6 @@ static inline bool on_stack(struct stack_info *info, void *addr, size_t len) | |||
43 | addr + len > begin && addr + len <= end); | 42 | addr + len > begin && addr + len <= end); |
44 | } | 43 | } |
45 | 44 | ||
46 | extern int kstack_depth_to_print; | ||
47 | |||
48 | #ifdef CONFIG_X86_32 | 45 | #ifdef CONFIG_X86_32 |
49 | #define STACKSLOTS_PER_LINE 8 | 46 | #define STACKSLOTS_PER_LINE 8 |
50 | #else | 47 | #else |
@@ -86,9 +83,6 @@ get_stack_pointer(struct task_struct *task, struct pt_regs *regs) | |||
86 | void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | 83 | void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, |
87 | unsigned long *stack, char *log_lvl); | 84 | unsigned long *stack, char *log_lvl); |
88 | 85 | ||
89 | void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | ||
90 | unsigned long *sp, char *log_lvl); | ||
91 | |||
92 | extern unsigned int code_bytes; | 86 | extern unsigned int code_bytes; |
93 | 87 | ||
94 | /* The form of the top of the frame on the stack */ | 88 | /* The form of the top of the frame on the stack */ |
diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h index 46de9ac4b990..c5a7f3a930dd 100644 --- a/arch/x86/include/asm/unwind.h +++ b/arch/x86/include/asm/unwind.h | |||
@@ -13,6 +13,7 @@ struct unwind_state { | |||
13 | int graph_idx; | 13 | int graph_idx; |
14 | #ifdef CONFIG_FRAME_POINTER | 14 | #ifdef CONFIG_FRAME_POINTER |
15 | unsigned long *bp; | 15 | unsigned long *bp; |
16 | struct pt_regs *regs; | ||
16 | #else | 17 | #else |
17 | unsigned long *sp; | 18 | unsigned long *sp; |
18 | #endif | 19 | #endif |
@@ -47,7 +48,15 @@ unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) | |||
47 | if (unwind_done(state)) | 48 | if (unwind_done(state)) |
48 | return NULL; | 49 | return NULL; |
49 | 50 | ||
50 | return state->bp + 1; | 51 | return state->regs ? &state->regs->ip : state->bp + 1; |
52 | } | ||
53 | |||
54 | static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) | ||
55 | { | ||
56 | if (unwind_done(state)) | ||
57 | return NULL; | ||
58 | |||
59 | return state->regs; | ||
51 | } | 60 | } |
52 | 61 | ||
53 | #else /* !CONFIG_FRAME_POINTER */ | 62 | #else /* !CONFIG_FRAME_POINTER */ |
@@ -58,6 +67,11 @@ unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) | |||
58 | return NULL; | 67 | return NULL; |
59 | } | 68 | } |
60 | 69 | ||
70 | static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) | ||
71 | { | ||
72 | return NULL; | ||
73 | } | ||
74 | |||
61 | #endif /* CONFIG_FRAME_POINTER */ | 75 | #endif /* CONFIG_FRAME_POINTER */ |
62 | 76 | ||
63 | #endif /* _ASM_X86_UNWIND_H */ | 77 | #endif /* _ASM_X86_UNWIND_H */ |
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h index e728699db774..3a01996db58f 100644 --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h | |||
@@ -89,8 +89,13 @@ static inline unsigned int __getcpu(void) | |||
89 | * works on all CPUs. This is volatile so that it orders | 89 | * works on all CPUs. This is volatile so that it orders |
90 | * correctly wrt barrier() and to keep gcc from cleverly | 90 | * correctly wrt barrier() and to keep gcc from cleverly |
91 | * hoisting it out of the calling function. | 91 | * hoisting it out of the calling function. |
92 | * | ||
93 | * If RDPID is available, use it. | ||
92 | */ | 94 | */ |
93 | asm volatile ("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); | 95 | alternative_io ("lsl %[p],%[seg]", |
96 | ".byte 0xf3,0x0f,0xc7,0xf8", /* RDPID %eax/rax */ | ||
97 | X86_FEATURE_RDPID, | ||
98 | [p] "=a" (p), [seg] "r" (__PER_CPU_SEG)); | ||
94 | 99 | ||
95 | return p; | 100 | return p; |
96 | } | 101 | } |
diff --git a/arch/x86/include/uapi/asm/prctl.h b/arch/x86/include/uapi/asm/prctl.h index ae135de547f5..835aa51c7f6e 100644 --- a/arch/x86/include/uapi/asm/prctl.h +++ b/arch/x86/include/uapi/asm/prctl.h | |||
@@ -6,10 +6,8 @@ | |||
6 | #define ARCH_GET_FS 0x1003 | 6 | #define ARCH_GET_FS 0x1003 |
7 | #define ARCH_GET_GS 0x1004 | 7 | #define ARCH_GET_GS 0x1004 |
8 | 8 | ||
9 | #ifdef CONFIG_CHECKPOINT_RESTORE | 9 | #define ARCH_MAP_VDSO_X32 0x2001 |
10 | # define ARCH_MAP_VDSO_X32 0x2001 | 10 | #define ARCH_MAP_VDSO_32 0x2002 |
11 | # define ARCH_MAP_VDSO_32 0x2002 | 11 | #define ARCH_MAP_VDSO_64 0x2003 |
12 | # define ARCH_MAP_VDSO_64 0x2003 | ||
13 | #endif | ||
14 | 12 | ||
15 | #endif /* _ASM_X86_PRCTL_H */ | 13 | #endif /* _ASM_X86_PRCTL_H */ |
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 1db8dc490b66..d1316f9c8329 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c | |||
@@ -17,11 +17,17 @@ struct cpuid_bit { | |||
17 | u32 sub_leaf; | 17 | u32 sub_leaf; |
18 | }; | 18 | }; |
19 | 19 | ||
20 | enum cpuid_regs { | 20 | /* Please keep the leaf sorted by cpuid_bit.level for faster search. */ |
21 | CR_EAX = 0, | 21 | static const struct cpuid_bit cpuid_bits[] = { |
22 | CR_ECX, | 22 | { X86_FEATURE_APERFMPERF, CPUID_ECX, 0, 0x00000006, 0 }, |
23 | CR_EDX, | 23 | { X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 }, |
24 | CR_EBX | 24 | { X86_FEATURE_INTEL_PT, CPUID_EBX, 25, 0x00000007, 0 }, |
25 | { X86_FEATURE_AVX512_4VNNIW, CPUID_EDX, 2, 0x00000007, 0 }, | ||
26 | { X86_FEATURE_AVX512_4FMAPS, CPUID_EDX, 3, 0x00000007, 0 }, | ||
27 | { X86_FEATURE_HW_PSTATE, CPUID_EDX, 7, 0x80000007, 0 }, | ||
28 | { X86_FEATURE_CPB, CPUID_EDX, 9, 0x80000007, 0 }, | ||
29 | { X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 }, | ||
30 | { 0, 0, 0, 0, 0 } | ||
25 | }; | 31 | }; |
26 | 32 | ||
27 | void init_scattered_cpuid_features(struct cpuinfo_x86 *c) | 33 | void init_scattered_cpuid_features(struct cpuinfo_x86 *c) |
@@ -30,18 +36,6 @@ void init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |||
30 | u32 regs[4]; | 36 | u32 regs[4]; |
31 | const struct cpuid_bit *cb; | 37 | const struct cpuid_bit *cb; |
32 | 38 | ||
33 | static const struct cpuid_bit cpuid_bits[] = { | ||
34 | { X86_FEATURE_INTEL_PT, CR_EBX,25, 0x00000007, 0 }, | ||
35 | { X86_FEATURE_AVX512_4VNNIW, CR_EDX, 2, 0x00000007, 0 }, | ||
36 | { X86_FEATURE_AVX512_4FMAPS, CR_EDX, 3, 0x00000007, 0 }, | ||
37 | { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006, 0 }, | ||
38 | { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 }, | ||
39 | { X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 }, | ||
40 | { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 }, | ||
41 | { X86_FEATURE_PROC_FEEDBACK, CR_EDX,11, 0x80000007, 0 }, | ||
42 | { 0, 0, 0, 0, 0 } | ||
43 | }; | ||
44 | |||
45 | for (cb = cpuid_bits; cb->feature; cb++) { | 39 | for (cb = cpuid_bits; cb->feature; cb++) { |
46 | 40 | ||
47 | /* Verify that the level is valid */ | 41 | /* Verify that the level is valid */ |
@@ -50,10 +44,35 @@ void init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |||
50 | max_level > (cb->level | 0xffff)) | 44 | max_level > (cb->level | 0xffff)) |
51 | continue; | 45 | continue; |
52 | 46 | ||
53 | cpuid_count(cb->level, cb->sub_leaf, ®s[CR_EAX], | 47 | cpuid_count(cb->level, cb->sub_leaf, ®s[CPUID_EAX], |
54 | ®s[CR_EBX], ®s[CR_ECX], ®s[CR_EDX]); | 48 | ®s[CPUID_EBX], ®s[CPUID_ECX], |
49 | ®s[CPUID_EDX]); | ||
55 | 50 | ||
56 | if (regs[cb->reg] & (1 << cb->bit)) | 51 | if (regs[cb->reg] & (1 << cb->bit)) |
57 | set_cpu_cap(c, cb->feature); | 52 | set_cpu_cap(c, cb->feature); |
58 | } | 53 | } |
59 | } | 54 | } |
55 | |||
56 | u32 get_scattered_cpuid_leaf(unsigned int level, unsigned int sub_leaf, | ||
57 | enum cpuid_regs_idx reg) | ||
58 | { | ||
59 | const struct cpuid_bit *cb; | ||
60 | u32 cpuid_val = 0; | ||
61 | |||
62 | for (cb = cpuid_bits; cb->feature; cb++) { | ||
63 | |||
64 | if (level > cb->level) | ||
65 | continue; | ||
66 | |||
67 | if (level < cb->level) | ||
68 | break; | ||
69 | |||
70 | if (reg == cb->reg && sub_leaf == cb->sub_leaf) { | ||
71 | if (cpu_has(&boot_cpu_data, cb->feature)) | ||
72 | cpuid_val |= BIT(cb->bit); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | return cpuid_val; | ||
77 | } | ||
78 | EXPORT_SYMBOL_GPL(get_scattered_cpuid_leaf); | ||
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 2836de390f95..9095c80723d6 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c | |||
@@ -46,10 +46,6 @@ | |||
46 | 46 | ||
47 | static struct class *cpuid_class; | 47 | static struct class *cpuid_class; |
48 | 48 | ||
49 | struct cpuid_regs { | ||
50 | u32 eax, ebx, ecx, edx; | ||
51 | }; | ||
52 | |||
53 | static void cpuid_smp_cpuid(void *cmd_block) | 49 | static void cpuid_smp_cpuid(void *cmd_block) |
54 | { | 50 | { |
55 | struct cpuid_regs *cmd = (struct cpuid_regs *)cmd_block; | 51 | struct cpuid_regs *cmd = (struct cpuid_regs *)cmd_block; |
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 85f854b98a9d..0cfd01d2754c 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
@@ -22,7 +22,6 @@ | |||
22 | int panic_on_unrecovered_nmi; | 22 | int panic_on_unrecovered_nmi; |
23 | int panic_on_io_nmi; | 23 | int panic_on_io_nmi; |
24 | unsigned int code_bytes = 64; | 24 | unsigned int code_bytes = 64; |
25 | int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE; | ||
26 | static int die_counter; | 25 | static int die_counter; |
27 | 26 | ||
28 | bool in_task_stack(unsigned long *stack, struct task_struct *task, | 27 | bool in_task_stack(unsigned long *stack, struct task_struct *task, |
@@ -46,14 +45,7 @@ static void printk_stack_address(unsigned long address, int reliable, | |||
46 | char *log_lvl) | 45 | char *log_lvl) |
47 | { | 46 | { |
48 | touch_nmi_watchdog(); | 47 | touch_nmi_watchdog(); |
49 | printk("%s [<%p>] %s%pB\n", | 48 | printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address); |
50 | log_lvl, (void *)address, reliable ? "" : "? ", | ||
51 | (void *)address); | ||
52 | } | ||
53 | |||
54 | void printk_address(unsigned long address) | ||
55 | { | ||
56 | pr_cont(" [<%p>] %pS\n", (void *)address, (void *)address); | ||
57 | } | 49 | } |
58 | 50 | ||
59 | void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | 51 | void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, |
@@ -67,6 +59,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
67 | printk("%sCall Trace:\n", log_lvl); | 59 | printk("%sCall Trace:\n", log_lvl); |
68 | 60 | ||
69 | unwind_start(&state, task, regs, stack); | 61 | unwind_start(&state, task, regs, stack); |
62 | stack = stack ? : get_stack_pointer(task, regs); | ||
70 | 63 | ||
71 | /* | 64 | /* |
72 | * Iterate through the stacks, starting with the current stack pointer. | 65 | * Iterate through the stacks, starting with the current stack pointer. |
@@ -82,8 +75,8 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
82 | * - softirq stack | 75 | * - softirq stack |
83 | * - hardirq stack | 76 | * - hardirq stack |
84 | */ | 77 | */ |
85 | for (; stack; stack = stack_info.next_sp) { | 78 | for (regs = NULL; stack; stack = stack_info.next_sp) { |
86 | const char *str_begin, *str_end; | 79 | const char *stack_name; |
87 | 80 | ||
88 | /* | 81 | /* |
89 | * If we overflowed the task stack into a guard page, jump back | 82 | * If we overflowed the task stack into a guard page, jump back |
@@ -95,9 +88,9 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
95 | if (get_stack_info(stack, task, &stack_info, &visit_mask)) | 88 | if (get_stack_info(stack, task, &stack_info, &visit_mask)) |
96 | break; | 89 | break; |
97 | 90 | ||
98 | stack_type_str(stack_info.type, &str_begin, &str_end); | 91 | stack_name = stack_type_name(stack_info.type); |
99 | if (str_begin) | 92 | if (stack_name) |
100 | printk("%s <%s> ", log_lvl, str_begin); | 93 | printk("%s <%s>\n", log_lvl, stack_name); |
101 | 94 | ||
102 | /* | 95 | /* |
103 | * Scan the stack, printing any text addresses we find. At the | 96 | * Scan the stack, printing any text addresses we find. At the |
@@ -119,6 +112,15 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
119 | if (!__kernel_text_address(addr)) | 112 | if (!__kernel_text_address(addr)) |
120 | continue; | 113 | continue; |
121 | 114 | ||
115 | /* | ||
116 | * Don't print regs->ip again if it was already printed | ||
117 | * by __show_regs() below. | ||
118 | */ | ||
119 | if (regs && stack == ®s->ip) { | ||
120 | unwind_next_frame(&state); | ||
121 | continue; | ||
122 | } | ||
123 | |||
122 | if (stack == ret_addr_p) | 124 | if (stack == ret_addr_p) |
123 | reliable = 1; | 125 | reliable = 1; |
124 | 126 | ||
@@ -146,10 +148,15 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
146 | * of the addresses will just be printed as unreliable. | 148 | * of the addresses will just be printed as unreliable. |
147 | */ | 149 | */ |
148 | unwind_next_frame(&state); | 150 | unwind_next_frame(&state); |
151 | |||
152 | /* if the frame has entry regs, print them */ | ||
153 | regs = unwind_get_entry_regs(&state); | ||
154 | if (regs) | ||
155 | __show_regs(regs, 0); | ||
149 | } | 156 | } |
150 | 157 | ||
151 | if (str_end) | 158 | if (stack_name) |
152 | printk("%s <%s> ", log_lvl, str_end); | 159 | printk("%s </%s>\n", log_lvl, stack_name); |
153 | } | 160 | } |
154 | } | 161 | } |
155 | 162 | ||
@@ -164,12 +171,12 @@ void show_stack(struct task_struct *task, unsigned long *sp) | |||
164 | if (!sp && task == current) | 171 | if (!sp && task == current) |
165 | sp = get_stack_pointer(current, NULL); | 172 | sp = get_stack_pointer(current, NULL); |
166 | 173 | ||
167 | show_stack_log_lvl(task, NULL, sp, ""); | 174 | show_trace_log_lvl(task, NULL, sp, KERN_DEFAULT); |
168 | } | 175 | } |
169 | 176 | ||
170 | void show_stack_regs(struct pt_regs *regs) | 177 | void show_stack_regs(struct pt_regs *regs) |
171 | { | 178 | { |
172 | show_stack_log_lvl(current, regs, NULL, ""); | 179 | show_trace_log_lvl(current, regs, NULL, KERN_DEFAULT); |
173 | } | 180 | } |
174 | 181 | ||
175 | static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; | 182 | static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; |
@@ -261,14 +268,11 @@ int __die(const char *str, struct pt_regs *regs, long err) | |||
261 | sp = kernel_stack_pointer(regs); | 268 | sp = kernel_stack_pointer(regs); |
262 | savesegment(ss, ss); | 269 | savesegment(ss, ss); |
263 | } | 270 | } |
264 | printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip); | 271 | printk(KERN_EMERG "EIP: %pS SS:ESP: %04x:%08lx\n", |
265 | print_symbol("%s", regs->ip); | 272 | (void *)regs->ip, ss, sp); |
266 | printk(" SS:ESP %04x:%08lx\n", ss, sp); | ||
267 | #else | 273 | #else |
268 | /* Executive summary in case the oops scrolled away */ | 274 | /* Executive summary in case the oops scrolled away */ |
269 | printk(KERN_ALERT "RIP "); | 275 | printk(KERN_ALERT "RIP: %pS RSP: %016lx\n", (void *)regs->ip, regs->sp); |
270 | printk_address(regs->ip); | ||
271 | printk(" RSP <%016lx>\n", regs->sp); | ||
272 | #endif | 276 | #endif |
273 | return 0; | 277 | return 0; |
274 | } | 278 | } |
@@ -291,22 +295,6 @@ void die(const char *str, struct pt_regs *regs, long err) | |||
291 | oops_end(flags, regs, sig); | 295 | oops_end(flags, regs, sig); |
292 | } | 296 | } |
293 | 297 | ||
294 | static int __init kstack_setup(char *s) | ||
295 | { | ||
296 | ssize_t ret; | ||
297 | unsigned long val; | ||
298 | |||
299 | if (!s) | ||
300 | return -EINVAL; | ||
301 | |||
302 | ret = kstrtoul(s, 0, &val); | ||
303 | if (ret) | ||
304 | return ret; | ||
305 | kstack_depth_to_print = val; | ||
306 | return 0; | ||
307 | } | ||
308 | early_param("kstack", kstack_setup); | ||
309 | |||
310 | static int __init code_bytes_setup(char *s) | 298 | static int __init code_bytes_setup(char *s) |
311 | { | 299 | { |
312 | ssize_t ret; | 300 | ssize_t ret; |
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index 06eb322b5f9f..bb3b5b9a6899 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
@@ -16,18 +16,15 @@ | |||
16 | 16 | ||
17 | #include <asm/stacktrace.h> | 17 | #include <asm/stacktrace.h> |
18 | 18 | ||
19 | void stack_type_str(enum stack_type type, const char **begin, const char **end) | 19 | const char *stack_type_name(enum stack_type type) |
20 | { | 20 | { |
21 | switch (type) { | 21 | if (type == STACK_TYPE_IRQ) |
22 | case STACK_TYPE_IRQ: | 22 | return "IRQ"; |
23 | case STACK_TYPE_SOFTIRQ: | 23 | |
24 | *begin = "IRQ"; | 24 | if (type == STACK_TYPE_SOFTIRQ) |
25 | *end = "EOI"; | 25 | return "SOFTIRQ"; |
26 | break; | 26 | |
27 | default: | 27 | return NULL; |
28 | *begin = NULL; | ||
29 | *end = NULL; | ||
30 | } | ||
31 | } | 28 | } |
32 | 29 | ||
33 | static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info) | 30 | static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info) |
@@ -109,8 +106,10 @@ recursion_check: | |||
109 | * just break out and report an unknown stack type. | 106 | * just break out and report an unknown stack type. |
110 | */ | 107 | */ |
111 | if (visit_mask) { | 108 | if (visit_mask) { |
112 | if (*visit_mask & (1UL << info->type)) | 109 | if (*visit_mask & (1UL << info->type)) { |
110 | printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type); | ||
113 | goto unknown; | 111 | goto unknown; |
112 | } | ||
114 | *visit_mask |= 1UL << info->type; | 113 | *visit_mask |= 1UL << info->type; |
115 | } | 114 | } |
116 | 115 | ||
@@ -121,36 +120,6 @@ unknown: | |||
121 | return -EINVAL; | 120 | return -EINVAL; |
122 | } | 121 | } |
123 | 122 | ||
124 | void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | ||
125 | unsigned long *sp, char *log_lvl) | ||
126 | { | ||
127 | unsigned long *stack; | ||
128 | int i; | ||
129 | |||
130 | if (!try_get_task_stack(task)) | ||
131 | return; | ||
132 | |||
133 | sp = sp ? : get_stack_pointer(task, regs); | ||
134 | |||
135 | stack = sp; | ||
136 | for (i = 0; i < kstack_depth_to_print; i++) { | ||
137 | if (kstack_end(stack)) | ||
138 | break; | ||
139 | if ((i % STACKSLOTS_PER_LINE) == 0) { | ||
140 | if (i != 0) | ||
141 | pr_cont("\n"); | ||
142 | printk("%s %08lx", log_lvl, *stack++); | ||
143 | } else | ||
144 | pr_cont(" %08lx", *stack++); | ||
145 | touch_nmi_watchdog(); | ||
146 | } | ||
147 | pr_cont("\n"); | ||
148 | show_trace_log_lvl(task, regs, sp, log_lvl); | ||
149 | |||
150 | put_task_stack(task); | ||
151 | } | ||
152 | |||
153 | |||
154 | void show_regs(struct pt_regs *regs) | 123 | void show_regs(struct pt_regs *regs) |
155 | { | 124 | { |
156 | int i; | 125 | int i; |
@@ -168,8 +137,7 @@ void show_regs(struct pt_regs *regs) | |||
168 | unsigned char c; | 137 | unsigned char c; |
169 | u8 *ip; | 138 | u8 *ip; |
170 | 139 | ||
171 | pr_emerg("Stack:\n"); | 140 | show_trace_log_lvl(current, regs, NULL, KERN_EMERG); |
172 | show_stack_log_lvl(current, regs, NULL, KERN_EMERG); | ||
173 | 141 | ||
174 | pr_emerg("Code:"); | 142 | pr_emerg("Code:"); |
175 | 143 | ||
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 36cf1a498227..fac189efcc34 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -28,23 +28,17 @@ static unsigned long exception_stack_sizes[N_EXCEPTION_STACKS] = { | |||
28 | [DEBUG_STACK - 1] = DEBUG_STKSZ | 28 | [DEBUG_STACK - 1] = DEBUG_STKSZ |
29 | }; | 29 | }; |
30 | 30 | ||
31 | void stack_type_str(enum stack_type type, const char **begin, const char **end) | 31 | const char *stack_type_name(enum stack_type type) |
32 | { | 32 | { |
33 | BUILD_BUG_ON(N_EXCEPTION_STACKS != 4); | 33 | BUILD_BUG_ON(N_EXCEPTION_STACKS != 4); |
34 | 34 | ||
35 | switch (type) { | 35 | if (type == STACK_TYPE_IRQ) |
36 | case STACK_TYPE_IRQ: | 36 | return "IRQ"; |
37 | *begin = "IRQ"; | 37 | |
38 | *end = "EOI"; | 38 | if (type >= STACK_TYPE_EXCEPTION && type <= STACK_TYPE_EXCEPTION_LAST) |
39 | break; | 39 | return exception_stack_names[type - STACK_TYPE_EXCEPTION]; |
40 | case STACK_TYPE_EXCEPTION ... STACK_TYPE_EXCEPTION_LAST: | 40 | |
41 | *begin = exception_stack_names[type - STACK_TYPE_EXCEPTION]; | 41 | return NULL; |
42 | *end = "EOE"; | ||
43 | break; | ||
44 | default: | ||
45 | *begin = NULL; | ||
46 | *end = NULL; | ||
47 | } | ||
48 | } | 42 | } |
49 | 43 | ||
50 | static bool in_exception_stack(unsigned long *stack, struct stack_info *info) | 44 | static bool in_exception_stack(unsigned long *stack, struct stack_info *info) |
@@ -128,8 +122,10 @@ recursion_check: | |||
128 | * just break out and report an unknown stack type. | 122 | * just break out and report an unknown stack type. |
129 | */ | 123 | */ |
130 | if (visit_mask) { | 124 | if (visit_mask) { |
131 | if (*visit_mask & (1UL << info->type)) | 125 | if (*visit_mask & (1UL << info->type)) { |
126 | printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type); | ||
132 | goto unknown; | 127 | goto unknown; |
128 | } | ||
133 | *visit_mask |= 1UL << info->type; | 129 | *visit_mask |= 1UL << info->type; |
134 | } | 130 | } |
135 | 131 | ||
@@ -140,56 +136,6 @@ unknown: | |||
140 | return -EINVAL; | 136 | return -EINVAL; |
141 | } | 137 | } |
142 | 138 | ||
143 | void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | ||
144 | unsigned long *sp, char *log_lvl) | ||
145 | { | ||
146 | unsigned long *irq_stack_end; | ||
147 | unsigned long *irq_stack; | ||
148 | unsigned long *stack; | ||
149 | int i; | ||
150 | |||
151 | if (!try_get_task_stack(task)) | ||
152 | return; | ||
153 | |||
154 | irq_stack_end = (unsigned long *)this_cpu_read(irq_stack_ptr); | ||
155 | irq_stack = irq_stack_end - (IRQ_STACK_SIZE / sizeof(long)); | ||
156 | |||
157 | sp = sp ? : get_stack_pointer(task, regs); | ||
158 | |||
159 | stack = sp; | ||
160 | for (i = 0; i < kstack_depth_to_print; i++) { | ||
161 | unsigned long word; | ||
162 | |||
163 | if (stack >= irq_stack && stack <= irq_stack_end) { | ||
164 | if (stack == irq_stack_end) { | ||
165 | stack = (unsigned long *) (irq_stack_end[-1]); | ||
166 | pr_cont(" <EOI> "); | ||
167 | } | ||
168 | } else { | ||
169 | if (kstack_end(stack)) | ||
170 | break; | ||
171 | } | ||
172 | |||
173 | if (probe_kernel_address(stack, word)) | ||
174 | break; | ||
175 | |||
176 | if ((i % STACKSLOTS_PER_LINE) == 0) { | ||
177 | if (i != 0) | ||
178 | pr_cont("\n"); | ||
179 | printk("%s %016lx", log_lvl, word); | ||
180 | } else | ||
181 | pr_cont(" %016lx", word); | ||
182 | |||
183 | stack++; | ||
184 | touch_nmi_watchdog(); | ||
185 | } | ||
186 | |||
187 | pr_cont("\n"); | ||
188 | show_trace_log_lvl(task, regs, sp, log_lvl); | ||
189 | |||
190 | put_task_stack(task); | ||
191 | } | ||
192 | |||
193 | void show_regs(struct pt_regs *regs) | 139 | void show_regs(struct pt_regs *regs) |
194 | { | 140 | { |
195 | int i; | 141 | int i; |
@@ -207,8 +153,7 @@ void show_regs(struct pt_regs *regs) | |||
207 | unsigned char c; | 153 | unsigned char c; |
208 | u8 *ip; | 154 | u8 *ip; |
209 | 155 | ||
210 | printk(KERN_DEFAULT "Stack:\n"); | 156 | show_trace_log_lvl(current, regs, NULL, KERN_DEFAULT); |
211 | show_stack_log_lvl(current, regs, NULL, KERN_DEFAULT); | ||
212 | 157 | ||
213 | printk(KERN_DEFAULT "Code: "); | 158 | printk(KERN_DEFAULT "Code: "); |
214 | 159 | ||
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index 095ef7ddd6ae..ce47452879fd 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c | |||
@@ -65,6 +65,7 @@ void fpu__xstate_clear_all_cpu_caps(void) | |||
65 | setup_clear_cpu_cap(X86_FEATURE_AVX); | 65 | setup_clear_cpu_cap(X86_FEATURE_AVX); |
66 | setup_clear_cpu_cap(X86_FEATURE_AVX2); | 66 | setup_clear_cpu_cap(X86_FEATURE_AVX2); |
67 | setup_clear_cpu_cap(X86_FEATURE_AVX512F); | 67 | setup_clear_cpu_cap(X86_FEATURE_AVX512F); |
68 | setup_clear_cpu_cap(X86_FEATURE_AVX512IFMA); | ||
68 | setup_clear_cpu_cap(X86_FEATURE_AVX512PF); | 69 | setup_clear_cpu_cap(X86_FEATURE_AVX512PF); |
69 | setup_clear_cpu_cap(X86_FEATURE_AVX512ER); | 70 | setup_clear_cpu_cap(X86_FEATURE_AVX512ER); |
70 | setup_clear_cpu_cap(X86_FEATURE_AVX512CD); | 71 | setup_clear_cpu_cap(X86_FEATURE_AVX512CD); |
@@ -73,6 +74,7 @@ void fpu__xstate_clear_all_cpu_caps(void) | |||
73 | setup_clear_cpu_cap(X86_FEATURE_AVX512VL); | 74 | setup_clear_cpu_cap(X86_FEATURE_AVX512VL); |
74 | setup_clear_cpu_cap(X86_FEATURE_MPX); | 75 | setup_clear_cpu_cap(X86_FEATURE_MPX); |
75 | setup_clear_cpu_cap(X86_FEATURE_XGETBV1); | 76 | setup_clear_cpu_cap(X86_FEATURE_XGETBV1); |
77 | setup_clear_cpu_cap(X86_FEATURE_AVX512VBMI); | ||
76 | setup_clear_cpu_cap(X86_FEATURE_PKU); | 78 | setup_clear_cpu_cap(X86_FEATURE_PKU); |
77 | setup_clear_cpu_cap(X86_FEATURE_AVX512_4VNNIW); | 79 | setup_clear_cpu_cap(X86_FEATURE_AVX512_4VNNIW); |
78 | setup_clear_cpu_cap(X86_FEATURE_AVX512_4FMAPS); | 80 | setup_clear_cpu_cap(X86_FEATURE_AVX512_4FMAPS); |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 2dabea46f039..4e8577d03372 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -63,6 +63,8 @@ | |||
63 | #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) | 63 | #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) |
64 | #endif | 64 | #endif |
65 | 65 | ||
66 | #define SIZEOF_PTREGS 17*4 | ||
67 | |||
66 | /* | 68 | /* |
67 | * Number of possible pages in the lowmem region. | 69 | * Number of possible pages in the lowmem region. |
68 | * | 70 | * |
@@ -248,19 +250,19 @@ page_pde_offset = (__PAGE_OFFSET >> 20); | |||
248 | #ifdef CONFIG_PARAVIRT | 250 | #ifdef CONFIG_PARAVIRT |
249 | /* This is can only trip for a broken bootloader... */ | 251 | /* This is can only trip for a broken bootloader... */ |
250 | cmpw $0x207, pa(boot_params + BP_version) | 252 | cmpw $0x207, pa(boot_params + BP_version) |
251 | jb default_entry | 253 | jb .Ldefault_entry |
252 | 254 | ||
253 | /* Paravirt-compatible boot parameters. Look to see what architecture | 255 | /* Paravirt-compatible boot parameters. Look to see what architecture |
254 | we're booting under. */ | 256 | we're booting under. */ |
255 | movl pa(boot_params + BP_hardware_subarch), %eax | 257 | movl pa(boot_params + BP_hardware_subarch), %eax |
256 | cmpl $num_subarch_entries, %eax | 258 | cmpl $num_subarch_entries, %eax |
257 | jae bad_subarch | 259 | jae .Lbad_subarch |
258 | 260 | ||
259 | movl pa(subarch_entries)(,%eax,4), %eax | 261 | movl pa(subarch_entries)(,%eax,4), %eax |
260 | subl $__PAGE_OFFSET, %eax | 262 | subl $__PAGE_OFFSET, %eax |
261 | jmp *%eax | 263 | jmp *%eax |
262 | 264 | ||
263 | bad_subarch: | 265 | .Lbad_subarch: |
264 | WEAK(lguest_entry) | 266 | WEAK(lguest_entry) |
265 | WEAK(xen_entry) | 267 | WEAK(xen_entry) |
266 | /* Unknown implementation; there's really | 268 | /* Unknown implementation; there's really |
@@ -270,14 +272,14 @@ WEAK(xen_entry) | |||
270 | __INITDATA | 272 | __INITDATA |
271 | 273 | ||
272 | subarch_entries: | 274 | subarch_entries: |
273 | .long default_entry /* normal x86/PC */ | 275 | .long .Ldefault_entry /* normal x86/PC */ |
274 | .long lguest_entry /* lguest hypervisor */ | 276 | .long lguest_entry /* lguest hypervisor */ |
275 | .long xen_entry /* Xen hypervisor */ | 277 | .long xen_entry /* Xen hypervisor */ |
276 | .long default_entry /* Moorestown MID */ | 278 | .long .Ldefault_entry /* Moorestown MID */ |
277 | num_subarch_entries = (. - subarch_entries) / 4 | 279 | num_subarch_entries = (. - subarch_entries) / 4 |
278 | .previous | 280 | .previous |
279 | #else | 281 | #else |
280 | jmp default_entry | 282 | jmp .Ldefault_entry |
281 | #endif /* CONFIG_PARAVIRT */ | 283 | #endif /* CONFIG_PARAVIRT */ |
282 | 284 | ||
283 | #ifdef CONFIG_HOTPLUG_CPU | 285 | #ifdef CONFIG_HOTPLUG_CPU |
@@ -289,7 +291,8 @@ num_subarch_entries = (. - subarch_entries) / 4 | |||
289 | ENTRY(start_cpu0) | 291 | ENTRY(start_cpu0) |
290 | movl initial_stack, %ecx | 292 | movl initial_stack, %ecx |
291 | movl %ecx, %esp | 293 | movl %ecx, %esp |
292 | jmp *(initial_code) | 294 | call *(initial_code) |
295 | 1: jmp 1b | ||
293 | ENDPROC(start_cpu0) | 296 | ENDPROC(start_cpu0) |
294 | #endif | 297 | #endif |
295 | 298 | ||
@@ -317,7 +320,7 @@ ENTRY(startup_32_smp) | |||
317 | call load_ucode_ap | 320 | call load_ucode_ap |
318 | #endif | 321 | #endif |
319 | 322 | ||
320 | default_entry: | 323 | .Ldefault_entry: |
321 | #define CR0_STATE (X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | \ | 324 | #define CR0_STATE (X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | \ |
322 | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM | \ | 325 | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM | \ |
323 | X86_CR0_PG) | 326 | X86_CR0_PG) |
@@ -347,7 +350,7 @@ default_entry: | |||
347 | pushfl | 350 | pushfl |
348 | popl %eax # get EFLAGS | 351 | popl %eax # get EFLAGS |
349 | testl $X86_EFLAGS_ID,%eax # did EFLAGS.ID remained set? | 352 | testl $X86_EFLAGS_ID,%eax # did EFLAGS.ID remained set? |
350 | jz enable_paging # hw disallowed setting of ID bit | 353 | jz .Lenable_paging # hw disallowed setting of ID bit |
351 | # which means no CPUID and no CR4 | 354 | # which means no CPUID and no CR4 |
352 | 355 | ||
353 | xorl %eax,%eax | 356 | xorl %eax,%eax |
@@ -357,13 +360,13 @@ default_entry: | |||
357 | movl $1,%eax | 360 | movl $1,%eax |
358 | cpuid | 361 | cpuid |
359 | andl $~1,%edx # Ignore CPUID.FPU | 362 | andl $~1,%edx # Ignore CPUID.FPU |
360 | jz enable_paging # No flags or only CPUID.FPU = no CR4 | 363 | jz .Lenable_paging # No flags or only CPUID.FPU = no CR4 |
361 | 364 | ||
362 | movl pa(mmu_cr4_features),%eax | 365 | movl pa(mmu_cr4_features),%eax |
363 | movl %eax,%cr4 | 366 | movl %eax,%cr4 |
364 | 367 | ||
365 | testb $X86_CR4_PAE, %al # check if PAE is enabled | 368 | testb $X86_CR4_PAE, %al # check if PAE is enabled |
366 | jz enable_paging | 369 | jz .Lenable_paging |
367 | 370 | ||
368 | /* Check if extended functions are implemented */ | 371 | /* Check if extended functions are implemented */ |
369 | movl $0x80000000, %eax | 372 | movl $0x80000000, %eax |
@@ -371,7 +374,7 @@ default_entry: | |||
371 | /* Value must be in the range 0x80000001 to 0x8000ffff */ | 374 | /* Value must be in the range 0x80000001 to 0x8000ffff */ |
372 | subl $0x80000001, %eax | 375 | subl $0x80000001, %eax |
373 | cmpl $(0x8000ffff-0x80000001), %eax | 376 | cmpl $(0x8000ffff-0x80000001), %eax |
374 | ja enable_paging | 377 | ja .Lenable_paging |
375 | 378 | ||
376 | /* Clear bogus XD_DISABLE bits */ | 379 | /* Clear bogus XD_DISABLE bits */ |
377 | call verify_cpu | 380 | call verify_cpu |
@@ -380,7 +383,7 @@ default_entry: | |||
380 | cpuid | 383 | cpuid |
381 | /* Execute Disable bit supported? */ | 384 | /* Execute Disable bit supported? */ |
382 | btl $(X86_FEATURE_NX & 31), %edx | 385 | btl $(X86_FEATURE_NX & 31), %edx |
383 | jnc enable_paging | 386 | jnc .Lenable_paging |
384 | 387 | ||
385 | /* Setup EFER (Extended Feature Enable Register) */ | 388 | /* Setup EFER (Extended Feature Enable Register) */ |
386 | movl $MSR_EFER, %ecx | 389 | movl $MSR_EFER, %ecx |
@@ -390,7 +393,7 @@ default_entry: | |||
390 | /* Make changes effective */ | 393 | /* Make changes effective */ |
391 | wrmsr | 394 | wrmsr |
392 | 395 | ||
393 | enable_paging: | 396 | .Lenable_paging: |
394 | 397 | ||
395 | /* | 398 | /* |
396 | * Enable paging | 399 | * Enable paging |
@@ -419,7 +422,7 @@ enable_paging: | |||
419 | */ | 422 | */ |
420 | movb $4,X86 # at least 486 | 423 | movb $4,X86 # at least 486 |
421 | cmpl $-1,X86_CPUID | 424 | cmpl $-1,X86_CPUID |
422 | je is486 | 425 | je .Lis486 |
423 | 426 | ||
424 | /* get vendor info */ | 427 | /* get vendor info */ |
425 | xorl %eax,%eax # call CPUID with 0 -> return vendor ID | 428 | xorl %eax,%eax # call CPUID with 0 -> return vendor ID |
@@ -430,7 +433,7 @@ enable_paging: | |||
430 | movl %ecx,X86_VENDOR_ID+8 # last 4 chars | 433 | movl %ecx,X86_VENDOR_ID+8 # last 4 chars |
431 | 434 | ||
432 | orl %eax,%eax # do we have processor info as well? | 435 | orl %eax,%eax # do we have processor info as well? |
433 | je is486 | 436 | je .Lis486 |
434 | 437 | ||
435 | movl $1,%eax # Use the CPUID instruction to get CPU type | 438 | movl $1,%eax # Use the CPUID instruction to get CPU type |
436 | cpuid | 439 | cpuid |
@@ -444,7 +447,7 @@ enable_paging: | |||
444 | movb %cl,X86_MASK | 447 | movb %cl,X86_MASK |
445 | movl %edx,X86_CAPABILITY | 448 | movl %edx,X86_CAPABILITY |
446 | 449 | ||
447 | is486: | 450 | .Lis486: |
448 | movl $0x50022,%ecx # set AM, WP, NE and MP | 451 | movl $0x50022,%ecx # set AM, WP, NE and MP |
449 | movl %cr0,%eax | 452 | movl %cr0,%eax |
450 | andl $0x80000011,%eax # Save PG,PE,ET | 453 | andl $0x80000011,%eax # Save PG,PE,ET |
@@ -470,8 +473,9 @@ is486: | |||
470 | xorl %eax,%eax # Clear LDT | 473 | xorl %eax,%eax # Clear LDT |
471 | lldt %ax | 474 | lldt %ax |
472 | 475 | ||
473 | pushl $0 # fake return address for unwinder | 476 | call *(initial_code) |
474 | jmp *(initial_code) | 477 | 1: jmp 1b |
478 | ENDPROC(startup_32_smp) | ||
475 | 479 | ||
476 | #include "verify_cpu.S" | 480 | #include "verify_cpu.S" |
477 | 481 | ||
@@ -709,7 +713,12 @@ ENTRY(initial_page_table) | |||
709 | .data | 713 | .data |
710 | .balign 4 | 714 | .balign 4 |
711 | ENTRY(initial_stack) | 715 | ENTRY(initial_stack) |
712 | .long init_thread_union+THREAD_SIZE | 716 | /* |
717 | * The SIZEOF_PTREGS gap is a convention which helps the in-kernel | ||
718 | * unwinder reliably detect the end of the stack. | ||
719 | */ | ||
720 | .long init_thread_union + THREAD_SIZE - SIZEOF_PTREGS - \ | ||
721 | TOP_OF_KERNEL_STACK_PADDING; | ||
713 | 722 | ||
714 | __INITRODATA | 723 | __INITRODATA |
715 | int_msg: | 724 | int_msg: |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index b4421cc191b0..a15d381e6020 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -66,13 +66,8 @@ startup_64: | |||
66 | * tables and then reload them. | 66 | * tables and then reload them. |
67 | */ | 67 | */ |
68 | 68 | ||
69 | /* | 69 | /* Set up the stack for verify_cpu(), similar to initial_stack below */ |
70 | * Setup stack for verify_cpu(). "-8" because initial_stack is defined | 70 | leaq (__end_init_task - SIZEOF_PTREGS)(%rip), %rsp |
71 | * this way, see below. Our best guess is a NULL ptr for stack | ||
72 | * termination heuristics and we don't want to break anything which | ||
73 | * might depend on it (kgdb, ...). | ||
74 | */ | ||
75 | leaq (__end_init_task - 8)(%rip), %rsp | ||
76 | 71 | ||
77 | /* Sanitize CPU configuration */ | 72 | /* Sanitize CPU configuration */ |
78 | call verify_cpu | 73 | call verify_cpu |
@@ -117,20 +112,20 @@ startup_64: | |||
117 | movq %rdi, %rax | 112 | movq %rdi, %rax |
118 | shrq $PGDIR_SHIFT, %rax | 113 | shrq $PGDIR_SHIFT, %rax |
119 | 114 | ||
120 | leaq (4096 + _KERNPG_TABLE)(%rbx), %rdx | 115 | leaq (PAGE_SIZE + _KERNPG_TABLE)(%rbx), %rdx |
121 | movq %rdx, 0(%rbx,%rax,8) | 116 | movq %rdx, 0(%rbx,%rax,8) |
122 | movq %rdx, 8(%rbx,%rax,8) | 117 | movq %rdx, 8(%rbx,%rax,8) |
123 | 118 | ||
124 | addq $4096, %rdx | 119 | addq $PAGE_SIZE, %rdx |
125 | movq %rdi, %rax | 120 | movq %rdi, %rax |
126 | shrq $PUD_SHIFT, %rax | 121 | shrq $PUD_SHIFT, %rax |
127 | andl $(PTRS_PER_PUD-1), %eax | 122 | andl $(PTRS_PER_PUD-1), %eax |
128 | movq %rdx, 4096(%rbx,%rax,8) | 123 | movq %rdx, PAGE_SIZE(%rbx,%rax,8) |
129 | incl %eax | 124 | incl %eax |
130 | andl $(PTRS_PER_PUD-1), %eax | 125 | andl $(PTRS_PER_PUD-1), %eax |
131 | movq %rdx, 4096(%rbx,%rax,8) | 126 | movq %rdx, PAGE_SIZE(%rbx,%rax,8) |
132 | 127 | ||
133 | addq $8192, %rbx | 128 | addq $PAGE_SIZE * 2, %rbx |
134 | movq %rdi, %rax | 129 | movq %rdi, %rax |
135 | shrq $PMD_SHIFT, %rdi | 130 | shrq $PMD_SHIFT, %rdi |
136 | addq $(__PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL), %rax | 131 | addq $(__PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL), %rax |
@@ -265,13 +260,17 @@ ENTRY(secondary_startup_64) | |||
265 | movl $MSR_GS_BASE,%ecx | 260 | movl $MSR_GS_BASE,%ecx |
266 | movl initial_gs(%rip),%eax | 261 | movl initial_gs(%rip),%eax |
267 | movl initial_gs+4(%rip),%edx | 262 | movl initial_gs+4(%rip),%edx |
268 | wrmsr | 263 | wrmsr |
269 | 264 | ||
270 | /* rsi is pointer to real mode structure with interesting info. | 265 | /* rsi is pointer to real mode structure with interesting info. |
271 | pass it to C */ | 266 | pass it to C */ |
272 | movq %rsi, %rdi | 267 | movq %rsi, %rdi |
273 | 268 | jmp start_cpu | |
274 | /* Finally jump to run C code and to be on real kernel address | 269 | ENDPROC(secondary_startup_64) |
270 | |||
271 | ENTRY(start_cpu) | ||
272 | /* | ||
273 | * Jump to run C code and to be on a real kernel address. | ||
275 | * Since we are running on identity-mapped space we have to jump | 274 | * Since we are running on identity-mapped space we have to jump |
276 | * to the full 64bit address, this is only possible as indirect | 275 | * to the full 64bit address, this is only possible as indirect |
277 | * jump. In addition we need to ensure %cs is set so we make this | 276 | * jump. In addition we need to ensure %cs is set so we make this |
@@ -295,12 +294,13 @@ ENTRY(secondary_startup_64) | |||
295 | * REX.W + FF /5 JMP m16:64 Jump far, absolute indirect, | 294 | * REX.W + FF /5 JMP m16:64 Jump far, absolute indirect, |
296 | * address given in m16:64. | 295 | * address given in m16:64. |
297 | */ | 296 | */ |
298 | movq initial_code(%rip),%rax | 297 | call 1f # put return address on stack for unwinder |
299 | pushq $0 # fake return address to stop unwinder | 298 | 1: xorq %rbp, %rbp # clear frame pointer |
299 | movq initial_code(%rip), %rax | ||
300 | pushq $__KERNEL_CS # set correct cs | 300 | pushq $__KERNEL_CS # set correct cs |
301 | pushq %rax # target address in negative space | 301 | pushq %rax # target address in negative space |
302 | lretq | 302 | lretq |
303 | ENDPROC(secondary_startup_64) | 303 | ENDPROC(start_cpu) |
304 | 304 | ||
305 | #include "verify_cpu.S" | 305 | #include "verify_cpu.S" |
306 | 306 | ||
@@ -308,15 +308,11 @@ ENDPROC(secondary_startup_64) | |||
308 | /* | 308 | /* |
309 | * Boot CPU0 entry point. It's called from play_dead(). Everything has been set | 309 | * Boot CPU0 entry point. It's called from play_dead(). Everything has been set |
310 | * up already except stack. We just set up stack here. Then call | 310 | * up already except stack. We just set up stack here. Then call |
311 | * start_secondary(). | 311 | * start_secondary() via start_cpu(). |
312 | */ | 312 | */ |
313 | ENTRY(start_cpu0) | 313 | ENTRY(start_cpu0) |
314 | movq initial_stack(%rip),%rsp | 314 | movq initial_stack(%rip), %rsp |
315 | movq initial_code(%rip),%rax | 315 | jmp start_cpu |
316 | pushq $0 # fake return address to stop unwinder | ||
317 | pushq $__KERNEL_CS # set correct cs | ||
318 | pushq %rax # target address in negative space | ||
319 | lretq | ||
320 | ENDPROC(start_cpu0) | 316 | ENDPROC(start_cpu0) |
321 | #endif | 317 | #endif |
322 | 318 | ||
@@ -328,7 +324,11 @@ ENDPROC(start_cpu0) | |||
328 | GLOBAL(initial_gs) | 324 | GLOBAL(initial_gs) |
329 | .quad INIT_PER_CPU_VAR(irq_stack_union) | 325 | .quad INIT_PER_CPU_VAR(irq_stack_union) |
330 | GLOBAL(initial_stack) | 326 | GLOBAL(initial_stack) |
331 | .quad init_thread_union+THREAD_SIZE-8 | 327 | /* |
328 | * The SIZEOF_PTREGS gap is a convention which helps the in-kernel | ||
329 | * unwinder reliably detect the end of the stack. | ||
330 | */ | ||
331 | .quad init_thread_union + THREAD_SIZE - SIZEOF_PTREGS | ||
332 | __FINITDATA | 332 | __FINITDATA |
333 | 333 | ||
334 | bad_address: | 334 | bad_address: |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index bd7be8efdc4c..e3223bc78cb6 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -72,10 +72,9 @@ void __show_regs(struct pt_regs *regs, int all) | |||
72 | savesegment(gs, gs); | 72 | savesegment(gs, gs); |
73 | } | 73 | } |
74 | 74 | ||
75 | printk(KERN_DEFAULT "EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", | 75 | printk(KERN_DEFAULT "EIP: %pS\n", (void *)regs->ip); |
76 | (u16)regs->cs, regs->ip, regs->flags, | 76 | printk(KERN_DEFAULT "EFLAGS: %08lx CPU: %d\n", regs->flags, |
77 | smp_processor_id()); | 77 | smp_processor_id()); |
78 | print_symbol("EIP is at %s\n", regs->ip); | ||
79 | 78 | ||
80 | printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", | 79 | printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", |
81 | regs->ax, regs->bx, regs->cx, regs->dx); | 80 | regs->ax, regs->bx, regs->cx, regs->dx); |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index b3760b3c1ca0..c99f1ca35eb5 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -61,10 +61,15 @@ void __show_regs(struct pt_regs *regs, int all) | |||
61 | unsigned int fsindex, gsindex; | 61 | unsigned int fsindex, gsindex; |
62 | unsigned int ds, cs, es; | 62 | unsigned int ds, cs, es; |
63 | 63 | ||
64 | printk(KERN_DEFAULT "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); | 64 | printk(KERN_DEFAULT "RIP: %04lx:%pS\n", regs->cs & 0xffff, |
65 | printk_address(regs->ip); | 65 | (void *)regs->ip); |
66 | printk(KERN_DEFAULT "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, | 66 | printk(KERN_DEFAULT "RSP: %04lx:%016lx EFLAGS: %08lx", regs->ss, |
67 | regs->sp, regs->flags); | 67 | regs->sp, regs->flags); |
68 | if (regs->orig_ax != -1) | ||
69 | pr_cont(" ORIG_RAX: %016lx\n", regs->orig_ax); | ||
70 | else | ||
71 | pr_cont("\n"); | ||
72 | |||
68 | printk(KERN_DEFAULT "RAX: %016lx RBX: %016lx RCX: %016lx\n", | 73 | printk(KERN_DEFAULT "RAX: %016lx RBX: %016lx RCX: %016lx\n", |
69 | regs->ax, regs->bx, regs->cx); | 74 | regs->ax, regs->bx, regs->cx); |
70 | printk(KERN_DEFAULT "RDX: %016lx RSI: %016lx RDI: %016lx\n", | 75 | printk(KERN_DEFAULT "RDX: %016lx RSI: %016lx RDI: %016lx\n", |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 118e792a7be6..8add3a5b8635 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -987,9 +987,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle) | |||
987 | int cpu0_nmi_registered = 0; | 987 | int cpu0_nmi_registered = 0; |
988 | unsigned long timeout; | 988 | unsigned long timeout; |
989 | 989 | ||
990 | idle->thread.sp = (unsigned long) (((struct pt_regs *) | 990 | idle->thread.sp = (unsigned long)task_pt_regs(idle); |
991 | (THREAD_SIZE + task_stack_page(idle))) - 1); | ||
992 | |||
993 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); | 991 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
994 | initial_code = (unsigned long)start_secondary; | 992 | initial_code = (unsigned long)start_secondary; |
995 | initial_stack = idle->thread.sp; | 993 | initial_stack = idle->thread.sp; |
diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c index a2456d4d286a..ea7b7f9a3b9e 100644 --- a/arch/x86/kernel/unwind_frame.c +++ b/arch/x86/kernel/unwind_frame.c | |||
@@ -14,13 +14,55 @@ unsigned long unwind_get_return_address(struct unwind_state *state) | |||
14 | if (unwind_done(state)) | 14 | if (unwind_done(state)) |
15 | return 0; | 15 | return 0; |
16 | 16 | ||
17 | if (state->regs && user_mode(state->regs)) | ||
18 | return 0; | ||
19 | |||
17 | addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p, | 20 | addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p, |
18 | addr_p); | 21 | addr_p); |
19 | 22 | ||
20 | return __kernel_text_address(addr) ? addr : 0; | 23 | if (!__kernel_text_address(addr)) { |
24 | printk_deferred_once(KERN_WARNING | ||
25 | "WARNING: unrecognized kernel stack return address %p at %p in %s:%d\n", | ||
26 | (void *)addr, addr_p, state->task->comm, | ||
27 | state->task->pid); | ||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | return addr; | ||
21 | } | 32 | } |
22 | EXPORT_SYMBOL_GPL(unwind_get_return_address); | 33 | EXPORT_SYMBOL_GPL(unwind_get_return_address); |
23 | 34 | ||
35 | static size_t regs_size(struct pt_regs *regs) | ||
36 | { | ||
37 | /* x86_32 regs from kernel mode are two words shorter: */ | ||
38 | if (IS_ENABLED(CONFIG_X86_32) && !user_mode(regs)) | ||
39 | return sizeof(*regs) - 2*sizeof(long); | ||
40 | |||
41 | return sizeof(*regs); | ||
42 | } | ||
43 | |||
44 | static bool is_last_task_frame(struct unwind_state *state) | ||
45 | { | ||
46 | unsigned long bp = (unsigned long)state->bp; | ||
47 | unsigned long regs = (unsigned long)task_pt_regs(state->task); | ||
48 | |||
49 | return bp == regs - FRAME_HEADER_SIZE; | ||
50 | } | ||
51 | |||
52 | /* | ||
53 | * This determines if the frame pointer actually contains an encoded pointer to | ||
54 | * pt_regs on the stack. See ENCODE_FRAME_POINTER. | ||
55 | */ | ||
56 | static struct pt_regs *decode_frame_pointer(unsigned long *bp) | ||
57 | { | ||
58 | unsigned long regs = (unsigned long)bp; | ||
59 | |||
60 | if (!(regs & 0x1)) | ||
61 | return NULL; | ||
62 | |||
63 | return (struct pt_regs *)(regs & ~0x1); | ||
64 | } | ||
65 | |||
24 | static bool update_stack_state(struct unwind_state *state, void *addr, | 66 | static bool update_stack_state(struct unwind_state *state, void *addr, |
25 | size_t len) | 67 | size_t len) |
26 | { | 68 | { |
@@ -43,26 +85,117 @@ static bool update_stack_state(struct unwind_state *state, void *addr, | |||
43 | 85 | ||
44 | bool unwind_next_frame(struct unwind_state *state) | 86 | bool unwind_next_frame(struct unwind_state *state) |
45 | { | 87 | { |
46 | unsigned long *next_bp; | 88 | struct pt_regs *regs; |
89 | unsigned long *next_bp, *next_frame; | ||
90 | size_t next_len; | ||
91 | enum stack_type prev_type = state->stack_info.type; | ||
47 | 92 | ||
48 | if (unwind_done(state)) | 93 | if (unwind_done(state)) |
49 | return false; | 94 | return false; |
50 | 95 | ||
51 | next_bp = (unsigned long *)*state->bp; | 96 | /* have we reached the end? */ |
97 | if (state->regs && user_mode(state->regs)) | ||
98 | goto the_end; | ||
99 | |||
100 | if (is_last_task_frame(state)) { | ||
101 | regs = task_pt_regs(state->task); | ||
102 | |||
103 | /* | ||
104 | * kthreads (other than the boot CPU's idle thread) have some | ||
105 | * partial regs at the end of their stack which were placed | ||
106 | * there by copy_thread_tls(). But the regs don't have any | ||
107 | * useful information, so we can skip them. | ||
108 | * | ||
109 | * This user_mode() check is slightly broader than a PF_KTHREAD | ||
110 | * check because it also catches the awkward situation where a | ||
111 | * newly forked kthread transitions into a user task by calling | ||
112 | * do_execve(), which eventually clears PF_KTHREAD. | ||
113 | */ | ||
114 | if (!user_mode(regs)) | ||
115 | goto the_end; | ||
116 | |||
117 | /* | ||
118 | * We're almost at the end, but not quite: there's still the | ||
119 | * syscall regs frame. Entry code doesn't encode the regs | ||
120 | * pointer for syscalls, so we have to set it manually. | ||
121 | */ | ||
122 | state->regs = regs; | ||
123 | state->bp = NULL; | ||
124 | return true; | ||
125 | } | ||
126 | |||
127 | /* get the next frame pointer */ | ||
128 | if (state->regs) | ||
129 | next_bp = (unsigned long *)state->regs->bp; | ||
130 | else | ||
131 | next_bp = (unsigned long *)*state->bp; | ||
132 | |||
133 | /* is the next frame pointer an encoded pointer to pt_regs? */ | ||
134 | regs = decode_frame_pointer(next_bp); | ||
135 | if (regs) { | ||
136 | next_frame = (unsigned long *)regs; | ||
137 | next_len = sizeof(*regs); | ||
138 | } else { | ||
139 | next_frame = next_bp; | ||
140 | next_len = FRAME_HEADER_SIZE; | ||
141 | } | ||
52 | 142 | ||
53 | /* make sure the next frame's data is accessible */ | 143 | /* make sure the next frame's data is accessible */ |
54 | if (!update_stack_state(state, next_bp, FRAME_HEADER_SIZE)) | 144 | if (!update_stack_state(state, next_frame, next_len)) { |
55 | return false; | 145 | /* |
146 | * Don't warn on bad regs->bp. An interrupt in entry code | ||
147 | * might cause a false positive warning. | ||
148 | */ | ||
149 | if (state->regs) | ||
150 | goto the_end; | ||
151 | |||
152 | goto bad_address; | ||
153 | } | ||
154 | |||
155 | /* Make sure it only unwinds up and doesn't overlap the last frame: */ | ||
156 | if (state->stack_info.type == prev_type) { | ||
157 | if (state->regs && (void *)next_frame < (void *)state->regs + regs_size(state->regs)) | ||
158 | goto bad_address; | ||
159 | |||
160 | if (state->bp && (void *)next_frame < (void *)state->bp + FRAME_HEADER_SIZE) | ||
161 | goto bad_address; | ||
162 | } | ||
56 | 163 | ||
57 | /* move to the next frame */ | 164 | /* move to the next frame */ |
58 | state->bp = next_bp; | 165 | if (regs) { |
166 | state->regs = regs; | ||
167 | state->bp = NULL; | ||
168 | } else { | ||
169 | state->bp = next_bp; | ||
170 | state->regs = NULL; | ||
171 | } | ||
172 | |||
59 | return true; | 173 | return true; |
174 | |||
175 | bad_address: | ||
176 | if (state->regs) { | ||
177 | printk_deferred_once(KERN_WARNING | ||
178 | "WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n", | ||
179 | state->regs, state->task->comm, | ||
180 | state->task->pid, next_frame); | ||
181 | } else { | ||
182 | printk_deferred_once(KERN_WARNING | ||
183 | "WARNING: kernel stack frame pointer at %p in %s:%d has bad value %p\n", | ||
184 | state->bp, state->task->comm, | ||
185 | state->task->pid, next_frame); | ||
186 | } | ||
187 | the_end: | ||
188 | state->stack_info.type = STACK_TYPE_UNKNOWN; | ||
189 | return false; | ||
60 | } | 190 | } |
61 | EXPORT_SYMBOL_GPL(unwind_next_frame); | 191 | EXPORT_SYMBOL_GPL(unwind_next_frame); |
62 | 192 | ||
63 | void __unwind_start(struct unwind_state *state, struct task_struct *task, | 193 | void __unwind_start(struct unwind_state *state, struct task_struct *task, |
64 | struct pt_regs *regs, unsigned long *first_frame) | 194 | struct pt_regs *regs, unsigned long *first_frame) |
65 | { | 195 | { |
196 | unsigned long *bp, *frame; | ||
197 | size_t len; | ||
198 | |||
66 | memset(state, 0, sizeof(*state)); | 199 | memset(state, 0, sizeof(*state)); |
67 | state->task = task; | 200 | state->task = task; |
68 | 201 | ||
@@ -73,12 +206,22 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, | |||
73 | } | 206 | } |
74 | 207 | ||
75 | /* set up the starting stack frame */ | 208 | /* set up the starting stack frame */ |
76 | state->bp = get_frame_pointer(task, regs); | 209 | bp = get_frame_pointer(task, regs); |
210 | regs = decode_frame_pointer(bp); | ||
211 | if (regs) { | ||
212 | state->regs = regs; | ||
213 | frame = (unsigned long *)regs; | ||
214 | len = sizeof(*regs); | ||
215 | } else { | ||
216 | state->bp = bp; | ||
217 | frame = bp; | ||
218 | len = FRAME_HEADER_SIZE; | ||
219 | } | ||
77 | 220 | ||
78 | /* initialize stack info and make sure the frame data is accessible */ | 221 | /* initialize stack info and make sure the frame data is accessible */ |
79 | get_stack_info(state->bp, state->task, &state->stack_info, | 222 | get_stack_info(frame, state->task, &state->stack_info, |
80 | &state->stack_mask); | 223 | &state->stack_mask); |
81 | update_stack_state(state, state->bp, FRAME_HEADER_SIZE); | 224 | update_stack_state(state, frame, len); |
82 | 225 | ||
83 | /* | 226 | /* |
84 | * The caller can provide the address of the first frame directly | 227 | * The caller can provide the address of the first frame directly |
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index dbf67f64d5ec..e79f15f108a8 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S | |||
@@ -91,10 +91,10 @@ SECTIONS | |||
91 | /* Text and read-only data */ | 91 | /* Text and read-only data */ |
92 | .text : AT(ADDR(.text) - LOAD_OFFSET) { | 92 | .text : AT(ADDR(.text) - LOAD_OFFSET) { |
93 | _text = .; | 93 | _text = .; |
94 | _stext = .; | ||
94 | /* bootstrapping code */ | 95 | /* bootstrapping code */ |
95 | HEAD_TEXT | 96 | HEAD_TEXT |
96 | . = ALIGN(8); | 97 | . = ALIGN(8); |
97 | _stext = .; | ||
98 | TEXT_TEXT | 98 | TEXT_TEXT |
99 | SCHED_TEXT | 99 | SCHED_TEXT |
100 | CPUIDLE_TEXT | 100 | CPUIDLE_TEXT |
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index d376e4b48f88..c5959576c315 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S | |||
@@ -16,53 +16,6 @@ | |||
16 | #include <asm/smap.h> | 16 | #include <asm/smap.h> |
17 | #include <asm/export.h> | 17 | #include <asm/export.h> |
18 | 18 | ||
19 | /* Standard copy_to_user with segment limit checking */ | ||
20 | ENTRY(_copy_to_user) | ||
21 | mov PER_CPU_VAR(current_task), %rax | ||
22 | movq %rdi,%rcx | ||
23 | addq %rdx,%rcx | ||
24 | jc bad_to_user | ||
25 | cmpq TASK_addr_limit(%rax),%rcx | ||
26 | ja bad_to_user | ||
27 | ALTERNATIVE_2 "jmp copy_user_generic_unrolled", \ | ||
28 | "jmp copy_user_generic_string", \ | ||
29 | X86_FEATURE_REP_GOOD, \ | ||
30 | "jmp copy_user_enhanced_fast_string", \ | ||
31 | X86_FEATURE_ERMS | ||
32 | ENDPROC(_copy_to_user) | ||
33 | EXPORT_SYMBOL(_copy_to_user) | ||
34 | |||
35 | /* Standard copy_from_user with segment limit checking */ | ||
36 | ENTRY(_copy_from_user) | ||
37 | mov PER_CPU_VAR(current_task), %rax | ||
38 | movq %rsi,%rcx | ||
39 | addq %rdx,%rcx | ||
40 | jc bad_from_user | ||
41 | cmpq TASK_addr_limit(%rax),%rcx | ||
42 | ja bad_from_user | ||
43 | ALTERNATIVE_2 "jmp copy_user_generic_unrolled", \ | ||
44 | "jmp copy_user_generic_string", \ | ||
45 | X86_FEATURE_REP_GOOD, \ | ||
46 | "jmp copy_user_enhanced_fast_string", \ | ||
47 | X86_FEATURE_ERMS | ||
48 | ENDPROC(_copy_from_user) | ||
49 | EXPORT_SYMBOL(_copy_from_user) | ||
50 | |||
51 | |||
52 | .section .fixup,"ax" | ||
53 | /* must zero dest */ | ||
54 | ENTRY(bad_from_user) | ||
55 | bad_from_user: | ||
56 | movl %edx,%ecx | ||
57 | xorl %eax,%eax | ||
58 | rep | ||
59 | stosb | ||
60 | bad_to_user: | ||
61 | movl %edx,%eax | ||
62 | ret | ||
63 | ENDPROC(bad_from_user) | ||
64 | .previous | ||
65 | |||
66 | /* | 19 | /* |
67 | * copy_user_generic_unrolled - memory copy with exception handling. | 20 | * copy_user_generic_unrolled - memory copy with exception handling. |
68 | * This version is for CPUs like P4 that don't have efficient micro | 21 | * This version is for CPUs like P4 that don't have efficient micro |
diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c index b4908789484e..c074799bddae 100644 --- a/arch/x86/lib/usercopy.c +++ b/arch/x86/lib/usercopy.c | |||
@@ -34,3 +34,52 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) | |||
34 | return ret; | 34 | return ret; |
35 | } | 35 | } |
36 | EXPORT_SYMBOL_GPL(copy_from_user_nmi); | 36 | EXPORT_SYMBOL_GPL(copy_from_user_nmi); |
37 | |||
38 | /** | ||
39 | * copy_to_user: - Copy a block of data into user space. | ||
40 | * @to: Destination address, in user space. | ||
41 | * @from: Source address, in kernel space. | ||
42 | * @n: Number of bytes to copy. | ||
43 | * | ||
44 | * Context: User context only. This function may sleep if pagefaults are | ||
45 | * enabled. | ||
46 | * | ||
47 | * Copy data from kernel space to user space. | ||
48 | * | ||
49 | * Returns number of bytes that could not be copied. | ||
50 | * On success, this will be zero. | ||
51 | */ | ||
52 | unsigned long _copy_to_user(void __user *to, const void *from, unsigned n) | ||
53 | { | ||
54 | if (access_ok(VERIFY_WRITE, to, n)) | ||
55 | n = __copy_to_user(to, from, n); | ||
56 | return n; | ||
57 | } | ||
58 | EXPORT_SYMBOL(_copy_to_user); | ||
59 | |||
60 | /** | ||
61 | * copy_from_user: - Copy a block of data from user space. | ||
62 | * @to: Destination address, in kernel space. | ||
63 | * @from: Source address, in user space. | ||
64 | * @n: Number of bytes to copy. | ||
65 | * | ||
66 | * Context: User context only. This function may sleep if pagefaults are | ||
67 | * enabled. | ||
68 | * | ||
69 | * Copy data from user space to kernel space. | ||
70 | * | ||
71 | * Returns number of bytes that could not be copied. | ||
72 | * On success, this will be zero. | ||
73 | * | ||
74 | * If some data could not be copied, this function will pad the copied | ||
75 | * data to the requested size using zero bytes. | ||
76 | */ | ||
77 | unsigned long _copy_from_user(void *to, const void __user *from, unsigned n) | ||
78 | { | ||
79 | if (access_ok(VERIFY_READ, from, n)) | ||
80 | n = __copy_from_user(to, from, n); | ||
81 | else | ||
82 | memset(to, 0, n); | ||
83 | return n; | ||
84 | } | ||
85 | EXPORT_SYMBOL(_copy_from_user); | ||
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c index 3bc7baf2a711..0b281217c890 100644 --- a/arch/x86/lib/usercopy_32.c +++ b/arch/x86/lib/usercopy_32.c | |||
@@ -640,52 +640,3 @@ unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *fr | |||
640 | return n; | 640 | return n; |
641 | } | 641 | } |
642 | EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero); | 642 | EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero); |
643 | |||
644 | /** | ||
645 | * copy_to_user: - Copy a block of data into user space. | ||
646 | * @to: Destination address, in user space. | ||
647 | * @from: Source address, in kernel space. | ||
648 | * @n: Number of bytes to copy. | ||
649 | * | ||
650 | * Context: User context only. This function may sleep if pagefaults are | ||
651 | * enabled. | ||
652 | * | ||
653 | * Copy data from kernel space to user space. | ||
654 | * | ||
655 | * Returns number of bytes that could not be copied. | ||
656 | * On success, this will be zero. | ||
657 | */ | ||
658 | unsigned long _copy_to_user(void __user *to, const void *from, unsigned n) | ||
659 | { | ||
660 | if (access_ok(VERIFY_WRITE, to, n)) | ||
661 | n = __copy_to_user(to, from, n); | ||
662 | return n; | ||
663 | } | ||
664 | EXPORT_SYMBOL(_copy_to_user); | ||
665 | |||
666 | /** | ||
667 | * copy_from_user: - Copy a block of data from user space. | ||
668 | * @to: Destination address, in kernel space. | ||
669 | * @from: Source address, in user space. | ||
670 | * @n: Number of bytes to copy. | ||
671 | * | ||
672 | * Context: User context only. This function may sleep if pagefaults are | ||
673 | * enabled. | ||
674 | * | ||
675 | * Copy data from user space to kernel space. | ||
676 | * | ||
677 | * Returns number of bytes that could not be copied. | ||
678 | * On success, this will be zero. | ||
679 | * | ||
680 | * If some data could not be copied, this function will pad the copied | ||
681 | * data to the requested size using zero bytes. | ||
682 | */ | ||
683 | unsigned long _copy_from_user(void *to, const void __user *from, unsigned n) | ||
684 | { | ||
685 | if (access_ok(VERIFY_READ, from, n)) | ||
686 | n = __copy_from_user(to, from, n); | ||
687 | else | ||
688 | memset(to, 0, n); | ||
689 | return n; | ||
690 | } | ||
691 | EXPORT_SYMBOL(_copy_from_user); | ||
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 9f72ca3b2669..17c55a536fdd 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -679,8 +679,7 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, | |||
679 | printk(KERN_CONT "paging request"); | 679 | printk(KERN_CONT "paging request"); |
680 | 680 | ||
681 | printk(KERN_CONT " at %p\n", (void *) address); | 681 | printk(KERN_CONT " at %p\n", (void *) address); |
682 | printk(KERN_ALERT "IP:"); | 682 | printk(KERN_ALERT "IP: %pS\n", (void *)regs->ip); |
683 | printk_address(regs->ip); | ||
684 | 683 | ||
685 | dump_pagetable(address); | 684 | dump_pagetable(address); |
686 | } | 685 | } |
diff --git a/arch/x86/platform/uv/uv_nmi.c b/arch/x86/platform/uv/uv_nmi.c index cd5173a2733f..8410e7d0a5b5 100644 --- a/arch/x86/platform/uv/uv_nmi.c +++ b/arch/x86/platform/uv/uv_nmi.c | |||
@@ -387,8 +387,8 @@ static void uv_nmi_dump_cpu_ip_hdr(void) | |||
387 | /* Dump Instruction Pointer info */ | 387 | /* Dump Instruction Pointer info */ |
388 | static void uv_nmi_dump_cpu_ip(int cpu, struct pt_regs *regs) | 388 | static void uv_nmi_dump_cpu_ip(int cpu, struct pt_regs *regs) |
389 | { | 389 | { |
390 | pr_info("UV: %4d %6d %-32.32s ", cpu, current->pid, current->comm); | 390 | pr_info("UV: %4d %6d %-32.32s %pS", |
391 | printk_address(regs->ip); | 391 | cpu, current->pid, current->comm, (void *)regs->ip); |
392 | } | 392 | } |
393 | 393 | ||
394 | /* | 394 | /* |
diff --git a/arch/x86/tools/insn_sanity.c b/arch/x86/tools/insn_sanity.c index ba70ff232917..1972565ab106 100644 --- a/arch/x86/tools/insn_sanity.c +++ b/arch/x86/tools/insn_sanity.c | |||
@@ -269,7 +269,8 @@ int main(int argc, char **argv) | |||
269 | insns++; | 269 | insns++; |
270 | } | 270 | } |
271 | 271 | ||
272 | fprintf(stdout, "%s: %s: decoded and checked %d %s instructions with %d errors (seed:0x%x)\n", | 272 | fprintf((errors) ? stderr : stdout, |
273 | "%s: %s: decoded and checked %d %s instructions with %d errors (seed:0x%x)\n", | ||
273 | prog, | 274 | prog, |
274 | (errors) ? "Failure" : "Success", | 275 | (errors) ? "Failure" : "Success", |
275 | insns, | 276 | insns, |
diff --git a/arch/x86/tools/test_get_len.c b/arch/x86/tools/test_get_len.c index 56f04db0c9c0..ecf31e0358c8 100644 --- a/arch/x86/tools/test_get_len.c +++ b/arch/x86/tools/test_get_len.c | |||
@@ -167,7 +167,7 @@ int main(int argc, char **argv) | |||
167 | fprintf(stderr, "Warning: decoded and checked %d" | 167 | fprintf(stderr, "Warning: decoded and checked %d" |
168 | " instructions with %d warnings\n", insns, warnings); | 168 | " instructions with %d warnings\n", insns, warnings); |
169 | else | 169 | else |
170 | fprintf(stderr, "Succeed: decoded and checked %d" | 170 | fprintf(stdout, "Success: decoded and checked %d" |
171 | " instructions\n", insns); | 171 | " instructions\n", insns); |
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 739fb17371af..39b3368f6de6 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -983,13 +983,6 @@ static struct ctl_table kern_table[] = { | |||
983 | .proc_handler = proc_dointvec, | 983 | .proc_handler = proc_dointvec, |
984 | }, | 984 | }, |
985 | { | 985 | { |
986 | .procname = "kstack_depth_to_print", | ||
987 | .data = &kstack_depth_to_print, | ||
988 | .maxlen = sizeof(int), | ||
989 | .mode = 0644, | ||
990 | .proc_handler = proc_dointvec, | ||
991 | }, | ||
992 | { | ||
993 | .procname = "io_delay_type", | 986 | .procname = "io_delay_type", |
994 | .data = &io_delay_type, | 987 | .data = &io_delay_type, |
995 | .maxlen = sizeof(int), | 988 | .maxlen = sizeof(int), |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6de9440e3ae2..61b0988bba8c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -6399,8 +6399,8 @@ unsigned long free_reserved_area(void *start, void *end, int poison, char *s) | |||
6399 | } | 6399 | } |
6400 | 6400 | ||
6401 | if (pages && s) | 6401 | if (pages && s) |
6402 | pr_info("Freeing %s memory: %ldK (%p - %p)\n", | 6402 | pr_info("Freeing %s memory: %ldK\n", |
6403 | s, pages << (PAGE_SHIFT - 10), start, end); | 6403 | s, pages << (PAGE_SHIFT - 10)); |
6404 | 6404 | ||
6405 | return pages; | 6405 | return pages; |
6406 | } | 6406 | } |
diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index c332684e1b5a..5206d99ddeb8 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh | |||
@@ -139,7 +139,8 @@ handle_line() { | |||
139 | 139 | ||
140 | while read line; do | 140 | while read line; do |
141 | # Let's see if we have an address in the line | 141 | # Let's see if we have an address in the line |
142 | if [[ $line =~ \[\<([^]]+)\>\] ]]; then | 142 | if [[ $line =~ \[\<([^]]+)\>\] ]] || |
143 | [[ $line =~ [^+\ ]+\+0x[0-9a-f]+/0x[0-9a-f]+ ]]; then | ||
143 | # Translate address to line numbers | 144 | # Translate address to line numbers |
144 | handle_line "$line" | 145 | handle_line "$line" |
145 | # Is it a code line? | 146 | # Is it a code line? |
diff --git a/scripts/faddr2line b/scripts/faddr2line index 450b33257339..29df825d375c 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line | |||
@@ -105,9 +105,18 @@ __faddr2line() { | |||
105 | # In rare cases there might be duplicates. | 105 | # In rare cases there might be duplicates. |
106 | while read symbol; do | 106 | while read symbol; do |
107 | local fields=($symbol) | 107 | local fields=($symbol) |
108 | local sym_base=0x${fields[1]} | 108 | local sym_base=0x${fields[0]} |
109 | local sym_size=${fields[2]} | 109 | local sym_type=${fields[1]} |
110 | local sym_type=${fields[3]} | 110 | local sym_end=0x${fields[3]} |
111 | |||
112 | # calculate the size | ||
113 | local sym_size=$(($sym_end - $sym_base)) | ||
114 | if [[ -z $sym_size ]] || [[ $sym_size -le 0 ]]; then | ||
115 | warn "bad symbol size: base: $sym_base end: $sym_end" | ||
116 | DONE=1 | ||
117 | return | ||
118 | fi | ||
119 | sym_size=0x$(printf %x $sym_size) | ||
111 | 120 | ||
112 | # calculate the address | 121 | # calculate the address |
113 | local addr=$(($sym_base + $offset)) | 122 | local addr=$(($sym_base + $offset)) |
@@ -116,26 +125,26 @@ __faddr2line() { | |||
116 | DONE=1 | 125 | DONE=1 |
117 | return | 126 | return |
118 | fi | 127 | fi |
119 | local hexaddr=0x$(printf %x $addr) | 128 | addr=0x$(printf %x $addr) |
120 | 129 | ||
121 | # weed out non-function symbols | 130 | # weed out non-function symbols |
122 | if [[ $sym_type != "FUNC" ]]; then | 131 | if [[ $sym_type != t ]] && [[ $sym_type != T ]]; then |
123 | [[ $print_warnings = 1 ]] && | 132 | [[ $print_warnings = 1 ]] && |
124 | echo "skipping $func address at $hexaddr due to non-function symbol" | 133 | echo "skipping $func address at $addr due to non-function symbol of type '$sym_type'" |
125 | continue | 134 | continue |
126 | fi | 135 | fi |
127 | 136 | ||
128 | # if the user provided a size, make sure it matches the symbol's size | 137 | # if the user provided a size, make sure it matches the symbol's size |
129 | if [[ -n $size ]] && [[ $size -ne $sym_size ]]; then | 138 | if [[ -n $size ]] && [[ $size -ne $sym_size ]]; then |
130 | [[ $print_warnings = 1 ]] && | 139 | [[ $print_warnings = 1 ]] && |
131 | echo "skipping $func address at $hexaddr due to size mismatch ($size != $sym_size)" | 140 | echo "skipping $func address at $addr due to size mismatch ($size != $sym_size)" |
132 | continue; | 141 | continue; |
133 | fi | 142 | fi |
134 | 143 | ||
135 | # make sure the provided offset is within the symbol's range | 144 | # make sure the provided offset is within the symbol's range |
136 | if [[ $offset -gt $sym_size ]]; then | 145 | if [[ $offset -gt $sym_size ]]; then |
137 | [[ $print_warnings = 1 ]] && | 146 | [[ $print_warnings = 1 ]] && |
138 | echo "skipping $func address at $hexaddr due to size mismatch ($offset > $sym_size)" | 147 | echo "skipping $func address at $addr due to size mismatch ($offset > $sym_size)" |
139 | continue | 148 | continue |
140 | fi | 149 | fi |
141 | 150 | ||
@@ -143,12 +152,12 @@ __faddr2line() { | |||
143 | [[ $FIRST = 0 ]] && echo | 152 | [[ $FIRST = 0 ]] && echo |
144 | FIRST=0 | 153 | FIRST=0 |
145 | 154 | ||
146 | local hexsize=0x$(printf %x $sym_size) | 155 | # pass real address to addr2line |
147 | echo "$func+$offset/$hexsize:" | 156 | echo "$func+$offset/$sym_size:" |
148 | addr2line -fpie $objfile $hexaddr | sed "s; $dir_prefix\(\./\)*; ;" | 157 | addr2line -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;" |
149 | DONE=1 | 158 | DONE=1 |
150 | 159 | ||
151 | done < <(readelf -sW $objfile | awk -v f=$func '$8 == f {print}') | 160 | done < <(nm -n $objfile | awk -v fn=$func '$3 == fn { found=1; line=$0; start=$1; next } found == 1 { found=0; print line, $1 }') |
152 | } | 161 | } |
153 | 162 | ||
154 | [[ $# -lt 2 ]] && usage | 163 | [[ $# -lt 2 ]] && usage |
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index a89f80a5b711..8c1cb423cfe6 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile | |||
@@ -6,7 +6,7 @@ include ../lib.mk | |||
6 | 6 | ||
7 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ | 7 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ |
8 | check_initial_reg_state sigreturn ldt_gdt iopl \ | 8 | check_initial_reg_state sigreturn ldt_gdt iopl \ |
9 | protection_keys | 9 | protection_keys test_vdso |
10 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ | 10 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ |
11 | test_FCMOV test_FCOMI test_FISTTP \ | 11 | test_FCMOV test_FCOMI test_FISTTP \ |
12 | vdso_restorer | 12 | vdso_restorer |
diff --git a/tools/testing/selftests/x86/test_vdso.c b/tools/testing/selftests/x86/test_vdso.c new file mode 100644 index 000000000000..65d7a2bf7e14 --- /dev/null +++ b/tools/testing/selftests/x86/test_vdso.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * ldt_gdt.c - Test cases for LDT and GDT access | ||
3 | * Copyright (c) 2011-2015 Andrew Lutomirski | ||
4 | */ | ||
5 | |||
6 | #define _GNU_SOURCE | ||
7 | |||
8 | #include <stdio.h> | ||
9 | #include <sys/time.h> | ||
10 | #include <time.h> | ||
11 | #include <stdlib.h> | ||
12 | #include <unistd.h> | ||
13 | #include <sys/syscall.h> | ||
14 | #include <dlfcn.h> | ||
15 | #include <string.h> | ||
16 | #include <errno.h> | ||
17 | #include <sched.h> | ||
18 | #include <stdbool.h> | ||
19 | |||
20 | #ifndef SYS_getcpu | ||
21 | # ifdef __x86_64__ | ||
22 | # define SYS_getcpu 309 | ||
23 | # else | ||
24 | # define SYS_getcpu 318 | ||
25 | # endif | ||
26 | #endif | ||
27 | |||
28 | int nerrs = 0; | ||
29 | |||
30 | #ifdef __x86_64__ | ||
31 | # define VSYS(x) (x) | ||
32 | #else | ||
33 | # define VSYS(x) 0 | ||
34 | #endif | ||
35 | |||
36 | typedef long (*getcpu_t)(unsigned *, unsigned *, void *); | ||
37 | |||
38 | const getcpu_t vgetcpu = (getcpu_t)VSYS(0xffffffffff600800); | ||
39 | getcpu_t vdso_getcpu; | ||
40 | |||
41 | void fill_function_pointers() | ||
42 | { | ||
43 | void *vdso = dlopen("linux-vdso.so.1", | ||
44 | RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); | ||
45 | if (!vdso) | ||
46 | vdso = dlopen("linux-gate.so.1", | ||
47 | RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); | ||
48 | if (!vdso) { | ||
49 | printf("[WARN]\tfailed to find vDSO\n"); | ||
50 | return; | ||
51 | } | ||
52 | |||
53 | vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu"); | ||
54 | if (!vdso_getcpu) | ||
55 | printf("Warning: failed to find getcpu in vDSO\n"); | ||
56 | } | ||
57 | |||
58 | static long sys_getcpu(unsigned * cpu, unsigned * node, | ||
59 | void* cache) | ||
60 | { | ||
61 | return syscall(__NR_getcpu, cpu, node, cache); | ||
62 | } | ||
63 | |||
64 | static void test_getcpu(void) | ||
65 | { | ||
66 | printf("[RUN]\tTesting getcpu...\n"); | ||
67 | |||
68 | for (int cpu = 0; ; cpu++) { | ||
69 | cpu_set_t cpuset; | ||
70 | CPU_ZERO(&cpuset); | ||
71 | CPU_SET(cpu, &cpuset); | ||
72 | if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) | ||
73 | return; | ||
74 | |||
75 | unsigned cpu_sys, cpu_vdso, cpu_vsys, | ||
76 | node_sys, node_vdso, node_vsys; | ||
77 | long ret_sys, ret_vdso = 1, ret_vsys = 1; | ||
78 | unsigned node; | ||
79 | |||
80 | ret_sys = sys_getcpu(&cpu_sys, &node_sys, 0); | ||
81 | if (vdso_getcpu) | ||
82 | ret_vdso = vdso_getcpu(&cpu_vdso, &node_vdso, 0); | ||
83 | if (vgetcpu) | ||
84 | ret_vsys = vgetcpu(&cpu_vsys, &node_vsys, 0); | ||
85 | |||
86 | if (!ret_sys) | ||
87 | node = node_sys; | ||
88 | else if (!ret_vdso) | ||
89 | node = node_vdso; | ||
90 | else if (!ret_vsys) | ||
91 | node = node_vsys; | ||
92 | |||
93 | bool ok = true; | ||
94 | if (!ret_sys && (cpu_sys != cpu || node_sys != node)) | ||
95 | ok = false; | ||
96 | if (!ret_vdso && (cpu_vdso != cpu || node_vdso != node)) | ||
97 | ok = false; | ||
98 | if (!ret_vsys && (cpu_vsys != cpu || node_vsys != node)) | ||
99 | ok = false; | ||
100 | |||
101 | printf("[%s]\tCPU %u:", ok ? "OK" : "FAIL", cpu); | ||
102 | if (!ret_sys) | ||
103 | printf(" syscall: cpu %u, node %u", cpu_sys, node_sys); | ||
104 | if (!ret_vdso) | ||
105 | printf(" vdso: cpu %u, node %u", cpu_vdso, node_vdso); | ||
106 | if (!ret_vsys) | ||
107 | printf(" vsyscall: cpu %u, node %u", cpu_vsys, | ||
108 | node_vsys); | ||
109 | printf("\n"); | ||
110 | |||
111 | if (!ok) | ||
112 | nerrs++; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | int main(int argc, char **argv) | ||
117 | { | ||
118 | fill_function_pointers(); | ||
119 | |||
120 | test_getcpu(); | ||
121 | |||
122 | return nerrs ? 1 : 0; | ||
123 | } | ||