diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-14 20:02:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-14 20:02:15 -0500 |
commit | d4667ca142610961c89ae7c41a823b3358fcdd0e (patch) | |
tree | ff43d39e20feaf477a1ceaf35eba841eebd7e0a6 | |
parent | 6556677a80400ca5744340d8ff6fbed22621293e (diff) | |
parent | e48657573481a5dff7cfdc3d57005c80aa816500 (diff) |
Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 PTI and Spectre related fixes and updates from Ingo Molnar:
"Here's the latest set of Spectre and PTI related fixes and updates:
Spectre:
- Add entry code register clearing to reduce the Spectre attack
surface
- Update the Spectre microcode blacklist
- Inline the KVM Spectre helpers to get close to v4.14 performance
again.
- Fix indirect_branch_prediction_barrier()
- Fix/improve Spectre related kernel messages
- Fix array_index_nospec_mask() asm constraint
- KVM: fix two MSR handling bugs
PTI:
- Fix a paranoid entry PTI CR3 handling bug
- Fix comments
objtool:
- Fix paranoid_entry() frame pointer warning
- Annotate WARN()-related UD2 as reachable
- Various fixes
- Add Add Peter Zijlstra as objtool co-maintainer
Misc:
- Various x86 entry code self-test fixes
- Improve/simplify entry code stack frame generation and handling
after recent heavy-handed PTI and Spectre changes. (There's two
more WIP improvements expected here.)
- Type fix for cache entries
There's also some low risk non-fix changes I've included in this
branch to reduce backporting conflicts:
- rename a confusing x86_cpu field name
- de-obfuscate the naming of single-TLB flushing primitives"
* 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (41 commits)
x86/entry/64: Fix CR3 restore in paranoid_exit()
x86/cpu: Change type of x86_cache_size variable to unsigned int
x86/spectre: Fix an error message
x86/cpu: Rename cpu_data.x86_mask to cpu_data.x86_stepping
selftests/x86/mpx: Fix incorrect bounds with old _sigfault
x86/mm: Rename flush_tlb_single() and flush_tlb_one() to __flush_tlb_one_[user|kernel]()
x86/speculation: Add <asm/msr-index.h> dependency
nospec: Move array_index_nospec() parameter checking into separate macro
x86/speculation: Fix up array_index_nospec_mask() asm constraint
x86/debug: Use UD2 for WARN()
x86/debug, objtool: Annotate WARN()-related UD2 as reachable
objtool: Fix segfault in ignore_unreachable_insn()
selftests/x86: Disable tests requiring 32-bit support on pure 64-bit systems
selftests/x86: Do not rely on "int $0x80" in single_step_syscall.c
selftests/x86: Do not rely on "int $0x80" in test_mremap_vdso.c
selftests/x86: Fix build bug caused by the 5lvl test which has been moved to the VM directory
selftests/x86/pkeys: Remove unused functions
selftests/x86: Clean up and document sscanf() usage
selftests/x86: Fix vDSO selftest segfault for vsyscall=none
x86/entry/64: Remove the unused 'icebp' macro
...
69 files changed, 444 insertions, 362 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index a4dcdd35d9a3..9a7f76eadae9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -9946,6 +9946,7 @@ F: drivers/nfc/nxp-nci | |||
9946 | 9946 | ||
9947 | OBJTOOL | 9947 | OBJTOOL |
9948 | M: Josh Poimboeuf <jpoimboe@redhat.com> | 9948 | M: Josh Poimboeuf <jpoimboe@redhat.com> |
9949 | M: Peter Zijlstra <peterz@infradead.org> | ||
9949 | S: Supported | 9950 | S: Supported |
9950 | F: tools/objtool/ | 9951 | F: tools/objtool/ |
9951 | 9952 | ||
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index 3f48f695d5e6..dce7092ab24a 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h | |||
@@ -97,80 +97,69 @@ For 32-bit we have the following conventions - kernel is built with | |||
97 | 97 | ||
98 | #define SIZEOF_PTREGS 21*8 | 98 | #define SIZEOF_PTREGS 21*8 |
99 | 99 | ||
100 | .macro ALLOC_PT_GPREGS_ON_STACK | 100 | .macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax |
101 | addq $-(15*8), %rsp | 101 | /* |
102 | .endm | 102 | * Push registers and sanitize registers of values that a |
103 | * speculation attack might otherwise want to exploit. The | ||
104 | * lower registers are likely clobbered well before they | ||
105 | * could be put to use in a speculative execution gadget. | ||
106 | * Interleave XOR with PUSH for better uop scheduling: | ||
107 | */ | ||
108 | pushq %rdi /* pt_regs->di */ | ||
109 | pushq %rsi /* pt_regs->si */ | ||
110 | pushq \rdx /* pt_regs->dx */ | ||
111 | pushq %rcx /* pt_regs->cx */ | ||
112 | pushq \rax /* pt_regs->ax */ | ||
113 | pushq %r8 /* pt_regs->r8 */ | ||
114 | xorq %r8, %r8 /* nospec r8 */ | ||
115 | pushq %r9 /* pt_regs->r9 */ | ||
116 | xorq %r9, %r9 /* nospec r9 */ | ||
117 | pushq %r10 /* pt_regs->r10 */ | ||
118 | xorq %r10, %r10 /* nospec r10 */ | ||
119 | pushq %r11 /* pt_regs->r11 */ | ||
120 | xorq %r11, %r11 /* nospec r11*/ | ||
121 | pushq %rbx /* pt_regs->rbx */ | ||
122 | xorl %ebx, %ebx /* nospec rbx*/ | ||
123 | pushq %rbp /* pt_regs->rbp */ | ||
124 | xorl %ebp, %ebp /* nospec rbp*/ | ||
125 | pushq %r12 /* pt_regs->r12 */ | ||
126 | xorq %r12, %r12 /* nospec r12*/ | ||
127 | pushq %r13 /* pt_regs->r13 */ | ||
128 | xorq %r13, %r13 /* nospec r13*/ | ||
129 | pushq %r14 /* pt_regs->r14 */ | ||
130 | xorq %r14, %r14 /* nospec r14*/ | ||
131 | pushq %r15 /* pt_regs->r15 */ | ||
132 | xorq %r15, %r15 /* nospec r15*/ | ||
133 | UNWIND_HINT_REGS | ||
134 | .endm | ||
103 | 135 | ||
104 | .macro SAVE_C_REGS_HELPER offset=0 rax=1 rcx=1 r8910=1 r11=1 | 136 | .macro POP_REGS pop_rdi=1 skip_r11rcx=0 |
105 | .if \r11 | ||
106 | movq %r11, 6*8+\offset(%rsp) | ||
107 | .endif | ||
108 | .if \r8910 | ||
109 | movq %r10, 7*8+\offset(%rsp) | ||
110 | movq %r9, 8*8+\offset(%rsp) | ||
111 | movq %r8, 9*8+\offset(%rsp) | ||
112 | .endif | ||
113 | .if \rax | ||
114 | movq %rax, 10*8+\offset(%rsp) | ||
115 | .endif | ||
116 | .if \rcx | ||
117 | movq %rcx, 11*8+\offset(%rsp) | ||
118 | .endif | ||
119 | movq %rdx, 12*8+\offset(%rsp) | ||
120 | movq %rsi, 13*8+\offset(%rsp) | ||
121 | movq %rdi, 14*8+\offset(%rsp) | ||
122 | UNWIND_HINT_REGS offset=\offset extra=0 | ||
123 | .endm | ||
124 | .macro SAVE_C_REGS offset=0 | ||
125 | SAVE_C_REGS_HELPER \offset, 1, 1, 1, 1 | ||
126 | .endm | ||
127 | .macro SAVE_C_REGS_EXCEPT_RAX_RCX offset=0 | ||
128 | SAVE_C_REGS_HELPER \offset, 0, 0, 1, 1 | ||
129 | .endm | ||
130 | .macro SAVE_C_REGS_EXCEPT_R891011 | ||
131 | SAVE_C_REGS_HELPER 0, 1, 1, 0, 0 | ||
132 | .endm | ||
133 | .macro SAVE_C_REGS_EXCEPT_RCX_R891011 | ||
134 | SAVE_C_REGS_HELPER 0, 1, 0, 0, 0 | ||
135 | .endm | ||
136 | .macro SAVE_C_REGS_EXCEPT_RAX_RCX_R11 | ||
137 | SAVE_C_REGS_HELPER 0, 0, 0, 1, 0 | ||
138 | .endm | ||
139 | |||
140 | .macro SAVE_EXTRA_REGS offset=0 | ||
141 | movq %r15, 0*8+\offset(%rsp) | ||
142 | movq %r14, 1*8+\offset(%rsp) | ||
143 | movq %r13, 2*8+\offset(%rsp) | ||
144 | movq %r12, 3*8+\offset(%rsp) | ||
145 | movq %rbp, 4*8+\offset(%rsp) | ||
146 | movq %rbx, 5*8+\offset(%rsp) | ||
147 | UNWIND_HINT_REGS offset=\offset | ||
148 | .endm | ||
149 | |||
150 | .macro POP_EXTRA_REGS | ||
151 | popq %r15 | 137 | popq %r15 |
152 | popq %r14 | 138 | popq %r14 |
153 | popq %r13 | 139 | popq %r13 |
154 | popq %r12 | 140 | popq %r12 |
155 | popq %rbp | 141 | popq %rbp |
156 | popq %rbx | 142 | popq %rbx |
157 | .endm | 143 | .if \skip_r11rcx |
158 | 144 | popq %rsi | |
159 | .macro POP_C_REGS | 145 | .else |
160 | popq %r11 | 146 | popq %r11 |
147 | .endif | ||
161 | popq %r10 | 148 | popq %r10 |
162 | popq %r9 | 149 | popq %r9 |
163 | popq %r8 | 150 | popq %r8 |
164 | popq %rax | 151 | popq %rax |
152 | .if \skip_r11rcx | ||
153 | popq %rsi | ||
154 | .else | ||
165 | popq %rcx | 155 | popq %rcx |
156 | .endif | ||
166 | popq %rdx | 157 | popq %rdx |
167 | popq %rsi | 158 | popq %rsi |
159 | .if \pop_rdi | ||
168 | popq %rdi | 160 | popq %rdi |
169 | .endm | 161 | .endif |
170 | 162 | .endm | |
171 | .macro icebp | ||
172 | .byte 0xf1 | ||
173 | .endm | ||
174 | 163 | ||
175 | /* | 164 | /* |
176 | * This is a sneaky trick to help the unwinder find pt_regs on the stack. The | 165 | * This is a sneaky trick to help the unwinder find pt_regs on the stack. The |
@@ -178,7 +167,7 @@ For 32-bit we have the following conventions - kernel is built with | |||
178 | * is just setting the LSB, which makes it an invalid stack address and is also | 167 | * is just setting the LSB, which makes it an invalid stack address and is also |
179 | * a signal to the unwinder that it's a pt_regs pointer in disguise. | 168 | * a signal to the unwinder that it's a pt_regs pointer in disguise. |
180 | * | 169 | * |
181 | * NOTE: This macro must be used *after* SAVE_EXTRA_REGS because it corrupts | 170 | * NOTE: This macro must be used *after* PUSH_AND_CLEAR_REGS because it corrupts |
182 | * the original rbp. | 171 | * the original rbp. |
183 | */ | 172 | */ |
184 | .macro ENCODE_FRAME_POINTER ptregs_offset=0 | 173 | .macro ENCODE_FRAME_POINTER ptregs_offset=0 |
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 30c8c5344c4a..8971bd64d515 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S | |||
@@ -213,7 +213,7 @@ ENTRY(entry_SYSCALL_64) | |||
213 | 213 | ||
214 | swapgs | 214 | swapgs |
215 | /* | 215 | /* |
216 | * This path is not taken when PAGE_TABLE_ISOLATION is disabled so it | 216 | * This path is only taken when PAGE_TABLE_ISOLATION is disabled so it |
217 | * is not required to switch CR3. | 217 | * is not required to switch CR3. |
218 | */ | 218 | */ |
219 | movq %rsp, PER_CPU_VAR(rsp_scratch) | 219 | movq %rsp, PER_CPU_VAR(rsp_scratch) |
@@ -227,22 +227,8 @@ ENTRY(entry_SYSCALL_64) | |||
227 | pushq %rcx /* pt_regs->ip */ | 227 | pushq %rcx /* pt_regs->ip */ |
228 | GLOBAL(entry_SYSCALL_64_after_hwframe) | 228 | GLOBAL(entry_SYSCALL_64_after_hwframe) |
229 | pushq %rax /* pt_regs->orig_ax */ | 229 | pushq %rax /* pt_regs->orig_ax */ |
230 | pushq %rdi /* pt_regs->di */ | 230 | |
231 | pushq %rsi /* pt_regs->si */ | 231 | PUSH_AND_CLEAR_REGS rax=$-ENOSYS |
232 | pushq %rdx /* pt_regs->dx */ | ||
233 | pushq %rcx /* pt_regs->cx */ | ||
234 | pushq $-ENOSYS /* pt_regs->ax */ | ||
235 | pushq %r8 /* pt_regs->r8 */ | ||
236 | pushq %r9 /* pt_regs->r9 */ | ||
237 | pushq %r10 /* pt_regs->r10 */ | ||
238 | pushq %r11 /* pt_regs->r11 */ | ||
239 | pushq %rbx /* pt_regs->rbx */ | ||
240 | pushq %rbp /* pt_regs->rbp */ | ||
241 | pushq %r12 /* pt_regs->r12 */ | ||
242 | pushq %r13 /* pt_regs->r13 */ | ||
243 | pushq %r14 /* pt_regs->r14 */ | ||
244 | pushq %r15 /* pt_regs->r15 */ | ||
245 | UNWIND_HINT_REGS | ||
246 | 232 | ||
247 | TRACE_IRQS_OFF | 233 | TRACE_IRQS_OFF |
248 | 234 | ||
@@ -321,15 +307,7 @@ GLOBAL(entry_SYSCALL_64_after_hwframe) | |||
321 | syscall_return_via_sysret: | 307 | syscall_return_via_sysret: |
322 | /* rcx and r11 are already restored (see code above) */ | 308 | /* rcx and r11 are already restored (see code above) */ |
323 | UNWIND_HINT_EMPTY | 309 | UNWIND_HINT_EMPTY |
324 | POP_EXTRA_REGS | 310 | POP_REGS pop_rdi=0 skip_r11rcx=1 |
325 | popq %rsi /* skip r11 */ | ||
326 | popq %r10 | ||
327 | popq %r9 | ||
328 | popq %r8 | ||
329 | popq %rax | ||
330 | popq %rsi /* skip rcx */ | ||
331 | popq %rdx | ||
332 | popq %rsi | ||
333 | 311 | ||
334 | /* | 312 | /* |
335 | * Now all regs are restored except RSP and RDI. | 313 | * Now all regs are restored except RSP and RDI. |
@@ -559,9 +537,7 @@ END(irq_entries_start) | |||
559 | call switch_to_thread_stack | 537 | call switch_to_thread_stack |
560 | 1: | 538 | 1: |
561 | 539 | ||
562 | ALLOC_PT_GPREGS_ON_STACK | 540 | PUSH_AND_CLEAR_REGS |
563 | SAVE_C_REGS | ||
564 | SAVE_EXTRA_REGS | ||
565 | ENCODE_FRAME_POINTER | 541 | ENCODE_FRAME_POINTER |
566 | 542 | ||
567 | testb $3, CS(%rsp) | 543 | testb $3, CS(%rsp) |
@@ -622,15 +598,7 @@ GLOBAL(swapgs_restore_regs_and_return_to_usermode) | |||
622 | ud2 | 598 | ud2 |
623 | 1: | 599 | 1: |
624 | #endif | 600 | #endif |
625 | POP_EXTRA_REGS | 601 | POP_REGS pop_rdi=0 |
626 | popq %r11 | ||
627 | popq %r10 | ||
628 | popq %r9 | ||
629 | popq %r8 | ||
630 | popq %rax | ||
631 | popq %rcx | ||
632 | popq %rdx | ||
633 | popq %rsi | ||
634 | 602 | ||
635 | /* | 603 | /* |
636 | * The stack is now user RDI, orig_ax, RIP, CS, EFLAGS, RSP, SS. | 604 | * The stack is now user RDI, orig_ax, RIP, CS, EFLAGS, RSP, SS. |
@@ -688,8 +656,7 @@ GLOBAL(restore_regs_and_return_to_kernel) | |||
688 | ud2 | 656 | ud2 |
689 | 1: | 657 | 1: |
690 | #endif | 658 | #endif |
691 | POP_EXTRA_REGS | 659 | POP_REGS |
692 | POP_C_REGS | ||
693 | addq $8, %rsp /* skip regs->orig_ax */ | 660 | addq $8, %rsp /* skip regs->orig_ax */ |
694 | /* | 661 | /* |
695 | * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization | 662 | * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization |
@@ -908,7 +875,9 @@ ENTRY(\sym) | |||
908 | pushq $-1 /* ORIG_RAX: no syscall to restart */ | 875 | pushq $-1 /* ORIG_RAX: no syscall to restart */ |
909 | .endif | 876 | .endif |
910 | 877 | ||
911 | ALLOC_PT_GPREGS_ON_STACK | 878 | /* Save all registers in pt_regs */ |
879 | PUSH_AND_CLEAR_REGS | ||
880 | ENCODE_FRAME_POINTER | ||
912 | 881 | ||
913 | .if \paranoid < 2 | 882 | .if \paranoid < 2 |
914 | testb $3, CS(%rsp) /* If coming from userspace, switch stacks */ | 883 | testb $3, CS(%rsp) /* If coming from userspace, switch stacks */ |
@@ -1121,9 +1090,7 @@ ENTRY(xen_failsafe_callback) | |||
1121 | addq $0x30, %rsp | 1090 | addq $0x30, %rsp |
1122 | UNWIND_HINT_IRET_REGS | 1091 | UNWIND_HINT_IRET_REGS |
1123 | pushq $-1 /* orig_ax = -1 => not a system call */ | 1092 | pushq $-1 /* orig_ax = -1 => not a system call */ |
1124 | ALLOC_PT_GPREGS_ON_STACK | 1093 | PUSH_AND_CLEAR_REGS |
1125 | SAVE_C_REGS | ||
1126 | SAVE_EXTRA_REGS | ||
1127 | ENCODE_FRAME_POINTER | 1094 | ENCODE_FRAME_POINTER |
1128 | jmp error_exit | 1095 | jmp error_exit |
1129 | END(xen_failsafe_callback) | 1096 | END(xen_failsafe_callback) |
@@ -1163,16 +1130,13 @@ idtentry machine_check do_mce has_error_code=0 paranoid=1 | |||
1163 | #endif | 1130 | #endif |
1164 | 1131 | ||
1165 | /* | 1132 | /* |
1166 | * Save all registers in pt_regs, and switch gs if needed. | 1133 | * Switch gs if needed. |
1167 | * Use slow, but surefire "are we in kernel?" check. | 1134 | * Use slow, but surefire "are we in kernel?" check. |
1168 | * Return: ebx=0: need swapgs on exit, ebx=1: otherwise | 1135 | * Return: ebx=0: need swapgs on exit, ebx=1: otherwise |
1169 | */ | 1136 | */ |
1170 | ENTRY(paranoid_entry) | 1137 | ENTRY(paranoid_entry) |
1171 | UNWIND_HINT_FUNC | 1138 | UNWIND_HINT_FUNC |
1172 | cld | 1139 | cld |
1173 | SAVE_C_REGS 8 | ||
1174 | SAVE_EXTRA_REGS 8 | ||
1175 | ENCODE_FRAME_POINTER 8 | ||
1176 | movl $1, %ebx | 1140 | movl $1, %ebx |
1177 | movl $MSR_GS_BASE, %ecx | 1141 | movl $MSR_GS_BASE, %ecx |
1178 | rdmsr | 1142 | rdmsr |
@@ -1211,21 +1175,18 @@ ENTRY(paranoid_exit) | |||
1211 | jmp .Lparanoid_exit_restore | 1175 | jmp .Lparanoid_exit_restore |
1212 | .Lparanoid_exit_no_swapgs: | 1176 | .Lparanoid_exit_no_swapgs: |
1213 | TRACE_IRQS_IRETQ_DEBUG | 1177 | TRACE_IRQS_IRETQ_DEBUG |
1178 | RESTORE_CR3 scratch_reg=%rbx save_reg=%r14 | ||
1214 | .Lparanoid_exit_restore: | 1179 | .Lparanoid_exit_restore: |
1215 | jmp restore_regs_and_return_to_kernel | 1180 | jmp restore_regs_and_return_to_kernel |
1216 | END(paranoid_exit) | 1181 | END(paranoid_exit) |
1217 | 1182 | ||
1218 | /* | 1183 | /* |
1219 | * Save all registers in pt_regs, and switch gs if needed. | 1184 | * Switch gs if needed. |
1220 | * Return: EBX=0: came from user mode; EBX=1: otherwise | 1185 | * Return: EBX=0: came from user mode; EBX=1: otherwise |
1221 | */ | 1186 | */ |
1222 | ENTRY(error_entry) | 1187 | ENTRY(error_entry) |
1223 | UNWIND_HINT_FUNC | 1188 | UNWIND_HINT_REGS offset=8 |
1224 | cld | 1189 | cld |
1225 | SAVE_C_REGS 8 | ||
1226 | SAVE_EXTRA_REGS 8 | ||
1227 | ENCODE_FRAME_POINTER 8 | ||
1228 | xorl %ebx, %ebx | ||
1229 | testb $3, CS+8(%rsp) | 1190 | testb $3, CS+8(%rsp) |
1230 | jz .Lerror_kernelspace | 1191 | jz .Lerror_kernelspace |
1231 | 1192 | ||
@@ -1406,22 +1367,7 @@ ENTRY(nmi) | |||
1406 | pushq 1*8(%rdx) /* pt_regs->rip */ | 1367 | pushq 1*8(%rdx) /* pt_regs->rip */ |
1407 | UNWIND_HINT_IRET_REGS | 1368 | UNWIND_HINT_IRET_REGS |
1408 | pushq $-1 /* pt_regs->orig_ax */ | 1369 | pushq $-1 /* pt_regs->orig_ax */ |
1409 | pushq %rdi /* pt_regs->di */ | 1370 | PUSH_AND_CLEAR_REGS rdx=(%rdx) |
1410 | pushq %rsi /* pt_regs->si */ | ||
1411 | pushq (%rdx) /* pt_regs->dx */ | ||
1412 | pushq %rcx /* pt_regs->cx */ | ||
1413 | pushq %rax /* pt_regs->ax */ | ||
1414 | pushq %r8 /* pt_regs->r8 */ | ||
1415 | pushq %r9 /* pt_regs->r9 */ | ||
1416 | pushq %r10 /* pt_regs->r10 */ | ||
1417 | pushq %r11 /* pt_regs->r11 */ | ||
1418 | pushq %rbx /* pt_regs->rbx */ | ||
1419 | pushq %rbp /* pt_regs->rbp */ | ||
1420 | pushq %r12 /* pt_regs->r12 */ | ||
1421 | pushq %r13 /* pt_regs->r13 */ | ||
1422 | pushq %r14 /* pt_regs->r14 */ | ||
1423 | pushq %r15 /* pt_regs->r15 */ | ||
1424 | UNWIND_HINT_REGS | ||
1425 | ENCODE_FRAME_POINTER | 1371 | ENCODE_FRAME_POINTER |
1426 | 1372 | ||
1427 | /* | 1373 | /* |
@@ -1631,7 +1577,8 @@ end_repeat_nmi: | |||
1631 | * frame to point back to repeat_nmi. | 1577 | * frame to point back to repeat_nmi. |
1632 | */ | 1578 | */ |
1633 | pushq $-1 /* ORIG_RAX: no syscall to restart */ | 1579 | pushq $-1 /* ORIG_RAX: no syscall to restart */ |
1634 | ALLOC_PT_GPREGS_ON_STACK | 1580 | PUSH_AND_CLEAR_REGS |
1581 | ENCODE_FRAME_POINTER | ||
1635 | 1582 | ||
1636 | /* | 1583 | /* |
1637 | * Use paranoid_entry to handle SWAPGS, but no need to use paranoid_exit | 1584 | * Use paranoid_entry to handle SWAPGS, but no need to use paranoid_exit |
@@ -1655,8 +1602,7 @@ end_repeat_nmi: | |||
1655 | nmi_swapgs: | 1602 | nmi_swapgs: |
1656 | SWAPGS_UNSAFE_STACK | 1603 | SWAPGS_UNSAFE_STACK |
1657 | nmi_restore: | 1604 | nmi_restore: |
1658 | POP_EXTRA_REGS | 1605 | POP_REGS |
1659 | POP_C_REGS | ||
1660 | 1606 | ||
1661 | /* | 1607 | /* |
1662 | * Skip orig_ax and the "outermost" frame to point RSP at the "iret" | 1608 | * Skip orig_ax and the "outermost" frame to point RSP at the "iret" |
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index 98d5358e4041..fd65e016e413 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S | |||
@@ -85,15 +85,25 @@ ENTRY(entry_SYSENTER_compat) | |||
85 | pushq %rcx /* pt_regs->cx */ | 85 | pushq %rcx /* pt_regs->cx */ |
86 | pushq $-ENOSYS /* pt_regs->ax */ | 86 | pushq $-ENOSYS /* pt_regs->ax */ |
87 | pushq $0 /* pt_regs->r8 = 0 */ | 87 | pushq $0 /* pt_regs->r8 = 0 */ |
88 | xorq %r8, %r8 /* nospec r8 */ | ||
88 | pushq $0 /* pt_regs->r9 = 0 */ | 89 | pushq $0 /* pt_regs->r9 = 0 */ |
90 | xorq %r9, %r9 /* nospec r9 */ | ||
89 | pushq $0 /* pt_regs->r10 = 0 */ | 91 | pushq $0 /* pt_regs->r10 = 0 */ |
92 | xorq %r10, %r10 /* nospec r10 */ | ||
90 | pushq $0 /* pt_regs->r11 = 0 */ | 93 | pushq $0 /* pt_regs->r11 = 0 */ |
94 | xorq %r11, %r11 /* nospec r11 */ | ||
91 | pushq %rbx /* pt_regs->rbx */ | 95 | pushq %rbx /* pt_regs->rbx */ |
96 | xorl %ebx, %ebx /* nospec rbx */ | ||
92 | pushq %rbp /* pt_regs->rbp (will be overwritten) */ | 97 | pushq %rbp /* pt_regs->rbp (will be overwritten) */ |
98 | xorl %ebp, %ebp /* nospec rbp */ | ||
93 | pushq $0 /* pt_regs->r12 = 0 */ | 99 | pushq $0 /* pt_regs->r12 = 0 */ |
100 | xorq %r12, %r12 /* nospec r12 */ | ||
94 | pushq $0 /* pt_regs->r13 = 0 */ | 101 | pushq $0 /* pt_regs->r13 = 0 */ |
102 | xorq %r13, %r13 /* nospec r13 */ | ||
95 | pushq $0 /* pt_regs->r14 = 0 */ | 103 | pushq $0 /* pt_regs->r14 = 0 */ |
104 | xorq %r14, %r14 /* nospec r14 */ | ||
96 | pushq $0 /* pt_regs->r15 = 0 */ | 105 | pushq $0 /* pt_regs->r15 = 0 */ |
106 | xorq %r15, %r15 /* nospec r15 */ | ||
97 | cld | 107 | cld |
98 | 108 | ||
99 | /* | 109 | /* |
@@ -214,15 +224,25 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe) | |||
214 | pushq %rbp /* pt_regs->cx (stashed in bp) */ | 224 | pushq %rbp /* pt_regs->cx (stashed in bp) */ |
215 | pushq $-ENOSYS /* pt_regs->ax */ | 225 | pushq $-ENOSYS /* pt_regs->ax */ |
216 | pushq $0 /* pt_regs->r8 = 0 */ | 226 | pushq $0 /* pt_regs->r8 = 0 */ |
227 | xorq %r8, %r8 /* nospec r8 */ | ||
217 | pushq $0 /* pt_regs->r9 = 0 */ | 228 | pushq $0 /* pt_regs->r9 = 0 */ |
229 | xorq %r9, %r9 /* nospec r9 */ | ||
218 | pushq $0 /* pt_regs->r10 = 0 */ | 230 | pushq $0 /* pt_regs->r10 = 0 */ |
231 | xorq %r10, %r10 /* nospec r10 */ | ||
219 | pushq $0 /* pt_regs->r11 = 0 */ | 232 | pushq $0 /* pt_regs->r11 = 0 */ |
233 | xorq %r11, %r11 /* nospec r11 */ | ||
220 | pushq %rbx /* pt_regs->rbx */ | 234 | pushq %rbx /* pt_regs->rbx */ |
235 | xorl %ebx, %ebx /* nospec rbx */ | ||
221 | pushq %rbp /* pt_regs->rbp (will be overwritten) */ | 236 | pushq %rbp /* pt_regs->rbp (will be overwritten) */ |
237 | xorl %ebp, %ebp /* nospec rbp */ | ||
222 | pushq $0 /* pt_regs->r12 = 0 */ | 238 | pushq $0 /* pt_regs->r12 = 0 */ |
239 | xorq %r12, %r12 /* nospec r12 */ | ||
223 | pushq $0 /* pt_regs->r13 = 0 */ | 240 | pushq $0 /* pt_regs->r13 = 0 */ |
241 | xorq %r13, %r13 /* nospec r13 */ | ||
224 | pushq $0 /* pt_regs->r14 = 0 */ | 242 | pushq $0 /* pt_regs->r14 = 0 */ |
243 | xorq %r14, %r14 /* nospec r14 */ | ||
225 | pushq $0 /* pt_regs->r15 = 0 */ | 244 | pushq $0 /* pt_regs->r15 = 0 */ |
245 | xorq %r15, %r15 /* nospec r15 */ | ||
226 | 246 | ||
227 | /* | 247 | /* |
228 | * User mode is traced as though IRQs are on, and SYSENTER | 248 | * User mode is traced as though IRQs are on, and SYSENTER |
@@ -338,15 +358,25 @@ ENTRY(entry_INT80_compat) | |||
338 | pushq %rcx /* pt_regs->cx */ | 358 | pushq %rcx /* pt_regs->cx */ |
339 | pushq $-ENOSYS /* pt_regs->ax */ | 359 | pushq $-ENOSYS /* pt_regs->ax */ |
340 | pushq $0 /* pt_regs->r8 = 0 */ | 360 | pushq $0 /* pt_regs->r8 = 0 */ |
361 | xorq %r8, %r8 /* nospec r8 */ | ||
341 | pushq $0 /* pt_regs->r9 = 0 */ | 362 | pushq $0 /* pt_regs->r9 = 0 */ |
363 | xorq %r9, %r9 /* nospec r9 */ | ||
342 | pushq $0 /* pt_regs->r10 = 0 */ | 364 | pushq $0 /* pt_regs->r10 = 0 */ |
365 | xorq %r10, %r10 /* nospec r10 */ | ||
343 | pushq $0 /* pt_regs->r11 = 0 */ | 366 | pushq $0 /* pt_regs->r11 = 0 */ |
367 | xorq %r11, %r11 /* nospec r11 */ | ||
344 | pushq %rbx /* pt_regs->rbx */ | 368 | pushq %rbx /* pt_regs->rbx */ |
369 | xorl %ebx, %ebx /* nospec rbx */ | ||
345 | pushq %rbp /* pt_regs->rbp */ | 370 | pushq %rbp /* pt_regs->rbp */ |
371 | xorl %ebp, %ebp /* nospec rbp */ | ||
346 | pushq %r12 /* pt_regs->r12 */ | 372 | pushq %r12 /* pt_regs->r12 */ |
373 | xorq %r12, %r12 /* nospec r12 */ | ||
347 | pushq %r13 /* pt_regs->r13 */ | 374 | pushq %r13 /* pt_regs->r13 */ |
375 | xorq %r13, %r13 /* nospec r13 */ | ||
348 | pushq %r14 /* pt_regs->r14 */ | 376 | pushq %r14 /* pt_regs->r14 */ |
377 | xorq %r14, %r14 /* nospec r14 */ | ||
349 | pushq %r15 /* pt_regs->r15 */ | 378 | pushq %r15 /* pt_regs->r15 */ |
379 | xorq %r15, %r15 /* nospec r15 */ | ||
350 | cld | 380 | cld |
351 | 381 | ||
352 | /* | 382 | /* |
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 731153a4681e..56457cb73448 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c | |||
@@ -3559,7 +3559,7 @@ static int intel_snb_pebs_broken(int cpu) | |||
3559 | break; | 3559 | break; |
3560 | 3560 | ||
3561 | case INTEL_FAM6_SANDYBRIDGE_X: | 3561 | case INTEL_FAM6_SANDYBRIDGE_X: |
3562 | switch (cpu_data(cpu).x86_mask) { | 3562 | switch (cpu_data(cpu).x86_stepping) { |
3563 | case 6: rev = 0x618; break; | 3563 | case 6: rev = 0x618; break; |
3564 | case 7: rev = 0x70c; break; | 3564 | case 7: rev = 0x70c; break; |
3565 | } | 3565 | } |
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index ae64d0b69729..cf372b90557e 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c | |||
@@ -1186,7 +1186,7 @@ void __init intel_pmu_lbr_init_atom(void) | |||
1186 | * on PMU interrupt | 1186 | * on PMU interrupt |
1187 | */ | 1187 | */ |
1188 | if (boot_cpu_data.x86_model == 28 | 1188 | if (boot_cpu_data.x86_model == 28 |
1189 | && boot_cpu_data.x86_mask < 10) { | 1189 | && boot_cpu_data.x86_stepping < 10) { |
1190 | pr_cont("LBR disabled due to erratum"); | 1190 | pr_cont("LBR disabled due to erratum"); |
1191 | return; | 1191 | return; |
1192 | } | 1192 | } |
diff --git a/arch/x86/events/intel/p6.c b/arch/x86/events/intel/p6.c index a5604c352930..408879b0c0d4 100644 --- a/arch/x86/events/intel/p6.c +++ b/arch/x86/events/intel/p6.c | |||
@@ -234,7 +234,7 @@ static __initconst const struct x86_pmu p6_pmu = { | |||
234 | 234 | ||
235 | static __init void p6_pmu_rdpmc_quirk(void) | 235 | static __init void p6_pmu_rdpmc_quirk(void) |
236 | { | 236 | { |
237 | if (boot_cpu_data.x86_mask < 9) { | 237 | if (boot_cpu_data.x86_stepping < 9) { |
238 | /* | 238 | /* |
239 | * PPro erratum 26; fixed in stepping 9 and above. | 239 | * PPro erratum 26; fixed in stepping 9 and above. |
240 | */ | 240 | */ |
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 44f5d79d5105..11881726ed37 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
@@ -94,7 +94,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate) | |||
94 | if (boot_cpu_data.x86 == 0x0F && | 94 | if (boot_cpu_data.x86 == 0x0F && |
95 | boot_cpu_data.x86_vendor == X86_VENDOR_AMD && | 95 | boot_cpu_data.x86_vendor == X86_VENDOR_AMD && |
96 | boot_cpu_data.x86_model <= 0x05 && | 96 | boot_cpu_data.x86_model <= 0x05 && |
97 | boot_cpu_data.x86_mask < 0x0A) | 97 | boot_cpu_data.x86_stepping < 0x0A) |
98 | return 1; | 98 | return 1; |
99 | else if (boot_cpu_has(X86_BUG_AMD_APIC_C1E)) | 99 | else if (boot_cpu_has(X86_BUG_AMD_APIC_C1E)) |
100 | return 1; | 100 | return 1; |
diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h index 30d406146016..e1259f043ae9 100644 --- a/arch/x86/include/asm/barrier.h +++ b/arch/x86/include/asm/barrier.h | |||
@@ -40,7 +40,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, | |||
40 | 40 | ||
41 | asm ("cmp %1,%2; sbb %0,%0;" | 41 | asm ("cmp %1,%2; sbb %0,%0;" |
42 | :"=r" (mask) | 42 | :"=r" (mask) |
43 | :"r"(size),"r" (index) | 43 | :"g"(size),"r" (index) |
44 | :"cc"); | 44 | :"cc"); |
45 | return mask; | 45 | return mask; |
46 | } | 46 | } |
diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h index 34d99af43994..6804d6642767 100644 --- a/arch/x86/include/asm/bug.h +++ b/arch/x86/include/asm/bug.h | |||
@@ -5,23 +5,20 @@ | |||
5 | #include <linux/stringify.h> | 5 | #include <linux/stringify.h> |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Since some emulators terminate on UD2, we cannot use it for WARN. | 8 | * Despite that some emulators terminate on UD2, we use it for WARN(). |
9 | * Since various instruction decoders disagree on the length of UD1, | ||
10 | * we cannot use it either. So use UD0 for WARN. | ||
11 | * | 9 | * |
12 | * (binutils knows about "ud1" but {en,de}codes it as 2 bytes, whereas | 10 | * Since various instruction decoders/specs disagree on the encoding of |
13 | * our kernel decoder thinks it takes a ModRM byte, which seems consistent | 11 | * UD0/UD1. |
14 | * with various things like the Intel SDM instruction encoding rules) | ||
15 | */ | 12 | */ |
16 | 13 | ||
17 | #define ASM_UD0 ".byte 0x0f, 0xff" | 14 | #define ASM_UD0 ".byte 0x0f, 0xff" /* + ModRM (for Intel) */ |
18 | #define ASM_UD1 ".byte 0x0f, 0xb9" /* + ModRM */ | 15 | #define ASM_UD1 ".byte 0x0f, 0xb9" /* + ModRM */ |
19 | #define ASM_UD2 ".byte 0x0f, 0x0b" | 16 | #define ASM_UD2 ".byte 0x0f, 0x0b" |
20 | 17 | ||
21 | #define INSN_UD0 0xff0f | 18 | #define INSN_UD0 0xff0f |
22 | #define INSN_UD2 0x0b0f | 19 | #define INSN_UD2 0x0b0f |
23 | 20 | ||
24 | #define LEN_UD0 2 | 21 | #define LEN_UD2 2 |
25 | 22 | ||
26 | #ifdef CONFIG_GENERIC_BUG | 23 | #ifdef CONFIG_GENERIC_BUG |
27 | 24 | ||
@@ -77,7 +74,11 @@ do { \ | |||
77 | unreachable(); \ | 74 | unreachable(); \ |
78 | } while (0) | 75 | } while (0) |
79 | 76 | ||
80 | #define __WARN_FLAGS(flags) _BUG_FLAGS(ASM_UD0, BUGFLAG_WARNING|(flags)) | 77 | #define __WARN_FLAGS(flags) \ |
78 | do { \ | ||
79 | _BUG_FLAGS(ASM_UD2, BUGFLAG_WARNING|(flags)); \ | ||
80 | annotate_reachable(); \ | ||
81 | } while (0) | ||
81 | 82 | ||
82 | #include <asm-generic/bug.h> | 83 | #include <asm-generic/bug.h> |
83 | 84 | ||
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index 4d57894635f2..76b058533e47 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <asm/alternative.h> | 6 | #include <asm/alternative.h> |
7 | #include <asm/alternative-asm.h> | 7 | #include <asm/alternative-asm.h> |
8 | #include <asm/cpufeatures.h> | 8 | #include <asm/cpufeatures.h> |
9 | #include <asm/msr-index.h> | ||
9 | 10 | ||
10 | #ifdef __ASSEMBLY__ | 11 | #ifdef __ASSEMBLY__ |
11 | 12 | ||
@@ -164,10 +165,15 @@ static inline void vmexit_fill_RSB(void) | |||
164 | 165 | ||
165 | static inline void indirect_branch_prediction_barrier(void) | 166 | static inline void indirect_branch_prediction_barrier(void) |
166 | { | 167 | { |
167 | alternative_input("", | 168 | asm volatile(ALTERNATIVE("", |
168 | "call __ibp_barrier", | 169 | "movl %[msr], %%ecx\n\t" |
169 | X86_FEATURE_USE_IBPB, | 170 | "movl %[val], %%eax\n\t" |
170 | ASM_NO_INPUT_CLOBBER("eax", "ecx", "edx", "memory")); | 171 | "movl $0, %%edx\n\t" |
172 | "wrmsr", | ||
173 | X86_FEATURE_USE_IBPB) | ||
174 | : : [msr] "i" (MSR_IA32_PRED_CMD), | ||
175 | [val] "i" (PRED_CMD_IBPB) | ||
176 | : "eax", "ecx", "edx", "memory"); | ||
171 | } | 177 | } |
172 | 178 | ||
173 | #endif /* __ASSEMBLY__ */ | 179 | #endif /* __ASSEMBLY__ */ |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 892df375b615..554841fab717 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -297,9 +297,9 @@ static inline void __flush_tlb_global(void) | |||
297 | { | 297 | { |
298 | PVOP_VCALL0(pv_mmu_ops.flush_tlb_kernel); | 298 | PVOP_VCALL0(pv_mmu_ops.flush_tlb_kernel); |
299 | } | 299 | } |
300 | static inline void __flush_tlb_single(unsigned long addr) | 300 | static inline void __flush_tlb_one_user(unsigned long addr) |
301 | { | 301 | { |
302 | PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr); | 302 | PVOP_VCALL1(pv_mmu_ops.flush_tlb_one_user, addr); |
303 | } | 303 | } |
304 | 304 | ||
305 | static inline void flush_tlb_others(const struct cpumask *cpumask, | 305 | static inline void flush_tlb_others(const struct cpumask *cpumask, |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 6ec54d01972d..f624f1f10316 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
@@ -217,7 +217,7 @@ struct pv_mmu_ops { | |||
217 | /* TLB operations */ | 217 | /* TLB operations */ |
218 | void (*flush_tlb_user)(void); | 218 | void (*flush_tlb_user)(void); |
219 | void (*flush_tlb_kernel)(void); | 219 | void (*flush_tlb_kernel)(void); |
220 | void (*flush_tlb_single)(unsigned long addr); | 220 | void (*flush_tlb_one_user)(unsigned long addr); |
221 | void (*flush_tlb_others)(const struct cpumask *cpus, | 221 | void (*flush_tlb_others)(const struct cpumask *cpus, |
222 | const struct flush_tlb_info *info); | 222 | const struct flush_tlb_info *info); |
223 | 223 | ||
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index e67c0620aec2..e55466760ff8 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h | |||
@@ -61,7 +61,7 @@ void paging_init(void); | |||
61 | #define kpte_clear_flush(ptep, vaddr) \ | 61 | #define kpte_clear_flush(ptep, vaddr) \ |
62 | do { \ | 62 | do { \ |
63 | pte_clear(&init_mm, (vaddr), (ptep)); \ | 63 | pte_clear(&init_mm, (vaddr), (ptep)); \ |
64 | __flush_tlb_one((vaddr)); \ | 64 | __flush_tlb_one_kernel((vaddr)); \ |
65 | } while (0) | 65 | } while (0) |
66 | 66 | ||
67 | #endif /* !__ASSEMBLY__ */ | 67 | #endif /* !__ASSEMBLY__ */ |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 793bae7e7ce3..1bd9ed87606f 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -91,7 +91,7 @@ struct cpuinfo_x86 { | |||
91 | __u8 x86; /* CPU family */ | 91 | __u8 x86; /* CPU family */ |
92 | __u8 x86_vendor; /* CPU vendor */ | 92 | __u8 x86_vendor; /* CPU vendor */ |
93 | __u8 x86_model; | 93 | __u8 x86_model; |
94 | __u8 x86_mask; | 94 | __u8 x86_stepping; |
95 | #ifdef CONFIG_X86_64 | 95 | #ifdef CONFIG_X86_64 |
96 | /* Number of 4K pages in DTLB/ITLB combined(in pages): */ | 96 | /* Number of 4K pages in DTLB/ITLB combined(in pages): */ |
97 | int x86_tlbsize; | 97 | int x86_tlbsize; |
@@ -109,7 +109,7 @@ struct cpuinfo_x86 { | |||
109 | char x86_vendor_id[16]; | 109 | char x86_vendor_id[16]; |
110 | char x86_model_id[64]; | 110 | char x86_model_id[64]; |
111 | /* in KB - valid for CPUS which support this call: */ | 111 | /* in KB - valid for CPUS which support this call: */ |
112 | int x86_cache_size; | 112 | unsigned int x86_cache_size; |
113 | int x86_cache_alignment; /* In bytes */ | 113 | int x86_cache_alignment; /* In bytes */ |
114 | /* Cache QoS architectural values: */ | 114 | /* Cache QoS architectural values: */ |
115 | int x86_cache_max_rmid; /* max index */ | 115 | int x86_cache_max_rmid; /* max index */ |
@@ -977,7 +977,4 @@ bool xen_set_default_idle(void); | |||
977 | 977 | ||
978 | void stop_this_cpu(void *dummy); | 978 | void stop_this_cpu(void *dummy); |
979 | void df_debug(struct pt_regs *regs, long error_code); | 979 | void df_debug(struct pt_regs *regs, long error_code); |
980 | |||
981 | void __ibp_barrier(void); | ||
982 | |||
983 | #endif /* _ASM_X86_PROCESSOR_H */ | 980 | #endif /* _ASM_X86_PROCESSOR_H */ |
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 2b8f18ca5874..84137c22fdfa 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h | |||
@@ -140,7 +140,7 @@ static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid) | |||
140 | #else | 140 | #else |
141 | #define __flush_tlb() __native_flush_tlb() | 141 | #define __flush_tlb() __native_flush_tlb() |
142 | #define __flush_tlb_global() __native_flush_tlb_global() | 142 | #define __flush_tlb_global() __native_flush_tlb_global() |
143 | #define __flush_tlb_single(addr) __native_flush_tlb_single(addr) | 143 | #define __flush_tlb_one_user(addr) __native_flush_tlb_one_user(addr) |
144 | #endif | 144 | #endif |
145 | 145 | ||
146 | static inline bool tlb_defer_switch_to_init_mm(void) | 146 | static inline bool tlb_defer_switch_to_init_mm(void) |
@@ -400,7 +400,7 @@ static inline void __native_flush_tlb_global(void) | |||
400 | /* | 400 | /* |
401 | * flush one page in the user mapping | 401 | * flush one page in the user mapping |
402 | */ | 402 | */ |
403 | static inline void __native_flush_tlb_single(unsigned long addr) | 403 | static inline void __native_flush_tlb_one_user(unsigned long addr) |
404 | { | 404 | { |
405 | u32 loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid); | 405 | u32 loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid); |
406 | 406 | ||
@@ -437,18 +437,31 @@ static inline void __flush_tlb_all(void) | |||
437 | /* | 437 | /* |
438 | * flush one page in the kernel mapping | 438 | * flush one page in the kernel mapping |
439 | */ | 439 | */ |
440 | static inline void __flush_tlb_one(unsigned long addr) | 440 | static inline void __flush_tlb_one_kernel(unsigned long addr) |
441 | { | 441 | { |
442 | count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE); | 442 | count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE); |
443 | __flush_tlb_single(addr); | 443 | |
444 | /* | ||
445 | * If PTI is off, then __flush_tlb_one_user() is just INVLPG or its | ||
446 | * paravirt equivalent. Even with PCID, this is sufficient: we only | ||
447 | * use PCID if we also use global PTEs for the kernel mapping, and | ||
448 | * INVLPG flushes global translations across all address spaces. | ||
449 | * | ||
450 | * If PTI is on, then the kernel is mapped with non-global PTEs, and | ||
451 | * __flush_tlb_one_user() will flush the given address for the current | ||
452 | * kernel address space and for its usermode counterpart, but it does | ||
453 | * not flush it for other address spaces. | ||
454 | */ | ||
455 | __flush_tlb_one_user(addr); | ||
444 | 456 | ||
445 | if (!static_cpu_has(X86_FEATURE_PTI)) | 457 | if (!static_cpu_has(X86_FEATURE_PTI)) |
446 | return; | 458 | return; |
447 | 459 | ||
448 | /* | 460 | /* |
449 | * __flush_tlb_single() will have cleared the TLB entry for this ASID, | 461 | * See above. We need to propagate the flush to all other address |
450 | * but since kernel space is replicated across all, we must also | 462 | * spaces. In principle, we only need to propagate it to kernelmode |
451 | * invalidate all others. | 463 | * address spaces, but the extra bookkeeping we would need is not |
464 | * worth it. | ||
452 | */ | 465 | */ |
453 | invalidate_other_asid(); | 466 | invalidate_other_asid(); |
454 | } | 467 | } |
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 6db28f17ff28..c88e0b127810 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c | |||
@@ -235,7 +235,7 @@ int amd_cache_northbridges(void) | |||
235 | if (boot_cpu_data.x86 == 0x10 && | 235 | if (boot_cpu_data.x86 == 0x10 && |
236 | boot_cpu_data.x86_model >= 0x8 && | 236 | boot_cpu_data.x86_model >= 0x8 && |
237 | (boot_cpu_data.x86_model > 0x9 || | 237 | (boot_cpu_data.x86_model > 0x9 || |
238 | boot_cpu_data.x86_mask >= 0x1)) | 238 | boot_cpu_data.x86_stepping >= 0x1)) |
239 | amd_northbridges.flags |= AMD_NB_L3_INDEX_DISABLE; | 239 | amd_northbridges.flags |= AMD_NB_L3_INDEX_DISABLE; |
240 | 240 | ||
241 | if (boot_cpu_data.x86 == 0x15) | 241 | if (boot_cpu_data.x86 == 0x15) |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 25ddf02598d2..b203af0855b5 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -546,7 +546,7 @@ static DEFINE_PER_CPU(struct clock_event_device, lapic_events); | |||
546 | 546 | ||
547 | static u32 hsx_deadline_rev(void) | 547 | static u32 hsx_deadline_rev(void) |
548 | { | 548 | { |
549 | switch (boot_cpu_data.x86_mask) { | 549 | switch (boot_cpu_data.x86_stepping) { |
550 | case 0x02: return 0x3a; /* EP */ | 550 | case 0x02: return 0x3a; /* EP */ |
551 | case 0x04: return 0x0f; /* EX */ | 551 | case 0x04: return 0x0f; /* EX */ |
552 | } | 552 | } |
@@ -556,7 +556,7 @@ static u32 hsx_deadline_rev(void) | |||
556 | 556 | ||
557 | static u32 bdx_deadline_rev(void) | 557 | static u32 bdx_deadline_rev(void) |
558 | { | 558 | { |
559 | switch (boot_cpu_data.x86_mask) { | 559 | switch (boot_cpu_data.x86_stepping) { |
560 | case 0x02: return 0x00000011; | 560 | case 0x02: return 0x00000011; |
561 | case 0x03: return 0x0700000e; | 561 | case 0x03: return 0x0700000e; |
562 | case 0x04: return 0x0f00000c; | 562 | case 0x04: return 0x0f00000c; |
@@ -568,7 +568,7 @@ static u32 bdx_deadline_rev(void) | |||
568 | 568 | ||
569 | static u32 skx_deadline_rev(void) | 569 | static u32 skx_deadline_rev(void) |
570 | { | 570 | { |
571 | switch (boot_cpu_data.x86_mask) { | 571 | switch (boot_cpu_data.x86_stepping) { |
572 | case 0x03: return 0x01000136; | 572 | case 0x03: return 0x01000136; |
573 | case 0x04: return 0x02000014; | 573 | case 0x04: return 0x02000014; |
574 | } | 574 | } |
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index fa1261eefa16..f91ba53e06c8 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c | |||
@@ -18,7 +18,7 @@ void foo(void) | |||
18 | OFFSET(CPUINFO_x86, cpuinfo_x86, x86); | 18 | OFFSET(CPUINFO_x86, cpuinfo_x86, x86); |
19 | OFFSET(CPUINFO_x86_vendor, cpuinfo_x86, x86_vendor); | 19 | OFFSET(CPUINFO_x86_vendor, cpuinfo_x86, x86_vendor); |
20 | OFFSET(CPUINFO_x86_model, cpuinfo_x86, x86_model); | 20 | OFFSET(CPUINFO_x86_model, cpuinfo_x86, x86_model); |
21 | OFFSET(CPUINFO_x86_mask, cpuinfo_x86, x86_mask); | 21 | OFFSET(CPUINFO_x86_stepping, cpuinfo_x86, x86_stepping); |
22 | OFFSET(CPUINFO_cpuid_level, cpuinfo_x86, cpuid_level); | 22 | OFFSET(CPUINFO_cpuid_level, cpuinfo_x86, cpuid_level); |
23 | OFFSET(CPUINFO_x86_capability, cpuinfo_x86, x86_capability); | 23 | OFFSET(CPUINFO_x86_capability, cpuinfo_x86, x86_capability); |
24 | OFFSET(CPUINFO_x86_vendor_id, cpuinfo_x86, x86_vendor_id); | 24 | OFFSET(CPUINFO_x86_vendor_id, cpuinfo_x86, x86_vendor_id); |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 5bddbdcbc4a3..f0e6456ca7d3 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -119,7 +119,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c) | |||
119 | return; | 119 | return; |
120 | } | 120 | } |
121 | 121 | ||
122 | if (c->x86_model == 6 && c->x86_mask == 1) { | 122 | if (c->x86_model == 6 && c->x86_stepping == 1) { |
123 | const int K6_BUG_LOOP = 1000000; | 123 | const int K6_BUG_LOOP = 1000000; |
124 | int n; | 124 | int n; |
125 | void (*f_vide)(void); | 125 | void (*f_vide)(void); |
@@ -149,7 +149,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c) | |||
149 | 149 | ||
150 | /* K6 with old style WHCR */ | 150 | /* K6 with old style WHCR */ |
151 | if (c->x86_model < 8 || | 151 | if (c->x86_model < 8 || |
152 | (c->x86_model == 8 && c->x86_mask < 8)) { | 152 | (c->x86_model == 8 && c->x86_stepping < 8)) { |
153 | /* We can only write allocate on the low 508Mb */ | 153 | /* We can only write allocate on the low 508Mb */ |
154 | if (mbytes > 508) | 154 | if (mbytes > 508) |
155 | mbytes = 508; | 155 | mbytes = 508; |
@@ -168,7 +168,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c) | |||
168 | return; | 168 | return; |
169 | } | 169 | } |
170 | 170 | ||
171 | if ((c->x86_model == 8 && c->x86_mask > 7) || | 171 | if ((c->x86_model == 8 && c->x86_stepping > 7) || |
172 | c->x86_model == 9 || c->x86_model == 13) { | 172 | c->x86_model == 9 || c->x86_model == 13) { |
173 | /* The more serious chips .. */ | 173 | /* The more serious chips .. */ |
174 | 174 | ||
@@ -221,7 +221,7 @@ static void init_amd_k7(struct cpuinfo_x86 *c) | |||
221 | * are more robust with CLK_CTL set to 200xxxxx instead of 600xxxxx | 221 | * are more robust with CLK_CTL set to 200xxxxx instead of 600xxxxx |
222 | * As per AMD technical note 27212 0.2 | 222 | * As per AMD technical note 27212 0.2 |
223 | */ | 223 | */ |
224 | if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) { | 224 | if ((c->x86_model == 8 && c->x86_stepping >= 1) || (c->x86_model > 8)) { |
225 | rdmsr(MSR_K7_CLK_CTL, l, h); | 225 | rdmsr(MSR_K7_CLK_CTL, l, h); |
226 | if ((l & 0xfff00000) != 0x20000000) { | 226 | if ((l & 0xfff00000) != 0x20000000) { |
227 | pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", | 227 | pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", |
@@ -241,12 +241,12 @@ static void init_amd_k7(struct cpuinfo_x86 *c) | |||
241 | * but they are not certified as MP capable. | 241 | * but they are not certified as MP capable. |
242 | */ | 242 | */ |
243 | /* Athlon 660/661 is valid. */ | 243 | /* Athlon 660/661 is valid. */ |
244 | if ((c->x86_model == 6) && ((c->x86_mask == 0) || | 244 | if ((c->x86_model == 6) && ((c->x86_stepping == 0) || |
245 | (c->x86_mask == 1))) | 245 | (c->x86_stepping == 1))) |
246 | return; | 246 | return; |
247 | 247 | ||
248 | /* Duron 670 is valid */ | 248 | /* Duron 670 is valid */ |
249 | if ((c->x86_model == 7) && (c->x86_mask == 0)) | 249 | if ((c->x86_model == 7) && (c->x86_stepping == 0)) |
250 | return; | 250 | return; |
251 | 251 | ||
252 | /* | 252 | /* |
@@ -256,8 +256,8 @@ static void init_amd_k7(struct cpuinfo_x86 *c) | |||
256 | * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for | 256 | * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for |
257 | * more. | 257 | * more. |
258 | */ | 258 | */ |
259 | if (((c->x86_model == 6) && (c->x86_mask >= 2)) || | 259 | if (((c->x86_model == 6) && (c->x86_stepping >= 2)) || |
260 | ((c->x86_model == 7) && (c->x86_mask >= 1)) || | 260 | ((c->x86_model == 7) && (c->x86_stepping >= 1)) || |
261 | (c->x86_model > 7)) | 261 | (c->x86_model > 7)) |
262 | if (cpu_has(c, X86_FEATURE_MP)) | 262 | if (cpu_has(c, X86_FEATURE_MP)) |
263 | return; | 263 | return; |
@@ -628,7 +628,7 @@ static void early_init_amd(struct cpuinfo_x86 *c) | |||
628 | /* Set MTRR capability flag if appropriate */ | 628 | /* Set MTRR capability flag if appropriate */ |
629 | if (c->x86 == 5) | 629 | if (c->x86 == 5) |
630 | if (c->x86_model == 13 || c->x86_model == 9 || | 630 | if (c->x86_model == 13 || c->x86_model == 9 || |
631 | (c->x86_model == 8 && c->x86_mask >= 8)) | 631 | (c->x86_model == 8 && c->x86_stepping >= 8)) |
632 | set_cpu_cap(c, X86_FEATURE_K6_MTRR); | 632 | set_cpu_cap(c, X86_FEATURE_K6_MTRR); |
633 | #endif | 633 | #endif |
634 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI) | 634 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI) |
@@ -795,7 +795,7 @@ static void init_amd_zn(struct cpuinfo_x86 *c) | |||
795 | * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects | 795 | * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects |
796 | * all up to and including B1. | 796 | * all up to and including B1. |
797 | */ | 797 | */ |
798 | if (c->x86_model <= 1 && c->x86_mask <= 1) | 798 | if (c->x86_model <= 1 && c->x86_stepping <= 1) |
799 | set_cpu_cap(c, X86_FEATURE_CPB); | 799 | set_cpu_cap(c, X86_FEATURE_CPB); |
800 | } | 800 | } |
801 | 801 | ||
@@ -906,11 +906,11 @@ static unsigned int amd_size_cache(struct cpuinfo_x86 *c, unsigned int size) | |||
906 | /* AMD errata T13 (order #21922) */ | 906 | /* AMD errata T13 (order #21922) */ |
907 | if ((c->x86 == 6)) { | 907 | if ((c->x86 == 6)) { |
908 | /* Duron Rev A0 */ | 908 | /* Duron Rev A0 */ |
909 | if (c->x86_model == 3 && c->x86_mask == 0) | 909 | if (c->x86_model == 3 && c->x86_stepping == 0) |
910 | size = 64; | 910 | size = 64; |
911 | /* Tbird rev A1/A2 */ | 911 | /* Tbird rev A1/A2 */ |
912 | if (c->x86_model == 4 && | 912 | if (c->x86_model == 4 && |
913 | (c->x86_mask == 0 || c->x86_mask == 1)) | 913 | (c->x86_stepping == 0 || c->x86_stepping == 1)) |
914 | size = 256; | 914 | size = 256; |
915 | } | 915 | } |
916 | return size; | 916 | return size; |
@@ -1047,7 +1047,7 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) | |||
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | /* OSVW unavailable or ID unknown, match family-model-stepping range */ | 1049 | /* OSVW unavailable or ID unknown, match family-model-stepping range */ |
1050 | ms = (cpu->x86_model << 4) | cpu->x86_mask; | 1050 | ms = (cpu->x86_model << 4) | cpu->x86_stepping; |
1051 | while ((range = *erratum++)) | 1051 | while ((range = *erratum++)) |
1052 | if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && | 1052 | if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && |
1053 | (ms >= AMD_MODEL_RANGE_START(range)) && | 1053 | (ms >= AMD_MODEL_RANGE_START(range)) && |
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 71949bf2de5a..d71c8b54b696 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
@@ -162,8 +162,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) | |||
162 | if (cmdline_find_option_bool(boot_command_line, "nospectre_v2")) | 162 | if (cmdline_find_option_bool(boot_command_line, "nospectre_v2")) |
163 | return SPECTRE_V2_CMD_NONE; | 163 | return SPECTRE_V2_CMD_NONE; |
164 | else { | 164 | else { |
165 | ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, | 165 | ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, sizeof(arg)); |
166 | sizeof(arg)); | ||
167 | if (ret < 0) | 166 | if (ret < 0) |
168 | return SPECTRE_V2_CMD_AUTO; | 167 | return SPECTRE_V2_CMD_AUTO; |
169 | 168 | ||
@@ -175,8 +174,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) | |||
175 | } | 174 | } |
176 | 175 | ||
177 | if (i >= ARRAY_SIZE(mitigation_options)) { | 176 | if (i >= ARRAY_SIZE(mitigation_options)) { |
178 | pr_err("unknown option (%s). Switching to AUTO select\n", | 177 | pr_err("unknown option (%s). Switching to AUTO select\n", arg); |
179 | mitigation_options[i].option); | ||
180 | return SPECTRE_V2_CMD_AUTO; | 178 | return SPECTRE_V2_CMD_AUTO; |
181 | } | 179 | } |
182 | } | 180 | } |
@@ -185,8 +183,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) | |||
185 | cmd == SPECTRE_V2_CMD_RETPOLINE_AMD || | 183 | cmd == SPECTRE_V2_CMD_RETPOLINE_AMD || |
186 | cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) && | 184 | cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) && |
187 | !IS_ENABLED(CONFIG_RETPOLINE)) { | 185 | !IS_ENABLED(CONFIG_RETPOLINE)) { |
188 | pr_err("%s selected but not compiled in. Switching to AUTO select\n", | 186 | pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option); |
189 | mitigation_options[i].option); | ||
190 | return SPECTRE_V2_CMD_AUTO; | 187 | return SPECTRE_V2_CMD_AUTO; |
191 | } | 188 | } |
192 | 189 | ||
@@ -256,14 +253,14 @@ static void __init spectre_v2_select_mitigation(void) | |||
256 | goto retpoline_auto; | 253 | goto retpoline_auto; |
257 | break; | 254 | break; |
258 | } | 255 | } |
259 | pr_err("kernel not compiled with retpoline; no mitigation available!"); | 256 | pr_err("Spectre mitigation: kernel not compiled with retpoline; no mitigation available!"); |
260 | return; | 257 | return; |
261 | 258 | ||
262 | retpoline_auto: | 259 | retpoline_auto: |
263 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { | 260 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { |
264 | retpoline_amd: | 261 | retpoline_amd: |
265 | if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { | 262 | if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { |
266 | pr_err("LFENCE not serializing. Switching to generic retpoline\n"); | 263 | pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n"); |
267 | goto retpoline_generic; | 264 | goto retpoline_generic; |
268 | } | 265 | } |
269 | mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_AMD : | 266 | mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_AMD : |
@@ -281,7 +278,7 @@ retpoline_auto: | |||
281 | pr_info("%s\n", spectre_v2_strings[mode]); | 278 | pr_info("%s\n", spectre_v2_strings[mode]); |
282 | 279 | ||
283 | /* | 280 | /* |
284 | * If neither SMEP or KPTI are available, there is a risk of | 281 | * If neither SMEP nor PTI are available, there is a risk of |
285 | * hitting userspace addresses in the RSB after a context switch | 282 | * hitting userspace addresses in the RSB after a context switch |
286 | * from a shallow call stack to a deeper one. To prevent this fill | 283 | * from a shallow call stack to a deeper one. To prevent this fill |
287 | * the entire RSB, even when using IBRS. | 284 | * the entire RSB, even when using IBRS. |
@@ -295,21 +292,20 @@ retpoline_auto: | |||
295 | if ((!boot_cpu_has(X86_FEATURE_PTI) && | 292 | if ((!boot_cpu_has(X86_FEATURE_PTI) && |
296 | !boot_cpu_has(X86_FEATURE_SMEP)) || is_skylake_era()) { | 293 | !boot_cpu_has(X86_FEATURE_SMEP)) || is_skylake_era()) { |
297 | setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); | 294 | setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); |
298 | pr_info("Filling RSB on context switch\n"); | 295 | pr_info("Spectre v2 mitigation: Filling RSB on context switch\n"); |
299 | } | 296 | } |
300 | 297 | ||
301 | /* Initialize Indirect Branch Prediction Barrier if supported */ | 298 | /* Initialize Indirect Branch Prediction Barrier if supported */ |
302 | if (boot_cpu_has(X86_FEATURE_IBPB)) { | 299 | if (boot_cpu_has(X86_FEATURE_IBPB)) { |
303 | setup_force_cpu_cap(X86_FEATURE_USE_IBPB); | 300 | setup_force_cpu_cap(X86_FEATURE_USE_IBPB); |
304 | pr_info("Enabling Indirect Branch Prediction Barrier\n"); | 301 | pr_info("Spectre v2 mitigation: Enabling Indirect Branch Prediction Barrier\n"); |
305 | } | 302 | } |
306 | } | 303 | } |
307 | 304 | ||
308 | #undef pr_fmt | 305 | #undef pr_fmt |
309 | 306 | ||
310 | #ifdef CONFIG_SYSFS | 307 | #ifdef CONFIG_SYSFS |
311 | ssize_t cpu_show_meltdown(struct device *dev, | 308 | ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf) |
312 | struct device_attribute *attr, char *buf) | ||
313 | { | 309 | { |
314 | if (!boot_cpu_has_bug(X86_BUG_CPU_MELTDOWN)) | 310 | if (!boot_cpu_has_bug(X86_BUG_CPU_MELTDOWN)) |
315 | return sprintf(buf, "Not affected\n"); | 311 | return sprintf(buf, "Not affected\n"); |
@@ -318,16 +314,14 @@ ssize_t cpu_show_meltdown(struct device *dev, | |||
318 | return sprintf(buf, "Vulnerable\n"); | 314 | return sprintf(buf, "Vulnerable\n"); |
319 | } | 315 | } |
320 | 316 | ||
321 | ssize_t cpu_show_spectre_v1(struct device *dev, | 317 | ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf) |
322 | struct device_attribute *attr, char *buf) | ||
323 | { | 318 | { |
324 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1)) | 319 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1)) |
325 | return sprintf(buf, "Not affected\n"); | 320 | return sprintf(buf, "Not affected\n"); |
326 | return sprintf(buf, "Mitigation: __user pointer sanitization\n"); | 321 | return sprintf(buf, "Mitigation: __user pointer sanitization\n"); |
327 | } | 322 | } |
328 | 323 | ||
329 | ssize_t cpu_show_spectre_v2(struct device *dev, | 324 | ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf) |
330 | struct device_attribute *attr, char *buf) | ||
331 | { | 325 | { |
332 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) | 326 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) |
333 | return sprintf(buf, "Not affected\n"); | 327 | return sprintf(buf, "Not affected\n"); |
@@ -337,9 +331,3 @@ ssize_t cpu_show_spectre_v2(struct device *dev, | |||
337 | spectre_v2_module_string()); | 331 | spectre_v2_module_string()); |
338 | } | 332 | } |
339 | #endif | 333 | #endif |
340 | |||
341 | void __ibp_barrier(void) | ||
342 | { | ||
343 | __wrmsr(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, 0); | ||
344 | } | ||
345 | EXPORT_SYMBOL_GPL(__ibp_barrier); | ||
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index c578cd29c2d2..e5ec0f11c0de 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c | |||
@@ -140,7 +140,7 @@ static void init_centaur(struct cpuinfo_x86 *c) | |||
140 | clear_cpu_cap(c, X86_FEATURE_TSC); | 140 | clear_cpu_cap(c, X86_FEATURE_TSC); |
141 | break; | 141 | break; |
142 | case 8: | 142 | case 8: |
143 | switch (c->x86_mask) { | 143 | switch (c->x86_stepping) { |
144 | default: | 144 | default: |
145 | name = "2"; | 145 | name = "2"; |
146 | break; | 146 | break; |
@@ -215,7 +215,7 @@ centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size) | |||
215 | * - Note, it seems this may only be in engineering samples. | 215 | * - Note, it seems this may only be in engineering samples. |
216 | */ | 216 | */ |
217 | if ((c->x86 == 6) && (c->x86_model == 9) && | 217 | if ((c->x86 == 6) && (c->x86_model == 9) && |
218 | (c->x86_mask == 1) && (size == 65)) | 218 | (c->x86_stepping == 1) && (size == 65)) |
219 | size -= 1; | 219 | size -= 1; |
220 | return size; | 220 | return size; |
221 | } | 221 | } |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index d63f4b5706e4..824aee0117bb 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -731,7 +731,7 @@ void cpu_detect(struct cpuinfo_x86 *c) | |||
731 | cpuid(0x00000001, &tfms, &misc, &junk, &cap0); | 731 | cpuid(0x00000001, &tfms, &misc, &junk, &cap0); |
732 | c->x86 = x86_family(tfms); | 732 | c->x86 = x86_family(tfms); |
733 | c->x86_model = x86_model(tfms); | 733 | c->x86_model = x86_model(tfms); |
734 | c->x86_mask = x86_stepping(tfms); | 734 | c->x86_stepping = x86_stepping(tfms); |
735 | 735 | ||
736 | if (cap0 & (1<<19)) { | 736 | if (cap0 & (1<<19)) { |
737 | c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; | 737 | c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; |
@@ -1184,9 +1184,9 @@ static void identify_cpu(struct cpuinfo_x86 *c) | |||
1184 | int i; | 1184 | int i; |
1185 | 1185 | ||
1186 | c->loops_per_jiffy = loops_per_jiffy; | 1186 | c->loops_per_jiffy = loops_per_jiffy; |
1187 | c->x86_cache_size = -1; | 1187 | c->x86_cache_size = 0; |
1188 | c->x86_vendor = X86_VENDOR_UNKNOWN; | 1188 | c->x86_vendor = X86_VENDOR_UNKNOWN; |
1189 | c->x86_model = c->x86_mask = 0; /* So far unknown... */ | 1189 | c->x86_model = c->x86_stepping = 0; /* So far unknown... */ |
1190 | c->x86_vendor_id[0] = '\0'; /* Unset */ | 1190 | c->x86_vendor_id[0] = '\0'; /* Unset */ |
1191 | c->x86_model_id[0] = '\0'; /* Unset */ | 1191 | c->x86_model_id[0] = '\0'; /* Unset */ |
1192 | c->x86_max_cores = 1; | 1192 | c->x86_max_cores = 1; |
@@ -1378,8 +1378,8 @@ void print_cpu_info(struct cpuinfo_x86 *c) | |||
1378 | 1378 | ||
1379 | pr_cont(" (family: 0x%x, model: 0x%x", c->x86, c->x86_model); | 1379 | pr_cont(" (family: 0x%x, model: 0x%x", c->x86, c->x86_model); |
1380 | 1380 | ||
1381 | if (c->x86_mask || c->cpuid_level >= 0) | 1381 | if (c->x86_stepping || c->cpuid_level >= 0) |
1382 | pr_cont(", stepping: 0x%x)\n", c->x86_mask); | 1382 | pr_cont(", stepping: 0x%x)\n", c->x86_stepping); |
1383 | else | 1383 | else |
1384 | pr_cont(")\n"); | 1384 | pr_cont(")\n"); |
1385 | } | 1385 | } |
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c index 6b4bb335641f..8949b7ae6d92 100644 --- a/arch/x86/kernel/cpu/cyrix.c +++ b/arch/x86/kernel/cpu/cyrix.c | |||
@@ -215,7 +215,7 @@ static void init_cyrix(struct cpuinfo_x86 *c) | |||
215 | 215 | ||
216 | /* common case step number/rev -- exceptions handled below */ | 216 | /* common case step number/rev -- exceptions handled below */ |
217 | c->x86_model = (dir1 >> 4) + 1; | 217 | c->x86_model = (dir1 >> 4) + 1; |
218 | c->x86_mask = dir1 & 0xf; | 218 | c->x86_stepping = dir1 & 0xf; |
219 | 219 | ||
220 | /* Now cook; the original recipe is by Channing Corn, from Cyrix. | 220 | /* Now cook; the original recipe is by Channing Corn, from Cyrix. |
221 | * We do the same thing for each generation: we work out | 221 | * We do the same thing for each generation: we work out |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 319bf989fad1..d19e903214b4 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -116,14 +116,13 @@ struct sku_microcode { | |||
116 | u32 microcode; | 116 | u32 microcode; |
117 | }; | 117 | }; |
118 | static const struct sku_microcode spectre_bad_microcodes[] = { | 118 | static const struct sku_microcode spectre_bad_microcodes[] = { |
119 | { INTEL_FAM6_KABYLAKE_DESKTOP, 0x0B, 0x84 }, | 119 | { INTEL_FAM6_KABYLAKE_DESKTOP, 0x0B, 0x80 }, |
120 | { INTEL_FAM6_KABYLAKE_DESKTOP, 0x0A, 0x84 }, | 120 | { INTEL_FAM6_KABYLAKE_DESKTOP, 0x0A, 0x80 }, |
121 | { INTEL_FAM6_KABYLAKE_DESKTOP, 0x09, 0x84 }, | 121 | { INTEL_FAM6_KABYLAKE_DESKTOP, 0x09, 0x80 }, |
122 | { INTEL_FAM6_KABYLAKE_MOBILE, 0x0A, 0x84 }, | 122 | { INTEL_FAM6_KABYLAKE_MOBILE, 0x0A, 0x80 }, |
123 | { INTEL_FAM6_KABYLAKE_MOBILE, 0x09, 0x84 }, | 123 | { INTEL_FAM6_KABYLAKE_MOBILE, 0x09, 0x80 }, |
124 | { INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e }, | 124 | { INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e }, |
125 | { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c }, | 125 | { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c }, |
126 | { INTEL_FAM6_SKYLAKE_MOBILE, 0x03, 0xc2 }, | ||
127 | { INTEL_FAM6_SKYLAKE_DESKTOP, 0x03, 0xc2 }, | 126 | { INTEL_FAM6_SKYLAKE_DESKTOP, 0x03, 0xc2 }, |
128 | { INTEL_FAM6_BROADWELL_CORE, 0x04, 0x28 }, | 127 | { INTEL_FAM6_BROADWELL_CORE, 0x04, 0x28 }, |
129 | { INTEL_FAM6_BROADWELL_GT3E, 0x01, 0x1b }, | 128 | { INTEL_FAM6_BROADWELL_GT3E, 0x01, 0x1b }, |
@@ -136,8 +135,6 @@ static const struct sku_microcode spectre_bad_microcodes[] = { | |||
136 | { INTEL_FAM6_HASWELL_X, 0x02, 0x3b }, | 135 | { INTEL_FAM6_HASWELL_X, 0x02, 0x3b }, |
137 | { INTEL_FAM6_HASWELL_X, 0x04, 0x10 }, | 136 | { INTEL_FAM6_HASWELL_X, 0x04, 0x10 }, |
138 | { INTEL_FAM6_IVYBRIDGE_X, 0x04, 0x42a }, | 137 | { INTEL_FAM6_IVYBRIDGE_X, 0x04, 0x42a }, |
139 | /* Updated in the 20180108 release; blacklist until we know otherwise */ | ||
140 | { INTEL_FAM6_ATOM_GEMINI_LAKE, 0x01, 0x22 }, | ||
141 | /* Observed in the wild */ | 138 | /* Observed in the wild */ |
142 | { INTEL_FAM6_SANDYBRIDGE_X, 0x06, 0x61b }, | 139 | { INTEL_FAM6_SANDYBRIDGE_X, 0x06, 0x61b }, |
143 | { INTEL_FAM6_SANDYBRIDGE_X, 0x07, 0x712 }, | 140 | { INTEL_FAM6_SANDYBRIDGE_X, 0x07, 0x712 }, |
@@ -149,7 +146,7 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c) | |||
149 | 146 | ||
150 | for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) { | 147 | for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) { |
151 | if (c->x86_model == spectre_bad_microcodes[i].model && | 148 | if (c->x86_model == spectre_bad_microcodes[i].model && |
152 | c->x86_mask == spectre_bad_microcodes[i].stepping) | 149 | c->x86_stepping == spectre_bad_microcodes[i].stepping) |
153 | return (c->microcode <= spectre_bad_microcodes[i].microcode); | 150 | return (c->microcode <= spectre_bad_microcodes[i].microcode); |
154 | } | 151 | } |
155 | return false; | 152 | return false; |
@@ -196,7 +193,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) | |||
196 | * need the microcode to have already been loaded... so if it is | 193 | * need the microcode to have already been loaded... so if it is |
197 | * not, recommend a BIOS update and disable large pages. | 194 | * not, recommend a BIOS update and disable large pages. |
198 | */ | 195 | */ |
199 | if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2 && | 196 | if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_stepping <= 2 && |
200 | c->microcode < 0x20e) { | 197 | c->microcode < 0x20e) { |
201 | pr_warn("Atom PSE erratum detected, BIOS microcode update recommended\n"); | 198 | pr_warn("Atom PSE erratum detected, BIOS microcode update recommended\n"); |
202 | clear_cpu_cap(c, X86_FEATURE_PSE); | 199 | clear_cpu_cap(c, X86_FEATURE_PSE); |
@@ -212,7 +209,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) | |||
212 | 209 | ||
213 | /* CPUID workaround for 0F33/0F34 CPU */ | 210 | /* CPUID workaround for 0F33/0F34 CPU */ |
214 | if (c->x86 == 0xF && c->x86_model == 0x3 | 211 | if (c->x86 == 0xF && c->x86_model == 0x3 |
215 | && (c->x86_mask == 0x3 || c->x86_mask == 0x4)) | 212 | && (c->x86_stepping == 0x3 || c->x86_stepping == 0x4)) |
216 | c->x86_phys_bits = 36; | 213 | c->x86_phys_bits = 36; |
217 | 214 | ||
218 | /* | 215 | /* |
@@ -310,7 +307,7 @@ int ppro_with_ram_bug(void) | |||
310 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | 307 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && |
311 | boot_cpu_data.x86 == 6 && | 308 | boot_cpu_data.x86 == 6 && |
312 | boot_cpu_data.x86_model == 1 && | 309 | boot_cpu_data.x86_model == 1 && |
313 | boot_cpu_data.x86_mask < 8) { | 310 | boot_cpu_data.x86_stepping < 8) { |
314 | pr_info("Pentium Pro with Errata#50 detected. Taking evasive action.\n"); | 311 | pr_info("Pentium Pro with Errata#50 detected. Taking evasive action.\n"); |
315 | return 1; | 312 | return 1; |
316 | } | 313 | } |
@@ -327,7 +324,7 @@ static void intel_smp_check(struct cpuinfo_x86 *c) | |||
327 | * Mask B, Pentium, but not Pentium MMX | 324 | * Mask B, Pentium, but not Pentium MMX |
328 | */ | 325 | */ |
329 | if (c->x86 == 5 && | 326 | if (c->x86 == 5 && |
330 | c->x86_mask >= 1 && c->x86_mask <= 4 && | 327 | c->x86_stepping >= 1 && c->x86_stepping <= 4 && |
331 | c->x86_model <= 3) { | 328 | c->x86_model <= 3) { |
332 | /* | 329 | /* |
333 | * Remember we have B step Pentia with bugs | 330 | * Remember we have B step Pentia with bugs |
@@ -370,7 +367,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c) | |||
370 | * SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until | 367 | * SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until |
371 | * model 3 mask 3 | 368 | * model 3 mask 3 |
372 | */ | 369 | */ |
373 | if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633) | 370 | if ((c->x86<<8 | c->x86_model<<4 | c->x86_stepping) < 0x633) |
374 | clear_cpu_cap(c, X86_FEATURE_SEP); | 371 | clear_cpu_cap(c, X86_FEATURE_SEP); |
375 | 372 | ||
376 | /* | 373 | /* |
@@ -388,7 +385,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c) | |||
388 | * P4 Xeon erratum 037 workaround. | 385 | * P4 Xeon erratum 037 workaround. |
389 | * Hardware prefetcher may cause stale data to be loaded into the cache. | 386 | * Hardware prefetcher may cause stale data to be loaded into the cache. |
390 | */ | 387 | */ |
391 | if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { | 388 | if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_stepping == 1)) { |
392 | if (msr_set_bit(MSR_IA32_MISC_ENABLE, | 389 | if (msr_set_bit(MSR_IA32_MISC_ENABLE, |
393 | MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT) > 0) { | 390 | MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT) > 0) { |
394 | pr_info("CPU: C0 stepping P4 Xeon detected.\n"); | 391 | pr_info("CPU: C0 stepping P4 Xeon detected.\n"); |
@@ -403,7 +400,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c) | |||
403 | * Specification Update"). | 400 | * Specification Update"). |
404 | */ | 401 | */ |
405 | if (boot_cpu_has(X86_FEATURE_APIC) && (c->x86<<8 | c->x86_model<<4) == 0x520 && | 402 | if (boot_cpu_has(X86_FEATURE_APIC) && (c->x86<<8 | c->x86_model<<4) == 0x520 && |
406 | (c->x86_mask < 0x6 || c->x86_mask == 0xb)) | 403 | (c->x86_stepping < 0x6 || c->x86_stepping == 0xb)) |
407 | set_cpu_bug(c, X86_BUG_11AP); | 404 | set_cpu_bug(c, X86_BUG_11AP); |
408 | 405 | ||
409 | 406 | ||
@@ -650,7 +647,7 @@ static void init_intel(struct cpuinfo_x86 *c) | |||
650 | case 6: | 647 | case 6: |
651 | if (l2 == 128) | 648 | if (l2 == 128) |
652 | p = "Celeron (Mendocino)"; | 649 | p = "Celeron (Mendocino)"; |
653 | else if (c->x86_mask == 0 || c->x86_mask == 5) | 650 | else if (c->x86_stepping == 0 || c->x86_stepping == 5) |
654 | p = "Celeron-A"; | 651 | p = "Celeron-A"; |
655 | break; | 652 | break; |
656 | 653 | ||
diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index 410629f10ad3..589b948e6e01 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c | |||
@@ -819,7 +819,7 @@ static __init void rdt_quirks(void) | |||
819 | cache_alloc_hsw_probe(); | 819 | cache_alloc_hsw_probe(); |
820 | break; | 820 | break; |
821 | case INTEL_FAM6_SKYLAKE_X: | 821 | case INTEL_FAM6_SKYLAKE_X: |
822 | if (boot_cpu_data.x86_mask <= 4) | 822 | if (boot_cpu_data.x86_stepping <= 4) |
823 | set_rdt_options("!cmt,!mbmtotal,!mbmlocal,!l3cat"); | 823 | set_rdt_options("!cmt,!mbmtotal,!mbmlocal,!l3cat"); |
824 | } | 824 | } |
825 | } | 825 | } |
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index f7c55b0e753a..a15db2b4e0d6 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c | |||
@@ -921,7 +921,7 @@ static bool is_blacklisted(unsigned int cpu) | |||
921 | */ | 921 | */ |
922 | if (c->x86 == 6 && | 922 | if (c->x86 == 6 && |
923 | c->x86_model == INTEL_FAM6_BROADWELL_X && | 923 | c->x86_model == INTEL_FAM6_BROADWELL_X && |
924 | c->x86_mask == 0x01 && | 924 | c->x86_stepping == 0x01 && |
925 | llc_size_per_core > 2621440 && | 925 | llc_size_per_core > 2621440 && |
926 | c->microcode < 0x0b000021) { | 926 | c->microcode < 0x0b000021) { |
927 | pr_err_once("Erratum BDF90: late loading with revision < 0x0b000021 (0x%x) disabled.\n", c->microcode); | 927 | pr_err_once("Erratum BDF90: late loading with revision < 0x0b000021 (0x%x) disabled.\n", c->microcode); |
@@ -944,7 +944,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device, | |||
944 | return UCODE_NFOUND; | 944 | return UCODE_NFOUND; |
945 | 945 | ||
946 | sprintf(name, "intel-ucode/%02x-%02x-%02x", | 946 | sprintf(name, "intel-ucode/%02x-%02x-%02x", |
947 | c->x86, c->x86_model, c->x86_mask); | 947 | c->x86, c->x86_model, c->x86_stepping); |
948 | 948 | ||
949 | if (request_firmware_direct(&firmware, name, device)) { | 949 | if (request_firmware_direct(&firmware, name, device)) { |
950 | pr_debug("data file %s load failed\n", name); | 950 | pr_debug("data file %s load failed\n", name); |
@@ -982,7 +982,7 @@ static struct microcode_ops microcode_intel_ops = { | |||
982 | 982 | ||
983 | static int __init calc_llc_size_per_core(struct cpuinfo_x86 *c) | 983 | static int __init calc_llc_size_per_core(struct cpuinfo_x86 *c) |
984 | { | 984 | { |
985 | u64 llc_size = c->x86_cache_size * 1024; | 985 | u64 llc_size = c->x86_cache_size * 1024ULL; |
986 | 986 | ||
987 | do_div(llc_size, c->x86_max_cores); | 987 | do_div(llc_size, c->x86_max_cores); |
988 | 988 | ||
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index fdc55215d44d..e12ee86906c6 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
@@ -859,7 +859,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, | |||
859 | */ | 859 | */ |
860 | if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 && | 860 | if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 && |
861 | boot_cpu_data.x86_model == 1 && | 861 | boot_cpu_data.x86_model == 1 && |
862 | boot_cpu_data.x86_mask <= 7) { | 862 | boot_cpu_data.x86_stepping <= 7) { |
863 | if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) { | 863 | if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) { |
864 | pr_warn("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); | 864 | pr_warn("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); |
865 | return -EINVAL; | 865 | return -EINVAL; |
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 40d5a8a75212..7468de429087 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c | |||
@@ -711,8 +711,8 @@ void __init mtrr_bp_init(void) | |||
711 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | 711 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && |
712 | boot_cpu_data.x86 == 0xF && | 712 | boot_cpu_data.x86 == 0xF && |
713 | boot_cpu_data.x86_model == 0x3 && | 713 | boot_cpu_data.x86_model == 0x3 && |
714 | (boot_cpu_data.x86_mask == 0x3 || | 714 | (boot_cpu_data.x86_stepping == 0x3 || |
715 | boot_cpu_data.x86_mask == 0x4)) | 715 | boot_cpu_data.x86_stepping == 0x4)) |
716 | phys_addr = 36; | 716 | phys_addr = 36; |
717 | 717 | ||
718 | size_or_mask = SIZE_OR_MASK_BITS(phys_addr); | 718 | size_or_mask = SIZE_OR_MASK_BITS(phys_addr); |
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index e7ecedafa1c8..2c8522a39ed5 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c | |||
@@ -72,8 +72,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
72 | c->x86_model, | 72 | c->x86_model, |
73 | c->x86_model_id[0] ? c->x86_model_id : "unknown"); | 73 | c->x86_model_id[0] ? c->x86_model_id : "unknown"); |
74 | 74 | ||
75 | if (c->x86_mask || c->cpuid_level >= 0) | 75 | if (c->x86_stepping || c->cpuid_level >= 0) |
76 | seq_printf(m, "stepping\t: %d\n", c->x86_mask); | 76 | seq_printf(m, "stepping\t: %d\n", c->x86_stepping); |
77 | else | 77 | else |
78 | seq_puts(m, "stepping\t: unknown\n"); | 78 | seq_puts(m, "stepping\t: unknown\n"); |
79 | if (c->microcode) | 79 | if (c->microcode) |
@@ -91,8 +91,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
91 | } | 91 | } |
92 | 92 | ||
93 | /* Cache size */ | 93 | /* Cache size */ |
94 | if (c->x86_cache_size >= 0) | 94 | if (c->x86_cache_size) |
95 | seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); | 95 | seq_printf(m, "cache size\t: %u KB\n", c->x86_cache_size); |
96 | 96 | ||
97 | show_cpuinfo_core(m, c, cpu); | 97 | show_cpuinfo_core(m, c, cpu); |
98 | show_cpuinfo_misc(m, c); | 98 | show_cpuinfo_misc(m, c); |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index c29020907886..b59e4fb40fd9 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -37,7 +37,7 @@ | |||
37 | #define X86 new_cpu_data+CPUINFO_x86 | 37 | #define X86 new_cpu_data+CPUINFO_x86 |
38 | #define X86_VENDOR new_cpu_data+CPUINFO_x86_vendor | 38 | #define X86_VENDOR new_cpu_data+CPUINFO_x86_vendor |
39 | #define X86_MODEL new_cpu_data+CPUINFO_x86_model | 39 | #define X86_MODEL new_cpu_data+CPUINFO_x86_model |
40 | #define X86_MASK new_cpu_data+CPUINFO_x86_mask | 40 | #define X86_STEPPING new_cpu_data+CPUINFO_x86_stepping |
41 | #define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math | 41 | #define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math |
42 | #define X86_CPUID new_cpu_data+CPUINFO_cpuid_level | 42 | #define X86_CPUID new_cpu_data+CPUINFO_cpuid_level |
43 | #define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability | 43 | #define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability |
@@ -332,7 +332,7 @@ ENTRY(startup_32_smp) | |||
332 | shrb $4,%al | 332 | shrb $4,%al |
333 | movb %al,X86_MODEL | 333 | movb %al,X86_MODEL |
334 | andb $0x0f,%cl # mask mask revision | 334 | andb $0x0f,%cl # mask mask revision |
335 | movb %cl,X86_MASK | 335 | movb %cl,X86_STEPPING |
336 | movl %edx,X86_CAPABILITY | 336 | movl %edx,X86_CAPABILITY |
337 | 337 | ||
338 | .Lis486: | 338 | .Lis486: |
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 27d0a1712663..f1c5eb99d445 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
@@ -410,7 +410,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) | |||
410 | processor.apicver = mpc_default_type > 4 ? 0x10 : 0x01; | 410 | processor.apicver = mpc_default_type > 4 ? 0x10 : 0x01; |
411 | processor.cpuflag = CPU_ENABLED; | 411 | processor.cpuflag = CPU_ENABLED; |
412 | processor.cpufeature = (boot_cpu_data.x86 << 8) | | 412 | processor.cpufeature = (boot_cpu_data.x86 << 8) | |
413 | (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask; | 413 | (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_stepping; |
414 | processor.featureflag = boot_cpu_data.x86_capability[CPUID_1_EDX]; | 414 | processor.featureflag = boot_cpu_data.x86_capability[CPUID_1_EDX]; |
415 | processor.reserved[0] = 0; | 415 | processor.reserved[0] = 0; |
416 | processor.reserved[1] = 0; | 416 | processor.reserved[1] = 0; |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 041096bdef86..99dc79e76bdc 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -200,9 +200,9 @@ static void native_flush_tlb_global(void) | |||
200 | __native_flush_tlb_global(); | 200 | __native_flush_tlb_global(); |
201 | } | 201 | } |
202 | 202 | ||
203 | static void native_flush_tlb_single(unsigned long addr) | 203 | static void native_flush_tlb_one_user(unsigned long addr) |
204 | { | 204 | { |
205 | __native_flush_tlb_single(addr); | 205 | __native_flush_tlb_one_user(addr); |
206 | } | 206 | } |
207 | 207 | ||
208 | struct static_key paravirt_steal_enabled; | 208 | struct static_key paravirt_steal_enabled; |
@@ -401,7 +401,7 @@ struct pv_mmu_ops pv_mmu_ops __ro_after_init = { | |||
401 | 401 | ||
402 | .flush_tlb_user = native_flush_tlb, | 402 | .flush_tlb_user = native_flush_tlb, |
403 | .flush_tlb_kernel = native_flush_tlb_global, | 403 | .flush_tlb_kernel = native_flush_tlb_global, |
404 | .flush_tlb_single = native_flush_tlb_single, | 404 | .flush_tlb_one_user = native_flush_tlb_one_user, |
405 | .flush_tlb_others = native_flush_tlb_others, | 405 | .flush_tlb_others = native_flush_tlb_others, |
406 | 406 | ||
407 | .pgd_alloc = __paravirt_pgd_alloc, | 407 | .pgd_alloc = __paravirt_pgd_alloc, |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 446c9ef8cfc3..3d9b2308e7fa 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -181,7 +181,7 @@ int fixup_bug(struct pt_regs *regs, int trapnr) | |||
181 | break; | 181 | break; |
182 | 182 | ||
183 | case BUG_TRAP_TYPE_WARN: | 183 | case BUG_TRAP_TYPE_WARN: |
184 | regs->ip += LEN_UD0; | 184 | regs->ip += LEN_UD2; |
185 | return 1; | 185 | return 1; |
186 | } | 186 | } |
187 | 187 | ||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 8eca1d04aeb8..46ff304140c7 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -5080,7 +5080,7 @@ void kvm_mmu_uninit_vm(struct kvm *kvm) | |||
5080 | typedef bool (*slot_level_handler) (struct kvm *kvm, struct kvm_rmap_head *rmap_head); | 5080 | typedef bool (*slot_level_handler) (struct kvm *kvm, struct kvm_rmap_head *rmap_head); |
5081 | 5081 | ||
5082 | /* The caller should hold mmu-lock before calling this function. */ | 5082 | /* The caller should hold mmu-lock before calling this function. */ |
5083 | static bool | 5083 | static __always_inline bool |
5084 | slot_handle_level_range(struct kvm *kvm, struct kvm_memory_slot *memslot, | 5084 | slot_handle_level_range(struct kvm *kvm, struct kvm_memory_slot *memslot, |
5085 | slot_level_handler fn, int start_level, int end_level, | 5085 | slot_level_handler fn, int start_level, int end_level, |
5086 | gfn_t start_gfn, gfn_t end_gfn, bool lock_flush_tlb) | 5086 | gfn_t start_gfn, gfn_t end_gfn, bool lock_flush_tlb) |
@@ -5110,7 +5110,7 @@ slot_handle_level_range(struct kvm *kvm, struct kvm_memory_slot *memslot, | |||
5110 | return flush; | 5110 | return flush; |
5111 | } | 5111 | } |
5112 | 5112 | ||
5113 | static bool | 5113 | static __always_inline bool |
5114 | slot_handle_level(struct kvm *kvm, struct kvm_memory_slot *memslot, | 5114 | slot_handle_level(struct kvm *kvm, struct kvm_memory_slot *memslot, |
5115 | slot_level_handler fn, int start_level, int end_level, | 5115 | slot_level_handler fn, int start_level, int end_level, |
5116 | bool lock_flush_tlb) | 5116 | bool lock_flush_tlb) |
@@ -5121,7 +5121,7 @@ slot_handle_level(struct kvm *kvm, struct kvm_memory_slot *memslot, | |||
5121 | lock_flush_tlb); | 5121 | lock_flush_tlb); |
5122 | } | 5122 | } |
5123 | 5123 | ||
5124 | static bool | 5124 | static __always_inline bool |
5125 | slot_handle_all_level(struct kvm *kvm, struct kvm_memory_slot *memslot, | 5125 | slot_handle_all_level(struct kvm *kvm, struct kvm_memory_slot *memslot, |
5126 | slot_level_handler fn, bool lock_flush_tlb) | 5126 | slot_level_handler fn, bool lock_flush_tlb) |
5127 | { | 5127 | { |
@@ -5129,7 +5129,7 @@ slot_handle_all_level(struct kvm *kvm, struct kvm_memory_slot *memslot, | |||
5129 | PT_MAX_HUGEPAGE_LEVEL, lock_flush_tlb); | 5129 | PT_MAX_HUGEPAGE_LEVEL, lock_flush_tlb); |
5130 | } | 5130 | } |
5131 | 5131 | ||
5132 | static bool | 5132 | static __always_inline bool |
5133 | slot_handle_large_level(struct kvm *kvm, struct kvm_memory_slot *memslot, | 5133 | slot_handle_large_level(struct kvm *kvm, struct kvm_memory_slot *memslot, |
5134 | slot_level_handler fn, bool lock_flush_tlb) | 5134 | slot_level_handler fn, bool lock_flush_tlb) |
5135 | { | 5135 | { |
@@ -5137,7 +5137,7 @@ slot_handle_large_level(struct kvm *kvm, struct kvm_memory_slot *memslot, | |||
5137 | PT_MAX_HUGEPAGE_LEVEL, lock_flush_tlb); | 5137 | PT_MAX_HUGEPAGE_LEVEL, lock_flush_tlb); |
5138 | } | 5138 | } |
5139 | 5139 | ||
5140 | static bool | 5140 | static __always_inline bool |
5141 | slot_handle_leaf(struct kvm *kvm, struct kvm_memory_slot *memslot, | 5141 | slot_handle_leaf(struct kvm *kvm, struct kvm_memory_slot *memslot, |
5142 | slot_level_handler fn, bool lock_flush_tlb) | 5142 | slot_level_handler fn, bool lock_flush_tlb) |
5143 | { | 5143 | { |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f427723dc7db..3dec126aa302 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -10136,7 +10136,10 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu, | |||
10136 | (unsigned long)(vmcs12->posted_intr_desc_addr & | 10136 | (unsigned long)(vmcs12->posted_intr_desc_addr & |
10137 | (PAGE_SIZE - 1))); | 10137 | (PAGE_SIZE - 1))); |
10138 | } | 10138 | } |
10139 | if (!nested_vmx_prepare_msr_bitmap(vcpu, vmcs12)) | 10139 | if (nested_vmx_prepare_msr_bitmap(vcpu, vmcs12)) |
10140 | vmcs_set_bits(CPU_BASED_VM_EXEC_CONTROL, | ||
10141 | CPU_BASED_USE_MSR_BITMAPS); | ||
10142 | else | ||
10140 | vmcs_clear_bits(CPU_BASED_VM_EXEC_CONTROL, | 10143 | vmcs_clear_bits(CPU_BASED_VM_EXEC_CONTROL, |
10141 | CPU_BASED_USE_MSR_BITMAPS); | 10144 | CPU_BASED_USE_MSR_BITMAPS); |
10142 | } | 10145 | } |
@@ -10224,8 +10227,8 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu, | |||
10224 | * updated to reflect this when L1 (or its L2s) actually write to | 10227 | * updated to reflect this when L1 (or its L2s) actually write to |
10225 | * the MSR. | 10228 | * the MSR. |
10226 | */ | 10229 | */ |
10227 | bool pred_cmd = msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD); | 10230 | bool pred_cmd = !msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD); |
10228 | bool spec_ctrl = msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL); | 10231 | bool spec_ctrl = !msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL); |
10229 | 10232 | ||
10230 | /* Nothing to do if the MSR bitmap is not in use. */ | 10233 | /* Nothing to do if the MSR bitmap is not in use. */ |
10231 | if (!cpu_has_vmx_msr_bitmap() || | 10234 | if (!cpu_has_vmx_msr_bitmap() || |
diff --git a/arch/x86/lib/cpu.c b/arch/x86/lib/cpu.c index d6f848d1211d..2dd1fe13a37b 100644 --- a/arch/x86/lib/cpu.c +++ b/arch/x86/lib/cpu.c | |||
@@ -18,7 +18,7 @@ unsigned int x86_model(unsigned int sig) | |||
18 | { | 18 | { |
19 | unsigned int fam, model; | 19 | unsigned int fam, model; |
20 | 20 | ||
21 | fam = x86_family(sig); | 21 | fam = x86_family(sig); |
22 | 22 | ||
23 | model = (sig >> 4) & 0xf; | 23 | model = (sig >> 4) & 0xf; |
24 | 24 | ||
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 1ab42c852069..fecb0c0a6077 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -256,7 +256,7 @@ static void __set_pte_vaddr(pud_t *pud, unsigned long vaddr, pte_t new_pte) | |||
256 | * It's enough to flush this one mapping. | 256 | * It's enough to flush this one mapping. |
257 | * (PGE mappings get flushed as well) | 257 | * (PGE mappings get flushed as well) |
258 | */ | 258 | */ |
259 | __flush_tlb_one(vaddr); | 259 | __flush_tlb_one_kernel(vaddr); |
260 | } | 260 | } |
261 | 261 | ||
262 | void set_pte_vaddr_p4d(p4d_t *p4d_page, unsigned long vaddr, pte_t new_pte) | 262 | void set_pte_vaddr_p4d(p4d_t *p4d_page, unsigned long vaddr, pte_t new_pte) |
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index c45b6ec5357b..e2db83bebc3b 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -820,5 +820,5 @@ void __init __early_set_fixmap(enum fixed_addresses idx, | |||
820 | set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags)); | 820 | set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags)); |
821 | else | 821 | else |
822 | pte_clear(&init_mm, addr, pte); | 822 | pte_clear(&init_mm, addr, pte); |
823 | __flush_tlb_one(addr); | 823 | __flush_tlb_one_kernel(addr); |
824 | } | 824 | } |
diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 58477ec3d66d..7c8686709636 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c | |||
@@ -168,7 +168,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear) | |||
168 | return -1; | 168 | return -1; |
169 | } | 169 | } |
170 | 170 | ||
171 | __flush_tlb_one(f->addr); | 171 | __flush_tlb_one_kernel(f->addr); |
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
174 | 174 | ||
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index c3c5274410a9..9bb7f0ab9fe6 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c | |||
@@ -63,7 +63,7 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pteval) | |||
63 | * It's enough to flush this one mapping. | 63 | * It's enough to flush this one mapping. |
64 | * (PGE mappings get flushed as well) | 64 | * (PGE mappings get flushed as well) |
65 | */ | 65 | */ |
66 | __flush_tlb_one(vaddr); | 66 | __flush_tlb_one_kernel(vaddr); |
67 | } | 67 | } |
68 | 68 | ||
69 | unsigned long __FIXADDR_TOP = 0xfffff000; | 69 | unsigned long __FIXADDR_TOP = 0xfffff000; |
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 8dcc0607f805..7f1a51399674 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c | |||
@@ -498,7 +498,7 @@ static void flush_tlb_func_common(const struct flush_tlb_info *f, | |||
498 | * flush that changes context.tlb_gen from 2 to 3. If they get | 498 | * flush that changes context.tlb_gen from 2 to 3. If they get |
499 | * processed on this CPU in reverse order, we'll see | 499 | * processed on this CPU in reverse order, we'll see |
500 | * local_tlb_gen == 1, mm_tlb_gen == 3, and end != TLB_FLUSH_ALL. | 500 | * local_tlb_gen == 1, mm_tlb_gen == 3, and end != TLB_FLUSH_ALL. |
501 | * If we were to use __flush_tlb_single() and set local_tlb_gen to | 501 | * If we were to use __flush_tlb_one_user() and set local_tlb_gen to |
502 | * 3, we'd be break the invariant: we'd update local_tlb_gen above | 502 | * 3, we'd be break the invariant: we'd update local_tlb_gen above |
503 | * 1 without the full flush that's needed for tlb_gen 2. | 503 | * 1 without the full flush that's needed for tlb_gen 2. |
504 | * | 504 | * |
@@ -519,7 +519,7 @@ static void flush_tlb_func_common(const struct flush_tlb_info *f, | |||
519 | 519 | ||
520 | addr = f->start; | 520 | addr = f->start; |
521 | while (addr < f->end) { | 521 | while (addr < f->end) { |
522 | __flush_tlb_single(addr); | 522 | __flush_tlb_one_user(addr); |
523 | addr += PAGE_SIZE; | 523 | addr += PAGE_SIZE; |
524 | } | 524 | } |
525 | if (local) | 525 | if (local) |
@@ -666,7 +666,7 @@ static void do_kernel_range_flush(void *info) | |||
666 | 666 | ||
667 | /* flush range by one by one 'invlpg' */ | 667 | /* flush range by one by one 'invlpg' */ |
668 | for (addr = f->start; addr < f->end; addr += PAGE_SIZE) | 668 | for (addr = f->start; addr < f->end; addr += PAGE_SIZE) |
669 | __flush_tlb_one(addr); | 669 | __flush_tlb_one_kernel(addr); |
670 | } | 670 | } |
671 | 671 | ||
672 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | 672 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) |
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index c2e9285d1bf1..db77e087adaf 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c | |||
@@ -299,7 +299,7 @@ static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp, | |||
299 | local_flush_tlb(); | 299 | local_flush_tlb(); |
300 | stat->d_alltlb++; | 300 | stat->d_alltlb++; |
301 | } else { | 301 | } else { |
302 | __flush_tlb_single(msg->address); | 302 | __flush_tlb_one_user(msg->address); |
303 | stat->d_onetlb++; | 303 | stat->d_onetlb++; |
304 | } | 304 | } |
305 | stat->d_requestee++; | 305 | stat->d_requestee++; |
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index d85076223a69..aae88fec9941 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c | |||
@@ -1300,12 +1300,12 @@ static void xen_flush_tlb(void) | |||
1300 | preempt_enable(); | 1300 | preempt_enable(); |
1301 | } | 1301 | } |
1302 | 1302 | ||
1303 | static void xen_flush_tlb_single(unsigned long addr) | 1303 | static void xen_flush_tlb_one_user(unsigned long addr) |
1304 | { | 1304 | { |
1305 | struct mmuext_op *op; | 1305 | struct mmuext_op *op; |
1306 | struct multicall_space mcs; | 1306 | struct multicall_space mcs; |
1307 | 1307 | ||
1308 | trace_xen_mmu_flush_tlb_single(addr); | 1308 | trace_xen_mmu_flush_tlb_one_user(addr); |
1309 | 1309 | ||
1310 | preempt_disable(); | 1310 | preempt_disable(); |
1311 | 1311 | ||
@@ -2370,7 +2370,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { | |||
2370 | 2370 | ||
2371 | .flush_tlb_user = xen_flush_tlb, | 2371 | .flush_tlb_user = xen_flush_tlb, |
2372 | .flush_tlb_kernel = xen_flush_tlb, | 2372 | .flush_tlb_kernel = xen_flush_tlb, |
2373 | .flush_tlb_single = xen_flush_tlb_single, | 2373 | .flush_tlb_one_user = xen_flush_tlb_one_user, |
2374 | .flush_tlb_others = xen_flush_tlb_others, | 2374 | .flush_tlb_others = xen_flush_tlb_others, |
2375 | 2375 | ||
2376 | .pgd_alloc = xen_pgd_alloc, | 2376 | .pgd_alloc = xen_pgd_alloc, |
diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c index d1f5bb534e0e..6e9df558325b 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c | |||
@@ -162,7 +162,7 @@ static int via_rng_init(struct hwrng *rng) | |||
162 | /* Enable secondary noise source on CPUs where it is present. */ | 162 | /* Enable secondary noise source on CPUs where it is present. */ |
163 | 163 | ||
164 | /* Nehemiah stepping 8 and higher */ | 164 | /* Nehemiah stepping 8 and higher */ |
165 | if ((c->x86_model == 9) && (c->x86_mask > 7)) | 165 | if ((c->x86_model == 9) && (c->x86_stepping > 7)) |
166 | lo |= VIA_NOISESRC2; | 166 | lo |= VIA_NOISESRC2; |
167 | 167 | ||
168 | /* Esther */ | 168 | /* Esther */ |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 3a2ca0f79daf..d0c34df0529c 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
@@ -629,7 +629,7 @@ static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) | |||
629 | if (c->x86_vendor == X86_VENDOR_INTEL) { | 629 | if (c->x86_vendor == X86_VENDOR_INTEL) { |
630 | if ((c->x86 == 15) && | 630 | if ((c->x86 == 15) && |
631 | (c->x86_model == 6) && | 631 | (c->x86_model == 6) && |
632 | (c->x86_mask == 8)) { | 632 | (c->x86_stepping == 8)) { |
633 | pr_info("Intel(R) Xeon(R) 7100 Errata AL30, processors may lock up on frequency changes: disabling acpi-cpufreq\n"); | 633 | pr_info("Intel(R) Xeon(R) 7100 Errata AL30, processors may lock up on frequency changes: disabling acpi-cpufreq\n"); |
634 | return -ENODEV; | 634 | return -ENODEV; |
635 | } | 635 | } |
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 942632a27b50..f730b6528c18 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c | |||
@@ -775,7 +775,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy) | |||
775 | break; | 775 | break; |
776 | 776 | ||
777 | case 7: | 777 | case 7: |
778 | switch (c->x86_mask) { | 778 | switch (c->x86_stepping) { |
779 | case 0: | 779 | case 0: |
780 | longhaul_version = TYPE_LONGHAUL_V1; | 780 | longhaul_version = TYPE_LONGHAUL_V1; |
781 | cpu_model = CPU_SAMUEL2; | 781 | cpu_model = CPU_SAMUEL2; |
@@ -787,7 +787,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy) | |||
787 | break; | 787 | break; |
788 | case 1 ... 15: | 788 | case 1 ... 15: |
789 | longhaul_version = TYPE_LONGHAUL_V2; | 789 | longhaul_version = TYPE_LONGHAUL_V2; |
790 | if (c->x86_mask < 8) { | 790 | if (c->x86_stepping < 8) { |
791 | cpu_model = CPU_SAMUEL2; | 791 | cpu_model = CPU_SAMUEL2; |
792 | cpuname = "C3 'Samuel 2' [C5B]"; | 792 | cpuname = "C3 'Samuel 2' [C5B]"; |
793 | } else { | 793 | } else { |
@@ -814,7 +814,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy) | |||
814 | numscales = 32; | 814 | numscales = 32; |
815 | memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults)); | 815 | memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults)); |
816 | memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr)); | 816 | memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr)); |
817 | switch (c->x86_mask) { | 817 | switch (c->x86_stepping) { |
818 | case 0 ... 1: | 818 | case 0 ... 1: |
819 | cpu_model = CPU_NEHEMIAH; | 819 | cpu_model = CPU_NEHEMIAH; |
820 | cpuname = "C3 'Nehemiah A' [C5XLOE]"; | 820 | cpuname = "C3 'Nehemiah A' [C5XLOE]"; |
diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c index fd77812313f3..a25741b1281b 100644 --- a/drivers/cpufreq/p4-clockmod.c +++ b/drivers/cpufreq/p4-clockmod.c | |||
@@ -168,7 +168,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | |||
168 | #endif | 168 | #endif |
169 | 169 | ||
170 | /* Errata workaround */ | 170 | /* Errata workaround */ |
171 | cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_mask; | 171 | cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_stepping; |
172 | switch (cpuid) { | 172 | switch (cpuid) { |
173 | case 0x0f07: | 173 | case 0x0f07: |
174 | case 0x0f0a: | 174 | case 0x0f0a: |
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 80ac313e6c59..302e9ce793a0 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c | |||
@@ -131,7 +131,7 @@ static int check_powernow(void) | |||
131 | return 0; | 131 | return 0; |
132 | } | 132 | } |
133 | 133 | ||
134 | if ((c->x86_model == 6) && (c->x86_mask == 0)) { | 134 | if ((c->x86_model == 6) && (c->x86_stepping == 0)) { |
135 | pr_info("K7 660[A0] core detected, enabling errata workarounds\n"); | 135 | pr_info("K7 660[A0] core detected, enabling errata workarounds\n"); |
136 | have_a0 = 1; | 136 | have_a0 = 1; |
137 | } | 137 | } |
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c index 41bc5397f4bb..4fa5adf16c70 100644 --- a/drivers/cpufreq/speedstep-centrino.c +++ b/drivers/cpufreq/speedstep-centrino.c | |||
@@ -37,7 +37,7 @@ struct cpu_id | |||
37 | { | 37 | { |
38 | __u8 x86; /* CPU family */ | 38 | __u8 x86; /* CPU family */ |
39 | __u8 x86_model; /* model */ | 39 | __u8 x86_model; /* model */ |
40 | __u8 x86_mask; /* stepping */ | 40 | __u8 x86_stepping; /* stepping */ |
41 | }; | 41 | }; |
42 | 42 | ||
43 | enum { | 43 | enum { |
@@ -277,7 +277,7 @@ static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, | |||
277 | { | 277 | { |
278 | if ((c->x86 == x->x86) && | 278 | if ((c->x86 == x->x86) && |
279 | (c->x86_model == x->x86_model) && | 279 | (c->x86_model == x->x86_model) && |
280 | (c->x86_mask == x->x86_mask)) | 280 | (c->x86_stepping == x->x86_stepping)) |
281 | return 1; | 281 | return 1; |
282 | return 0; | 282 | return 0; |
283 | } | 283 | } |
diff --git a/drivers/cpufreq/speedstep-lib.c b/drivers/cpufreq/speedstep-lib.c index 8085ec9000d1..e3a9962ee410 100644 --- a/drivers/cpufreq/speedstep-lib.c +++ b/drivers/cpufreq/speedstep-lib.c | |||
@@ -272,9 +272,9 @@ unsigned int speedstep_detect_processor(void) | |||
272 | ebx = cpuid_ebx(0x00000001); | 272 | ebx = cpuid_ebx(0x00000001); |
273 | ebx &= 0x000000FF; | 273 | ebx &= 0x000000FF; |
274 | 274 | ||
275 | pr_debug("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask); | 275 | pr_debug("ebx value is %x, x86_stepping is %x\n", ebx, c->x86_stepping); |
276 | 276 | ||
277 | switch (c->x86_mask) { | 277 | switch (c->x86_stepping) { |
278 | case 4: | 278 | case 4: |
279 | /* | 279 | /* |
280 | * B-stepping [M-P4-M] | 280 | * B-stepping [M-P4-M] |
@@ -361,7 +361,7 @@ unsigned int speedstep_detect_processor(void) | |||
361 | msr_lo, msr_hi); | 361 | msr_lo, msr_hi); |
362 | if ((msr_hi & (1<<18)) && | 362 | if ((msr_hi & (1<<18)) && |
363 | (relaxed_check ? 1 : (msr_hi & (3<<24)))) { | 363 | (relaxed_check ? 1 : (msr_hi & (3<<24)))) { |
364 | if (c->x86_mask == 0x01) { | 364 | if (c->x86_stepping == 0x01) { |
365 | pr_debug("early PIII version\n"); | 365 | pr_debug("early PIII version\n"); |
366 | return SPEEDSTEP_CPU_PIII_C_EARLY; | 366 | return SPEEDSTEP_CPU_PIII_C_EARLY; |
367 | } else | 367 | } else |
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 4b6642a25df5..1c6cbda56afe 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c | |||
@@ -512,7 +512,7 @@ static int __init padlock_init(void) | |||
512 | 512 | ||
513 | printk(KERN_NOTICE PFX "Using VIA PadLock ACE for AES algorithm.\n"); | 513 | printk(KERN_NOTICE PFX "Using VIA PadLock ACE for AES algorithm.\n"); |
514 | 514 | ||
515 | if (c->x86 == 6 && c->x86_model == 15 && c->x86_mask == 2) { | 515 | if (c->x86 == 6 && c->x86_model == 15 && c->x86_stepping == 2) { |
516 | ecb_fetch_blocks = MAX_ECB_FETCH_BLOCKS; | 516 | ecb_fetch_blocks = MAX_ECB_FETCH_BLOCKS; |
517 | cbc_fetch_blocks = MAX_CBC_FETCH_BLOCKS; | 517 | cbc_fetch_blocks = MAX_CBC_FETCH_BLOCKS; |
518 | printk(KERN_NOTICE PFX "VIA Nano stepping 2 detected: enabling workaround.\n"); | 518 | printk(KERN_NOTICE PFX "VIA Nano stepping 2 detected: enabling workaround.\n"); |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 8b16ec595fa7..329cb96f886f 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -3147,7 +3147,7 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt) | |||
3147 | struct amd64_family_type *fam_type = NULL; | 3147 | struct amd64_family_type *fam_type = NULL; |
3148 | 3148 | ||
3149 | pvt->ext_model = boot_cpu_data.x86_model >> 4; | 3149 | pvt->ext_model = boot_cpu_data.x86_model >> 4; |
3150 | pvt->stepping = boot_cpu_data.x86_mask; | 3150 | pvt->stepping = boot_cpu_data.x86_stepping; |
3151 | pvt->model = boot_cpu_data.x86_model; | 3151 | pvt->model = boot_cpu_data.x86_model; |
3152 | pvt->fam = boot_cpu_data.x86; | 3152 | pvt->fam = boot_cpu_data.x86; |
3153 | 3153 | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 4bdbf77f7197..72c338eb5fae 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -269,13 +269,13 @@ static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | |||
269 | for (i = 0; i < ARRAY_SIZE(tjmax_model_table); i++) { | 269 | for (i = 0; i < ARRAY_SIZE(tjmax_model_table); i++) { |
270 | const struct tjmax_model *tm = &tjmax_model_table[i]; | 270 | const struct tjmax_model *tm = &tjmax_model_table[i]; |
271 | if (c->x86_model == tm->model && | 271 | if (c->x86_model == tm->model && |
272 | (tm->mask == ANY || c->x86_mask == tm->mask)) | 272 | (tm->mask == ANY || c->x86_stepping == tm->mask)) |
273 | return tm->tjmax; | 273 | return tm->tjmax; |
274 | } | 274 | } |
275 | 275 | ||
276 | /* Early chips have no MSR for TjMax */ | 276 | /* Early chips have no MSR for TjMax */ |
277 | 277 | ||
278 | if (c->x86_model == 0xf && c->x86_mask < 4) | 278 | if (c->x86_model == 0xf && c->x86_stepping < 4) |
279 | usemsr_ee = 0; | 279 | usemsr_ee = 0; |
280 | 280 | ||
281 | if (c->x86_model > 0xe && usemsr_ee) { | 281 | if (c->x86_model > 0xe && usemsr_ee) { |
@@ -426,7 +426,7 @@ static int chk_ucode_version(unsigned int cpu) | |||
426 | * Readings might stop update when processor visited too deep sleep, | 426 | * Readings might stop update when processor visited too deep sleep, |
427 | * fixed for stepping D0 (6EC). | 427 | * fixed for stepping D0 (6EC). |
428 | */ | 428 | */ |
429 | if (c->x86_model == 0xe && c->x86_mask < 0xc && c->microcode < 0x39) { | 429 | if (c->x86_model == 0xe && c->x86_stepping < 0xc && c->microcode < 0x39) { |
430 | pr_err("Errata AE18 not fixed, update BIOS or microcode of the CPU!\n"); | 430 | pr_err("Errata AE18 not fixed, update BIOS or microcode of the CPU!\n"); |
431 | return -ENODEV; | 431 | return -ENODEV; |
432 | } | 432 | } |
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index ef91b8a67549..84e91286fc4f 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c | |||
@@ -293,7 +293,7 @@ u8 vid_which_vrm(void) | |||
293 | if (c->x86 < 6) /* Any CPU with family lower than 6 */ | 293 | if (c->x86 < 6) /* Any CPU with family lower than 6 */ |
294 | return 0; /* doesn't have VID */ | 294 | return 0; /* doesn't have VID */ |
295 | 295 | ||
296 | vrm_ret = find_vrm(c->x86, c->x86_model, c->x86_mask, c->x86_vendor); | 296 | vrm_ret = find_vrm(c->x86, c->x86_model, c->x86_stepping, c->x86_vendor); |
297 | if (vrm_ret == 134) | 297 | if (vrm_ret == 134) |
298 | vrm_ret = get_via_model_d_vrm(); | 298 | vrm_ret = get_via_model_d_vrm(); |
299 | if (vrm_ret == 0) | 299 | if (vrm_ret == 0) |
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 06b4e1c78bd8..30303632fbb7 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c | |||
@@ -227,7 +227,7 @@ static bool has_erratum_319(struct pci_dev *pdev) | |||
227 | * and AM3 formats, but that's the best we can do. | 227 | * and AM3 formats, but that's the best we can do. |
228 | */ | 228 | */ |
229 | return boot_cpu_data.x86_model < 4 || | 229 | return boot_cpu_data.x86_model < 4 || |
230 | (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_mask <= 2); | 230 | (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_stepping <= 2); |
231 | } | 231 | } |
232 | 232 | ||
233 | static int k10temp_probe(struct pci_dev *pdev, | 233 | static int k10temp_probe(struct pci_dev *pdev, |
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 5a632bcf869b..e59f9113fb93 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c | |||
@@ -187,7 +187,7 @@ static int k8temp_probe(struct pci_dev *pdev, | |||
187 | return -ENOMEM; | 187 | return -ENOMEM; |
188 | 188 | ||
189 | model = boot_cpu_data.x86_model; | 189 | model = boot_cpu_data.x86_model; |
190 | stepping = boot_cpu_data.x86_mask; | 190 | stepping = boot_cpu_data.x86_stepping; |
191 | 191 | ||
192 | /* feature available since SH-C0, exclude older revisions */ | 192 | /* feature available since SH-C0, exclude older revisions */ |
193 | if ((model == 4 && stepping == 0) || | 193 | if ((model == 4 && stepping == 0) || |
diff --git a/drivers/video/fbdev/geode/video_gx.c b/drivers/video/fbdev/geode/video_gx.c index 6082f653c68a..67773e8bbb95 100644 --- a/drivers/video/fbdev/geode/video_gx.c +++ b/drivers/video/fbdev/geode/video_gx.c | |||
@@ -127,7 +127,7 @@ void gx_set_dclk_frequency(struct fb_info *info) | |||
127 | int timeout = 1000; | 127 | int timeout = 1000; |
128 | 128 | ||
129 | /* Rev. 1 Geode GXs use a 14 MHz reference clock instead of 48 MHz. */ | 129 | /* Rev. 1 Geode GXs use a 14 MHz reference clock instead of 48 MHz. */ |
130 | if (cpu_data(0).x86_mask == 1) { | 130 | if (cpu_data(0).x86_stepping == 1) { |
131 | pll_table = gx_pll_table_14MHz; | 131 | pll_table = gx_pll_table_14MHz; |
132 | pll_table_len = ARRAY_SIZE(gx_pll_table_14MHz); | 132 | pll_table_len = ARRAY_SIZE(gx_pll_table_14MHz); |
133 | } else { | 133 | } else { |
diff --git a/include/linux/nospec.h b/include/linux/nospec.h index b99bced39ac2..fbc98e2c8228 100644 --- a/include/linux/nospec.h +++ b/include/linux/nospec.h | |||
@@ -20,20 +20,6 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, | |||
20 | unsigned long size) | 20 | unsigned long size) |
21 | { | 21 | { |
22 | /* | 22 | /* |
23 | * Warn developers about inappropriate array_index_nospec() usage. | ||
24 | * | ||
25 | * Even if the CPU speculates past the WARN_ONCE branch, the | ||
26 | * sign bit of @index is taken into account when generating the | ||
27 | * mask. | ||
28 | * | ||
29 | * This warning is compiled out when the compiler can infer that | ||
30 | * @index and @size are less than LONG_MAX. | ||
31 | */ | ||
32 | if (WARN_ONCE(index > LONG_MAX || size > LONG_MAX, | ||
33 | "array_index_nospec() limited to range of [0, LONG_MAX]\n")) | ||
34 | return 0; | ||
35 | |||
36 | /* | ||
37 | * Always calculate and emit the mask even if the compiler | 23 | * Always calculate and emit the mask even if the compiler |
38 | * thinks the mask is not needed. The compiler does not take | 24 | * thinks the mask is not needed. The compiler does not take |
39 | * into account the value of @index under speculation. | 25 | * into account the value of @index under speculation. |
@@ -44,6 +30,26 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, | |||
44 | #endif | 30 | #endif |
45 | 31 | ||
46 | /* | 32 | /* |
33 | * Warn developers about inappropriate array_index_nospec() usage. | ||
34 | * | ||
35 | * Even if the CPU speculates past the WARN_ONCE branch, the | ||
36 | * sign bit of @index is taken into account when generating the | ||
37 | * mask. | ||
38 | * | ||
39 | * This warning is compiled out when the compiler can infer that | ||
40 | * @index and @size are less than LONG_MAX. | ||
41 | */ | ||
42 | #define array_index_mask_nospec_check(index, size) \ | ||
43 | ({ \ | ||
44 | if (WARN_ONCE(index > LONG_MAX || size > LONG_MAX, \ | ||
45 | "array_index_nospec() limited to range of [0, LONG_MAX]\n")) \ | ||
46 | _mask = 0; \ | ||
47 | else \ | ||
48 | _mask = array_index_mask_nospec(index, size); \ | ||
49 | _mask; \ | ||
50 | }) | ||
51 | |||
52 | /* | ||
47 | * array_index_nospec - sanitize an array index after a bounds check | 53 | * array_index_nospec - sanitize an array index after a bounds check |
48 | * | 54 | * |
49 | * For a code sequence like: | 55 | * For a code sequence like: |
@@ -61,7 +67,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, | |||
61 | ({ \ | 67 | ({ \ |
62 | typeof(index) _i = (index); \ | 68 | typeof(index) _i = (index); \ |
63 | typeof(size) _s = (size); \ | 69 | typeof(size) _s = (size); \ |
64 | unsigned long _mask = array_index_mask_nospec(_i, _s); \ | 70 | unsigned long _mask = array_index_mask_nospec_check(_i, _s); \ |
65 | \ | 71 | \ |
66 | BUILD_BUG_ON(sizeof(_i) > sizeof(long)); \ | 72 | BUILD_BUG_ON(sizeof(_i) > sizeof(long)); \ |
67 | BUILD_BUG_ON(sizeof(_s) > sizeof(long)); \ | 73 | BUILD_BUG_ON(sizeof(_s) > sizeof(long)); \ |
diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h index b8adf05c534e..7dd8f34c37df 100644 --- a/include/trace/events/xen.h +++ b/include/trace/events/xen.h | |||
@@ -368,7 +368,7 @@ TRACE_EVENT(xen_mmu_flush_tlb, | |||
368 | TP_printk("%s", "") | 368 | TP_printk("%s", "") |
369 | ); | 369 | ); |
370 | 370 | ||
371 | TRACE_EVENT(xen_mmu_flush_tlb_single, | 371 | TRACE_EVENT(xen_mmu_flush_tlb_one_user, |
372 | TP_PROTO(unsigned long addr), | 372 | TP_PROTO(unsigned long addr), |
373 | TP_ARGS(addr), | 373 | TP_ARGS(addr), |
374 | TP_STRUCT__entry( | 374 | TP_STRUCT__entry( |
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index b00b1896547e..a8cb69a26576 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c | |||
@@ -852,8 +852,14 @@ static int add_switch_table(struct objtool_file *file, struct symbol *func, | |||
852 | * This is a fairly uncommon pattern which is new for GCC 6. As of this | 852 | * This is a fairly uncommon pattern which is new for GCC 6. As of this |
853 | * writing, there are 11 occurrences of it in the allmodconfig kernel. | 853 | * writing, there are 11 occurrences of it in the allmodconfig kernel. |
854 | * | 854 | * |
855 | * As of GCC 7 there are quite a few more of these and the 'in between' code | ||
856 | * is significant. Esp. with KASAN enabled some of the code between the mov | ||
857 | * and jmpq uses .rodata itself, which can confuse things. | ||
858 | * | ||
855 | * TODO: Once we have DWARF CFI and smarter instruction decoding logic, | 859 | * TODO: Once we have DWARF CFI and smarter instruction decoding logic, |
856 | * ensure the same register is used in the mov and jump instructions. | 860 | * ensure the same register is used in the mov and jump instructions. |
861 | * | ||
862 | * NOTE: RETPOLINE made it harder still to decode dynamic jumps. | ||
857 | */ | 863 | */ |
858 | static struct rela *find_switch_table(struct objtool_file *file, | 864 | static struct rela *find_switch_table(struct objtool_file *file, |
859 | struct symbol *func, | 865 | struct symbol *func, |
@@ -875,12 +881,25 @@ static struct rela *find_switch_table(struct objtool_file *file, | |||
875 | text_rela->addend + 4); | 881 | text_rela->addend + 4); |
876 | if (!rodata_rela) | 882 | if (!rodata_rela) |
877 | return NULL; | 883 | return NULL; |
884 | |||
878 | file->ignore_unreachables = true; | 885 | file->ignore_unreachables = true; |
879 | return rodata_rela; | 886 | return rodata_rela; |
880 | } | 887 | } |
881 | 888 | ||
882 | /* case 3 */ | 889 | /* case 3 */ |
883 | func_for_each_insn_continue_reverse(file, func, insn) { | 890 | /* |
891 | * Backward search using the @first_jump_src links, these help avoid | ||
892 | * much of the 'in between' code. Which avoids us getting confused by | ||
893 | * it. | ||
894 | */ | ||
895 | for (insn = list_prev_entry(insn, list); | ||
896 | |||
897 | &insn->list != &file->insn_list && | ||
898 | insn->sec == func->sec && | ||
899 | insn->offset >= func->offset; | ||
900 | |||
901 | insn = insn->first_jump_src ?: list_prev_entry(insn, list)) { | ||
902 | |||
884 | if (insn->type == INSN_JUMP_DYNAMIC) | 903 | if (insn->type == INSN_JUMP_DYNAMIC) |
885 | break; | 904 | break; |
886 | 905 | ||
@@ -910,14 +929,32 @@ static struct rela *find_switch_table(struct objtool_file *file, | |||
910 | return NULL; | 929 | return NULL; |
911 | } | 930 | } |
912 | 931 | ||
932 | |||
913 | static int add_func_switch_tables(struct objtool_file *file, | 933 | static int add_func_switch_tables(struct objtool_file *file, |
914 | struct symbol *func) | 934 | struct symbol *func) |
915 | { | 935 | { |
916 | struct instruction *insn, *prev_jump = NULL; | 936 | struct instruction *insn, *last = NULL, *prev_jump = NULL; |
917 | struct rela *rela, *prev_rela = NULL; | 937 | struct rela *rela, *prev_rela = NULL; |
918 | int ret; | 938 | int ret; |
919 | 939 | ||
920 | func_for_each_insn(file, func, insn) { | 940 | func_for_each_insn(file, func, insn) { |
941 | if (!last) | ||
942 | last = insn; | ||
943 | |||
944 | /* | ||
945 | * Store back-pointers for unconditional forward jumps such | ||
946 | * that find_switch_table() can back-track using those and | ||
947 | * avoid some potentially confusing code. | ||
948 | */ | ||
949 | if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest && | ||
950 | insn->offset > last->offset && | ||
951 | insn->jump_dest->offset > insn->offset && | ||
952 | !insn->jump_dest->first_jump_src) { | ||
953 | |||
954 | insn->jump_dest->first_jump_src = insn; | ||
955 | last = insn->jump_dest; | ||
956 | } | ||
957 | |||
921 | if (insn->type != INSN_JUMP_DYNAMIC) | 958 | if (insn->type != INSN_JUMP_DYNAMIC) |
922 | continue; | 959 | continue; |
923 | 960 | ||
@@ -1899,13 +1936,19 @@ static bool ignore_unreachable_insn(struct instruction *insn) | |||
1899 | if (is_kasan_insn(insn) || is_ubsan_insn(insn)) | 1936 | if (is_kasan_insn(insn) || is_ubsan_insn(insn)) |
1900 | return true; | 1937 | return true; |
1901 | 1938 | ||
1902 | if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest) { | 1939 | if (insn->type == INSN_JUMP_UNCONDITIONAL) { |
1903 | insn = insn->jump_dest; | 1940 | if (insn->jump_dest && |
1904 | continue; | 1941 | insn->jump_dest->func == insn->func) { |
1942 | insn = insn->jump_dest; | ||
1943 | continue; | ||
1944 | } | ||
1945 | |||
1946 | break; | ||
1905 | } | 1947 | } |
1906 | 1948 | ||
1907 | if (insn->offset + insn->len >= insn->func->offset + insn->func->len) | 1949 | if (insn->offset + insn->len >= insn->func->offset + insn->func->len) |
1908 | break; | 1950 | break; |
1951 | |||
1909 | insn = list_next_entry(insn, list); | 1952 | insn = list_next_entry(insn, list); |
1910 | } | 1953 | } |
1911 | 1954 | ||
diff --git a/tools/objtool/check.h b/tools/objtool/check.h index dbadb304a410..23a1d065cae1 100644 --- a/tools/objtool/check.h +++ b/tools/objtool/check.h | |||
@@ -47,6 +47,7 @@ struct instruction { | |||
47 | bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts; | 47 | bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts; |
48 | struct symbol *call_dest; | 48 | struct symbol *call_dest; |
49 | struct instruction *jump_dest; | 49 | struct instruction *jump_dest; |
50 | struct instruction *first_jump_src; | ||
50 | struct list_head alts; | 51 | struct list_head alts; |
51 | struct symbol *func; | 52 | struct symbol *func; |
52 | struct stack_op stack_op; | 53 | struct stack_op stack_op; |
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 10ca46df1449..d744991c0f4f 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile | |||
@@ -5,16 +5,26 @@ include ../lib.mk | |||
5 | 5 | ||
6 | .PHONY: all all_32 all_64 warn_32bit_failure clean | 6 | .PHONY: all all_32 all_64 warn_32bit_failure clean |
7 | 7 | ||
8 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ | 8 | UNAME_M := $(shell uname -m) |
9 | check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test ioperm \ | 9 | CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32) |
10 | CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c) | ||
11 | |||
12 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \ | ||
13 | check_initial_reg_state sigreturn iopl mpx-mini-test ioperm \ | ||
10 | protection_keys test_vdso test_vsyscall | 14 | protection_keys test_vdso test_vsyscall |
11 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ | 15 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ |
12 | test_FCMOV test_FCOMI test_FISTTP \ | 16 | test_FCMOV test_FCOMI test_FISTTP \ |
13 | vdso_restorer | 17 | vdso_restorer |
14 | TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip 5lvl | 18 | TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip |
19 | # Some selftests require 32bit support enabled also on 64bit systems | ||
20 | TARGETS_C_32BIT_NEEDED := ldt_gdt ptrace_syscall | ||
15 | 21 | ||
16 | TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) | 22 | TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) $(TARGETS_C_32BIT_NEEDED) |
17 | TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY) | 23 | TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY) |
24 | ifeq ($(CAN_BUILD_I386)$(CAN_BUILD_X86_64),11) | ||
25 | TARGETS_C_64BIT_ALL += $(TARGETS_C_32BIT_NEEDED) | ||
26 | endif | ||
27 | |||
18 | BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) | 28 | BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) |
19 | BINARIES_64 := $(TARGETS_C_64BIT_ALL:%=%_64) | 29 | BINARIES_64 := $(TARGETS_C_64BIT_ALL:%=%_64) |
20 | 30 | ||
@@ -23,10 +33,6 @@ BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64)) | |||
23 | 33 | ||
24 | CFLAGS := -O2 -g -std=gnu99 -pthread -Wall -no-pie | 34 | CFLAGS := -O2 -g -std=gnu99 -pthread -Wall -no-pie |
25 | 35 | ||
26 | UNAME_M := $(shell uname -m) | ||
27 | CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32) | ||
28 | CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c) | ||
29 | |||
30 | define gen-target-rule-32 | 36 | define gen-target-rule-32 |
31 | $(1) $(1)_32: $(OUTPUT)/$(1)_32 | 37 | $(1) $(1)_32: $(OUTPUT)/$(1)_32 |
32 | .PHONY: $(1) $(1)_32 | 38 | .PHONY: $(1) $(1)_32 |
@@ -40,12 +46,14 @@ endef | |||
40 | ifeq ($(CAN_BUILD_I386),1) | 46 | ifeq ($(CAN_BUILD_I386),1) |
41 | all: all_32 | 47 | all: all_32 |
42 | TEST_PROGS += $(BINARIES_32) | 48 | TEST_PROGS += $(BINARIES_32) |
49 | EXTRA_CFLAGS += -DCAN_BUILD_32 | ||
43 | $(foreach t,$(TARGETS_C_32BIT_ALL),$(eval $(call gen-target-rule-32,$(t)))) | 50 | $(foreach t,$(TARGETS_C_32BIT_ALL),$(eval $(call gen-target-rule-32,$(t)))) |
44 | endif | 51 | endif |
45 | 52 | ||
46 | ifeq ($(CAN_BUILD_X86_64),1) | 53 | ifeq ($(CAN_BUILD_X86_64),1) |
47 | all: all_64 | 54 | all: all_64 |
48 | TEST_PROGS += $(BINARIES_64) | 55 | TEST_PROGS += $(BINARIES_64) |
56 | EXTRA_CFLAGS += -DCAN_BUILD_64 | ||
49 | $(foreach t,$(TARGETS_C_64BIT_ALL),$(eval $(call gen-target-rule-64,$(t)))) | 57 | $(foreach t,$(TARGETS_C_64BIT_ALL),$(eval $(call gen-target-rule-64,$(t)))) |
50 | endif | 58 | endif |
51 | 59 | ||
diff --git a/tools/testing/selftests/x86/mpx-mini-test.c b/tools/testing/selftests/x86/mpx-mini-test.c index ec0f6b45ce8b..9c0325e1ea68 100644 --- a/tools/testing/selftests/x86/mpx-mini-test.c +++ b/tools/testing/selftests/x86/mpx-mini-test.c | |||
@@ -315,11 +315,39 @@ static inline void *__si_bounds_upper(siginfo_t *si) | |||
315 | return si->si_upper; | 315 | return si->si_upper; |
316 | } | 316 | } |
317 | #else | 317 | #else |
318 | |||
319 | /* | ||
320 | * This deals with old version of _sigfault in some distros: | ||
321 | * | ||
322 | |||
323 | old _sigfault: | ||
324 | struct { | ||
325 | void *si_addr; | ||
326 | } _sigfault; | ||
327 | |||
328 | new _sigfault: | ||
329 | struct { | ||
330 | void __user *_addr; | ||
331 | int _trapno; | ||
332 | short _addr_lsb; | ||
333 | union { | ||
334 | struct { | ||
335 | void __user *_lower; | ||
336 | void __user *_upper; | ||
337 | } _addr_bnd; | ||
338 | __u32 _pkey; | ||
339 | }; | ||
340 | } _sigfault; | ||
341 | * | ||
342 | */ | ||
343 | |||
318 | static inline void **__si_bounds_hack(siginfo_t *si) | 344 | static inline void **__si_bounds_hack(siginfo_t *si) |
319 | { | 345 | { |
320 | void *sigfault = &si->_sifields._sigfault; | 346 | void *sigfault = &si->_sifields._sigfault; |
321 | void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault); | 347 | void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault); |
322 | void **__si_lower = end_sigfault; | 348 | int *trapno = (int*)end_sigfault; |
349 | /* skip _trapno and _addr_lsb */ | ||
350 | void **__si_lower = (void**)(trapno + 2); | ||
323 | 351 | ||
324 | return __si_lower; | 352 | return __si_lower; |
325 | } | 353 | } |
@@ -331,7 +359,7 @@ static inline void *__si_bounds_lower(siginfo_t *si) | |||
331 | 359 | ||
332 | static inline void *__si_bounds_upper(siginfo_t *si) | 360 | static inline void *__si_bounds_upper(siginfo_t *si) |
333 | { | 361 | { |
334 | return (*__si_bounds_hack(si)) + sizeof(void *); | 362 | return *(__si_bounds_hack(si) + 1); |
335 | } | 363 | } |
336 | #endif | 364 | #endif |
337 | 365 | ||
diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c index bc1b0735bb50..f15aa5a76fe3 100644 --- a/tools/testing/selftests/x86/protection_keys.c +++ b/tools/testing/selftests/x86/protection_keys.c | |||
@@ -393,34 +393,6 @@ pid_t fork_lazy_child(void) | |||
393 | return forkret; | 393 | return forkret; |
394 | } | 394 | } |
395 | 395 | ||
396 | void davecmp(void *_a, void *_b, int len) | ||
397 | { | ||
398 | int i; | ||
399 | unsigned long *a = _a; | ||
400 | unsigned long *b = _b; | ||
401 | |||
402 | for (i = 0; i < len / sizeof(*a); i++) { | ||
403 | if (a[i] == b[i]) | ||
404 | continue; | ||
405 | |||
406 | dprintf3("[%3d]: a: %016lx b: %016lx\n", i, a[i], b[i]); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | void dumpit(char *f) | ||
411 | { | ||
412 | int fd = open(f, O_RDONLY); | ||
413 | char buf[100]; | ||
414 | int nr_read; | ||
415 | |||
416 | dprintf2("maps fd: %d\n", fd); | ||
417 | do { | ||
418 | nr_read = read(fd, &buf[0], sizeof(buf)); | ||
419 | write(1, buf, nr_read); | ||
420 | } while (nr_read > 0); | ||
421 | close(fd); | ||
422 | } | ||
423 | |||
424 | #define PKEY_DISABLE_ACCESS 0x1 | 396 | #define PKEY_DISABLE_ACCESS 0x1 |
425 | #define PKEY_DISABLE_WRITE 0x2 | 397 | #define PKEY_DISABLE_WRITE 0x2 |
426 | 398 | ||
diff --git a/tools/testing/selftests/x86/single_step_syscall.c b/tools/testing/selftests/x86/single_step_syscall.c index a48da95c18fd..ddfdd635de16 100644 --- a/tools/testing/selftests/x86/single_step_syscall.c +++ b/tools/testing/selftests/x86/single_step_syscall.c | |||
@@ -119,7 +119,9 @@ static void check_result(void) | |||
119 | 119 | ||
120 | int main() | 120 | int main() |
121 | { | 121 | { |
122 | #ifdef CAN_BUILD_32 | ||
122 | int tmp; | 123 | int tmp; |
124 | #endif | ||
123 | 125 | ||
124 | sethandler(SIGTRAP, sigtrap, 0); | 126 | sethandler(SIGTRAP, sigtrap, 0); |
125 | 127 | ||
@@ -139,12 +141,13 @@ int main() | |||
139 | : : "c" (post_nop) : "r11"); | 141 | : : "c" (post_nop) : "r11"); |
140 | check_result(); | 142 | check_result(); |
141 | #endif | 143 | #endif |
142 | 144 | #ifdef CAN_BUILD_32 | |
143 | printf("[RUN]\tSet TF and check int80\n"); | 145 | printf("[RUN]\tSet TF and check int80\n"); |
144 | set_eflags(get_eflags() | X86_EFLAGS_TF); | 146 | set_eflags(get_eflags() | X86_EFLAGS_TF); |
145 | asm volatile ("int $0x80" : "=a" (tmp) : "a" (SYS_getpid) | 147 | asm volatile ("int $0x80" : "=a" (tmp) : "a" (SYS_getpid) |
146 | : INT80_CLOBBERS); | 148 | : INT80_CLOBBERS); |
147 | check_result(); | 149 | check_result(); |
150 | #endif | ||
148 | 151 | ||
149 | /* | 152 | /* |
150 | * This test is particularly interesting if fast syscalls use | 153 | * This test is particularly interesting if fast syscalls use |
diff --git a/tools/testing/selftests/x86/test_mremap_vdso.c b/tools/testing/selftests/x86/test_mremap_vdso.c index bf0d687c7db7..64f11c8d9b76 100644 --- a/tools/testing/selftests/x86/test_mremap_vdso.c +++ b/tools/testing/selftests/x86/test_mremap_vdso.c | |||
@@ -90,8 +90,12 @@ int main(int argc, char **argv, char **envp) | |||
90 | vdso_size += PAGE_SIZE; | 90 | vdso_size += PAGE_SIZE; |
91 | } | 91 | } |
92 | 92 | ||
93 | #ifdef __i386__ | ||
93 | /* Glibc is likely to explode now - exit with raw syscall */ | 94 | /* Glibc is likely to explode now - exit with raw syscall */ |
94 | asm volatile ("int $0x80" : : "a" (__NR_exit), "b" (!!ret)); | 95 | asm volatile ("int $0x80" : : "a" (__NR_exit), "b" (!!ret)); |
96 | #else /* __x86_64__ */ | ||
97 | syscall(SYS_exit, ret); | ||
98 | #endif | ||
95 | } else { | 99 | } else { |
96 | int status; | 100 | int status; |
97 | 101 | ||
diff --git a/tools/testing/selftests/x86/test_vdso.c b/tools/testing/selftests/x86/test_vdso.c index 29973cde06d3..235259011704 100644 --- a/tools/testing/selftests/x86/test_vdso.c +++ b/tools/testing/selftests/x86/test_vdso.c | |||
@@ -26,20 +26,59 @@ | |||
26 | # endif | 26 | # endif |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | /* max length of lines in /proc/self/maps - anything longer is skipped here */ | ||
30 | #define MAPS_LINE_LEN 128 | ||
31 | |||
29 | int nerrs = 0; | 32 | int nerrs = 0; |
30 | 33 | ||
34 | typedef long (*getcpu_t)(unsigned *, unsigned *, void *); | ||
35 | |||
36 | getcpu_t vgetcpu; | ||
37 | getcpu_t vdso_getcpu; | ||
38 | |||
39 | static void *vsyscall_getcpu(void) | ||
40 | { | ||
31 | #ifdef __x86_64__ | 41 | #ifdef __x86_64__ |
32 | # define VSYS(x) (x) | 42 | FILE *maps; |
43 | char line[MAPS_LINE_LEN]; | ||
44 | bool found = false; | ||
45 | |||
46 | maps = fopen("/proc/self/maps", "r"); | ||
47 | if (!maps) /* might still be present, but ignore it here, as we test vDSO not vsyscall */ | ||
48 | return NULL; | ||
49 | |||
50 | while (fgets(line, MAPS_LINE_LEN, maps)) { | ||
51 | char r, x; | ||
52 | void *start, *end; | ||
53 | char name[MAPS_LINE_LEN]; | ||
54 | |||
55 | /* sscanf() is safe here as strlen(name) >= strlen(line) */ | ||
56 | if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s", | ||
57 | &start, &end, &r, &x, name) != 5) | ||
58 | continue; | ||
59 | |||
60 | if (strcmp(name, "[vsyscall]")) | ||
61 | continue; | ||
62 | |||
63 | /* assume entries are OK, as we test vDSO here not vsyscall */ | ||
64 | found = true; | ||
65 | break; | ||
66 | } | ||
67 | |||
68 | fclose(maps); | ||
69 | |||
70 | if (!found) { | ||
71 | printf("Warning: failed to find vsyscall getcpu\n"); | ||
72 | return NULL; | ||
73 | } | ||
74 | return (void *) (0xffffffffff600800); | ||
33 | #else | 75 | #else |
34 | # define VSYS(x) 0 | 76 | return NULL; |
35 | #endif | 77 | #endif |
78 | } | ||
36 | 79 | ||
37 | typedef long (*getcpu_t)(unsigned *, unsigned *, void *); | ||
38 | |||
39 | const getcpu_t vgetcpu = (getcpu_t)VSYS(0xffffffffff600800); | ||
40 | getcpu_t vdso_getcpu; | ||
41 | 80 | ||
42 | void fill_function_pointers() | 81 | static void fill_function_pointers() |
43 | { | 82 | { |
44 | void *vdso = dlopen("linux-vdso.so.1", | 83 | void *vdso = dlopen("linux-vdso.so.1", |
45 | RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); | 84 | RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); |
@@ -54,6 +93,8 @@ void fill_function_pointers() | |||
54 | vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu"); | 93 | vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu"); |
55 | if (!vdso_getcpu) | 94 | if (!vdso_getcpu) |
56 | printf("Warning: failed to find getcpu in vDSO\n"); | 95 | printf("Warning: failed to find getcpu in vDSO\n"); |
96 | |||
97 | vgetcpu = (getcpu_t) vsyscall_getcpu(); | ||
57 | } | 98 | } |
58 | 99 | ||
59 | static long sys_getcpu(unsigned * cpu, unsigned * node, | 100 | static long sys_getcpu(unsigned * cpu, unsigned * node, |
diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c index 7a744fa7b786..be81621446f0 100644 --- a/tools/testing/selftests/x86/test_vsyscall.c +++ b/tools/testing/selftests/x86/test_vsyscall.c | |||
@@ -33,6 +33,9 @@ | |||
33 | # endif | 33 | # endif |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | /* max length of lines in /proc/self/maps - anything longer is skipped here */ | ||
37 | #define MAPS_LINE_LEN 128 | ||
38 | |||
36 | static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), | 39 | static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), |
37 | int flags) | 40 | int flags) |
38 | { | 41 | { |
@@ -98,7 +101,7 @@ static int init_vsys(void) | |||
98 | #ifdef __x86_64__ | 101 | #ifdef __x86_64__ |
99 | int nerrs = 0; | 102 | int nerrs = 0; |
100 | FILE *maps; | 103 | FILE *maps; |
101 | char line[128]; | 104 | char line[MAPS_LINE_LEN]; |
102 | bool found = false; | 105 | bool found = false; |
103 | 106 | ||
104 | maps = fopen("/proc/self/maps", "r"); | 107 | maps = fopen("/proc/self/maps", "r"); |
@@ -108,10 +111,12 @@ static int init_vsys(void) | |||
108 | return 0; | 111 | return 0; |
109 | } | 112 | } |
110 | 113 | ||
111 | while (fgets(line, sizeof(line), maps)) { | 114 | while (fgets(line, MAPS_LINE_LEN, maps)) { |
112 | char r, x; | 115 | char r, x; |
113 | void *start, *end; | 116 | void *start, *end; |
114 | char name[128]; | 117 | char name[MAPS_LINE_LEN]; |
118 | |||
119 | /* sscanf() is safe here as strlen(name) >= strlen(line) */ | ||
115 | if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s", | 120 | if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s", |
116 | &start, &end, &r, &x, name) != 5) | 121 | &start, &end, &r, &x, name) != 5) |
117 | continue; | 122 | continue; |