Contents of /trunk/kernel-alx/patches-4.14/0109-4.14.10-all-fixes.patch
Parent Directory | Revision Log
Revision 3238 -
(show annotations)
(download)
Fri Nov 9 12:14:58 2018 UTC (5 years, 10 months ago) by niro
File size: 300663 byte(s)
Fri Nov 9 12:14:58 2018 UTC (5 years, 10 months ago) by niro
File size: 300663 byte(s)
-added up to patches-4.14.79
1 | diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt |
2 | index 3448e675b462..51101708a03a 100644 |
3 | --- a/Documentation/x86/x86_64/mm.txt |
4 | +++ b/Documentation/x86/x86_64/mm.txt |
5 | @@ -1,6 +1,4 @@ |
6 | |
7 | -<previous description obsolete, deleted> |
8 | - |
9 | Virtual memory map with 4 level page tables: |
10 | |
11 | 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm |
12 | @@ -14,13 +12,15 @@ ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB) |
13 | ... unused hole ... |
14 | ffffec0000000000 - fffffbffffffffff (=44 bits) kasan shadow memory (16TB) |
15 | ... unused hole ... |
16 | +fffffe8000000000 - fffffeffffffffff (=39 bits) cpu_entry_area mapping |
17 | ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks |
18 | ... unused hole ... |
19 | ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space |
20 | ... unused hole ... |
21 | ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0 |
22 | -ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable) |
23 | -ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls |
24 | +ffffffffa0000000 - [fixmap start] (~1526 MB) module mapping space (variable) |
25 | +[fixmap start] - ffffffffff5fffff kernel-internal fixmap range |
26 | +ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI |
27 | ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole |
28 | |
29 | Virtual memory map with 5 level page tables: |
30 | @@ -36,19 +36,22 @@ ffd4000000000000 - ffd5ffffffffffff (=49 bits) virtual memory map (512TB) |
31 | ... unused hole ... |
32 | ffdf000000000000 - fffffc0000000000 (=53 bits) kasan shadow memory (8PB) |
33 | ... unused hole ... |
34 | +fffffe8000000000 - fffffeffffffffff (=39 bits) cpu_entry_area mapping |
35 | ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks |
36 | ... unused hole ... |
37 | ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space |
38 | ... unused hole ... |
39 | ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0 |
40 | -ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space |
41 | -ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls |
42 | +ffffffffa0000000 - [fixmap start] (~1526 MB) module mapping space |
43 | +[fixmap start] - ffffffffff5fffff kernel-internal fixmap range |
44 | +ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI |
45 | ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole |
46 | |
47 | Architecture defines a 64-bit virtual address. Implementations can support |
48 | less. Currently supported are 48- and 57-bit virtual addresses. Bits 63 |
49 | -through to the most-significant implemented bit are set to either all ones |
50 | -or all zero. This causes hole between user space and kernel addresses. |
51 | +through to the most-significant implemented bit are sign extended. |
52 | +This causes hole between user space and kernel addresses if you interpret them |
53 | +as unsigned. |
54 | |
55 | The direct mapping covers all memory in the system up to the highest |
56 | memory address (this means in some cases it can also include PCI memory |
57 | @@ -58,9 +61,6 @@ vmalloc space is lazily synchronized into the different PML4/PML5 pages of |
58 | the processes using the page fault handler, with init_top_pgt as |
59 | reference. |
60 | |
61 | -Current X86-64 implementations support up to 46 bits of address space (64 TB), |
62 | -which is our current limit. This expands into MBZ space in the page tables. |
63 | - |
64 | We map EFI runtime services in the 'efi_pgd' PGD in a 64Gb large virtual |
65 | memory window (this size is arbitrary, it can be raised later if needed). |
66 | The mappings are not part of any other kernel PGD and are only available |
67 | @@ -72,5 +72,3 @@ following fixmap section. |
68 | Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all |
69 | physical memory, vmalloc/ioremap space and virtual memory map are randomized. |
70 | Their order is preserved but their base will be offset early at boot time. |
71 | - |
72 | --Andi Kleen, Jul 2004 |
73 | diff --git a/Makefile b/Makefile |
74 | index ed2132c6d286..9edfb78836a9 100644 |
75 | --- a/Makefile |
76 | +++ b/Makefile |
77 | @@ -1,7 +1,7 @@ |
78 | # SPDX-License-Identifier: GPL-2.0 |
79 | VERSION = 4 |
80 | PATCHLEVEL = 14 |
81 | -SUBLEVEL = 9 |
82 | +SUBLEVEL = 10 |
83 | EXTRAVERSION = |
84 | NAME = Petit Gorille |
85 | |
86 | diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c |
87 | index f5154ed3da6c..2add22699764 100644 |
88 | --- a/arch/arm64/kvm/hyp/debug-sr.c |
89 | +++ b/arch/arm64/kvm/hyp/debug-sr.c |
90 | @@ -84,6 +84,9 @@ static void __hyp_text __debug_save_spe_nvhe(u64 *pmscr_el1) |
91 | { |
92 | u64 reg; |
93 | |
94 | + /* Clear pmscr in case of early return */ |
95 | + *pmscr_el1 = 0; |
96 | + |
97 | /* SPE present on this CPU? */ |
98 | if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1), |
99 | ID_AA64DFR0_PMSVER_SHIFT)) |
100 | diff --git a/arch/parisc/boot/compressed/misc.c b/arch/parisc/boot/compressed/misc.c |
101 | index 9345b44b86f0..f57118e1f6b4 100644 |
102 | --- a/arch/parisc/boot/compressed/misc.c |
103 | +++ b/arch/parisc/boot/compressed/misc.c |
104 | @@ -123,8 +123,8 @@ int puts(const char *s) |
105 | while ((nuline = strchr(s, '\n')) != NULL) { |
106 | if (nuline != s) |
107 | pdc_iodc_print(s, nuline - s); |
108 | - pdc_iodc_print("\r\n", 2); |
109 | - s = nuline + 1; |
110 | + pdc_iodc_print("\r\n", 2); |
111 | + s = nuline + 1; |
112 | } |
113 | if (*s != '\0') |
114 | pdc_iodc_print(s, strlen(s)); |
115 | diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S |
116 | index a4fd296c958e..f3cecf5117cf 100644 |
117 | --- a/arch/parisc/kernel/entry.S |
118 | +++ b/arch/parisc/kernel/entry.S |
119 | @@ -878,9 +878,6 @@ ENTRY_CFI(syscall_exit_rfi) |
120 | STREG %r19,PT_SR7(%r16) |
121 | |
122 | intr_return: |
123 | - /* NOTE: Need to enable interrupts incase we schedule. */ |
124 | - ssm PSW_SM_I, %r0 |
125 | - |
126 | /* check for reschedule */ |
127 | mfctl %cr30,%r1 |
128 | LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */ |
129 | @@ -907,6 +904,11 @@ intr_check_sig: |
130 | LDREG PT_IASQ1(%r16), %r20 |
131 | cmpib,COND(=),n 0,%r20,intr_restore /* backward */ |
132 | |
133 | + /* NOTE: We need to enable interrupts if we have to deliver |
134 | + * signals. We used to do this earlier but it caused kernel |
135 | + * stack overflows. */ |
136 | + ssm PSW_SM_I, %r0 |
137 | + |
138 | copy %r0, %r25 /* long in_syscall = 0 */ |
139 | #ifdef CONFIG_64BIT |
140 | ldo -16(%r30),%r29 /* Reference param save area */ |
141 | @@ -958,6 +960,10 @@ intr_do_resched: |
142 | cmpib,COND(=) 0, %r20, intr_do_preempt |
143 | nop |
144 | |
145 | + /* NOTE: We need to enable interrupts if we schedule. We used |
146 | + * to do this earlier but it caused kernel stack overflows. */ |
147 | + ssm PSW_SM_I, %r0 |
148 | + |
149 | #ifdef CONFIG_64BIT |
150 | ldo -16(%r30),%r29 /* Reference param save area */ |
151 | #endif |
152 | diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S |
153 | index e3a8e5e4d5de..8d072c44f300 100644 |
154 | --- a/arch/parisc/kernel/hpmc.S |
155 | +++ b/arch/parisc/kernel/hpmc.S |
156 | @@ -305,6 +305,7 @@ ENDPROC_CFI(os_hpmc) |
157 | |
158 | |
159 | __INITRODATA |
160 | + .align 4 |
161 | .export os_hpmc_size |
162 | os_hpmc_size: |
163 | .word .os_hpmc_end-.os_hpmc |
164 | diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h |
165 | index 492d8140a395..44fdf4786638 100644 |
166 | --- a/arch/powerpc/include/asm/mmu_context.h |
167 | +++ b/arch/powerpc/include/asm/mmu_context.h |
168 | @@ -114,9 +114,10 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, |
169 | #endif |
170 | } |
171 | |
172 | -static inline void arch_dup_mmap(struct mm_struct *oldmm, |
173 | - struct mm_struct *mm) |
174 | +static inline int arch_dup_mmap(struct mm_struct *oldmm, |
175 | + struct mm_struct *mm) |
176 | { |
177 | + return 0; |
178 | } |
179 | |
180 | static inline void arch_exit_mmap(struct mm_struct *mm) |
181 | diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c |
182 | index bf457843e032..0d750d274c4e 100644 |
183 | --- a/arch/powerpc/kvm/book3s_xive.c |
184 | +++ b/arch/powerpc/kvm/book3s_xive.c |
185 | @@ -725,7 +725,8 @@ u64 kvmppc_xive_get_icp(struct kvm_vcpu *vcpu) |
186 | |
187 | /* Return the per-cpu state for state saving/migration */ |
188 | return (u64)xc->cppr << KVM_REG_PPC_ICP_CPPR_SHIFT | |
189 | - (u64)xc->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT; |
190 | + (u64)xc->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT | |
191 | + (u64)0xff << KVM_REG_PPC_ICP_PPRI_SHIFT; |
192 | } |
193 | |
194 | int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval) |
195 | @@ -1558,7 +1559,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr) |
196 | |
197 | /* |
198 | * Restore P and Q. If the interrupt was pending, we |
199 | - * force both P and Q, which will trigger a resend. |
200 | + * force Q and !P, which will trigger a resend. |
201 | * |
202 | * That means that a guest that had both an interrupt |
203 | * pending (queued) and Q set will restore with only |
204 | @@ -1566,7 +1567,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr) |
205 | * is perfectly fine as coalescing interrupts that haven't |
206 | * been presented yet is always allowed. |
207 | */ |
208 | - if (val & KVM_XICS_PRESENTED || val & KVM_XICS_PENDING) |
209 | + if (val & KVM_XICS_PRESENTED && !(val & KVM_XICS_PENDING)) |
210 | state->old_p = true; |
211 | if (val & KVM_XICS_QUEUED || val & KVM_XICS_PENDING) |
212 | state->old_q = true; |
213 | diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c |
214 | index 9e3da168d54c..b4209a68b85d 100644 |
215 | --- a/arch/powerpc/perf/core-book3s.c |
216 | +++ b/arch/powerpc/perf/core-book3s.c |
217 | @@ -410,8 +410,12 @@ static __u64 power_pmu_bhrb_to(u64 addr) |
218 | int ret; |
219 | __u64 target; |
220 | |
221 | - if (is_kernel_addr(addr)) |
222 | - return branch_target((unsigned int *)addr); |
223 | + if (is_kernel_addr(addr)) { |
224 | + if (probe_kernel_read(&instr, (void *)addr, sizeof(instr))) |
225 | + return 0; |
226 | + |
227 | + return branch_target(&instr); |
228 | + } |
229 | |
230 | /* Userspace: need copy instruction here then translate it */ |
231 | pagefault_disable(); |
232 | diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h |
233 | index b668e351fd6c..fca34b2177e2 100644 |
234 | --- a/arch/um/include/asm/mmu_context.h |
235 | +++ b/arch/um/include/asm/mmu_context.h |
236 | @@ -15,9 +15,10 @@ extern void uml_setup_stubs(struct mm_struct *mm); |
237 | /* |
238 | * Needed since we do not use the asm-generic/mm_hooks.h: |
239 | */ |
240 | -static inline void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) |
241 | +static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) |
242 | { |
243 | uml_setup_stubs(mm); |
244 | + return 0; |
245 | } |
246 | extern void arch_exit_mmap(struct mm_struct *mm); |
247 | static inline void arch_unmap(struct mm_struct *mm, |
248 | diff --git a/arch/unicore32/include/asm/mmu_context.h b/arch/unicore32/include/asm/mmu_context.h |
249 | index 59b06b48f27d..5c205a9cb5a6 100644 |
250 | --- a/arch/unicore32/include/asm/mmu_context.h |
251 | +++ b/arch/unicore32/include/asm/mmu_context.h |
252 | @@ -81,9 +81,10 @@ do { \ |
253 | } \ |
254 | } while (0) |
255 | |
256 | -static inline void arch_dup_mmap(struct mm_struct *oldmm, |
257 | - struct mm_struct *mm) |
258 | +static inline int arch_dup_mmap(struct mm_struct *oldmm, |
259 | + struct mm_struct *mm) |
260 | { |
261 | + return 0; |
262 | } |
263 | |
264 | static inline void arch_unmap(struct mm_struct *mm, |
265 | diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig |
266 | index 48646160eb83..592c974d4558 100644 |
267 | --- a/arch/x86/Kconfig |
268 | +++ b/arch/x86/Kconfig |
269 | @@ -925,7 +925,8 @@ config MAXSMP |
270 | config NR_CPUS |
271 | int "Maximum number of CPUs" if SMP && !MAXSMP |
272 | range 2 8 if SMP && X86_32 && !X86_BIGSMP |
273 | - range 2 512 if SMP && !MAXSMP && !CPUMASK_OFFSTACK |
274 | + range 2 64 if SMP && X86_32 && X86_BIGSMP |
275 | + range 2 512 if SMP && !MAXSMP && !CPUMASK_OFFSTACK && X86_64 |
276 | range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64 |
277 | default "1" if !SMP |
278 | default "8192" if MAXSMP |
279 | diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S |
280 | index bd8b57a5c874..ace8f321a5a1 100644 |
281 | --- a/arch/x86/entry/entry_32.S |
282 | +++ b/arch/x86/entry/entry_32.S |
283 | @@ -942,9 +942,9 @@ ENTRY(debug) |
284 | |
285 | /* Are we currently on the SYSENTER stack? */ |
286 | movl PER_CPU_VAR(cpu_entry_area), %ecx |
287 | - addl $CPU_ENTRY_AREA_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx |
288 | - subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */ |
289 | - cmpl $SIZEOF_SYSENTER_stack, %ecx |
290 | + addl $CPU_ENTRY_AREA_entry_stack + SIZEOF_entry_stack, %ecx |
291 | + subl %eax, %ecx /* ecx = (end of entry_stack) - esp */ |
292 | + cmpl $SIZEOF_entry_stack, %ecx |
293 | jb .Ldebug_from_sysenter_stack |
294 | |
295 | TRACE_IRQS_OFF |
296 | @@ -986,9 +986,9 @@ ENTRY(nmi) |
297 | |
298 | /* Are we currently on the SYSENTER stack? */ |
299 | movl PER_CPU_VAR(cpu_entry_area), %ecx |
300 | - addl $CPU_ENTRY_AREA_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx |
301 | - subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */ |
302 | - cmpl $SIZEOF_SYSENTER_stack, %ecx |
303 | + addl $CPU_ENTRY_AREA_entry_stack + SIZEOF_entry_stack, %ecx |
304 | + subl %eax, %ecx /* ecx = (end of entry_stack) - esp */ |
305 | + cmpl $SIZEOF_entry_stack, %ecx |
306 | jb .Lnmi_from_sysenter_stack |
307 | |
308 | /* Not on SYSENTER stack. */ |
309 | diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S |
310 | index 6abe3fcaece9..22c891c3b78d 100644 |
311 | --- a/arch/x86/entry/entry_64.S |
312 | +++ b/arch/x86/entry/entry_64.S |
313 | @@ -154,8 +154,8 @@ END(native_usergs_sysret64) |
314 | _entry_trampoline - CPU_ENTRY_AREA_entry_trampoline(%rip) |
315 | |
316 | /* The top word of the SYSENTER stack is hot and is usable as scratch space. */ |
317 | -#define RSP_SCRATCH CPU_ENTRY_AREA_SYSENTER_stack + \ |
318 | - SIZEOF_SYSENTER_stack - 8 + CPU_ENTRY_AREA |
319 | +#define RSP_SCRATCH CPU_ENTRY_AREA_entry_stack + \ |
320 | + SIZEOF_entry_stack - 8 + CPU_ENTRY_AREA |
321 | |
322 | ENTRY(entry_SYSCALL_64_trampoline) |
323 | UNWIND_HINT_EMPTY |
324 | diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c |
325 | index f279ba2643dc..1faf40f2dda9 100644 |
326 | --- a/arch/x86/entry/vsyscall/vsyscall_64.c |
327 | +++ b/arch/x86/entry/vsyscall/vsyscall_64.c |
328 | @@ -37,6 +37,7 @@ |
329 | #include <asm/unistd.h> |
330 | #include <asm/fixmap.h> |
331 | #include <asm/traps.h> |
332 | +#include <asm/paravirt.h> |
333 | |
334 | #define CREATE_TRACE_POINTS |
335 | #include "vsyscall_trace.h" |
336 | @@ -138,6 +139,10 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) |
337 | |
338 | WARN_ON_ONCE(address != regs->ip); |
339 | |
340 | + /* This should be unreachable in NATIVE mode. */ |
341 | + if (WARN_ON(vsyscall_mode == NATIVE)) |
342 | + return false; |
343 | + |
344 | if (vsyscall_mode == NONE) { |
345 | warn_bad_vsyscall(KERN_INFO, regs, |
346 | "vsyscall attempted with vsyscall=none"); |
347 | @@ -329,16 +334,47 @@ int in_gate_area_no_mm(unsigned long addr) |
348 | return vsyscall_mode != NONE && (addr & PAGE_MASK) == VSYSCALL_ADDR; |
349 | } |
350 | |
351 | +/* |
352 | + * The VSYSCALL page is the only user-accessible page in the kernel address |
353 | + * range. Normally, the kernel page tables can have _PAGE_USER clear, but |
354 | + * the tables covering VSYSCALL_ADDR need _PAGE_USER set if vsyscalls |
355 | + * are enabled. |
356 | + * |
357 | + * Some day we may create a "minimal" vsyscall mode in which we emulate |
358 | + * vsyscalls but leave the page not present. If so, we skip calling |
359 | + * this. |
360 | + */ |
361 | +static void __init set_vsyscall_pgtable_user_bits(void) |
362 | +{ |
363 | + pgd_t *pgd; |
364 | + p4d_t *p4d; |
365 | + pud_t *pud; |
366 | + pmd_t *pmd; |
367 | + |
368 | + pgd = pgd_offset_k(VSYSCALL_ADDR); |
369 | + set_pgd(pgd, __pgd(pgd_val(*pgd) | _PAGE_USER)); |
370 | + p4d = p4d_offset(pgd, VSYSCALL_ADDR); |
371 | +#if CONFIG_PGTABLE_LEVELS >= 5 |
372 | + p4d->p4d |= _PAGE_USER; |
373 | +#endif |
374 | + pud = pud_offset(p4d, VSYSCALL_ADDR); |
375 | + set_pud(pud, __pud(pud_val(*pud) | _PAGE_USER)); |
376 | + pmd = pmd_offset(pud, VSYSCALL_ADDR); |
377 | + set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_USER)); |
378 | +} |
379 | + |
380 | void __init map_vsyscall(void) |
381 | { |
382 | extern char __vsyscall_page; |
383 | unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page); |
384 | |
385 | - if (vsyscall_mode != NONE) |
386 | + if (vsyscall_mode != NONE) { |
387 | __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall, |
388 | vsyscall_mode == NATIVE |
389 | ? PAGE_KERNEL_VSYSCALL |
390 | : PAGE_KERNEL_VVAR); |
391 | + set_vsyscall_pgtable_user_bits(); |
392 | + } |
393 | |
394 | BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) != |
395 | (unsigned long)VSYSCALL_ADDR); |
396 | diff --git a/arch/x86/include/asm/cpu_entry_area.h b/arch/x86/include/asm/cpu_entry_area.h |
397 | new file mode 100644 |
398 | index 000000000000..2fbc69a0916e |
399 | --- /dev/null |
400 | +++ b/arch/x86/include/asm/cpu_entry_area.h |
401 | @@ -0,0 +1,68 @@ |
402 | +// SPDX-License-Identifier: GPL-2.0 |
403 | + |
404 | +#ifndef _ASM_X86_CPU_ENTRY_AREA_H |
405 | +#define _ASM_X86_CPU_ENTRY_AREA_H |
406 | + |
407 | +#include <linux/percpu-defs.h> |
408 | +#include <asm/processor.h> |
409 | + |
410 | +/* |
411 | + * cpu_entry_area is a percpu region that contains things needed by the CPU |
412 | + * and early entry/exit code. Real types aren't used for all fields here |
413 | + * to avoid circular header dependencies. |
414 | + * |
415 | + * Every field is a virtual alias of some other allocated backing store. |
416 | + * There is no direct allocation of a struct cpu_entry_area. |
417 | + */ |
418 | +struct cpu_entry_area { |
419 | + char gdt[PAGE_SIZE]; |
420 | + |
421 | + /* |
422 | + * The GDT is just below entry_stack and thus serves (on x86_64) as |
423 | + * a a read-only guard page. |
424 | + */ |
425 | + struct entry_stack_page entry_stack_page; |
426 | + |
427 | + /* |
428 | + * On x86_64, the TSS is mapped RO. On x86_32, it's mapped RW because |
429 | + * we need task switches to work, and task switches write to the TSS. |
430 | + */ |
431 | + struct tss_struct tss; |
432 | + |
433 | + char entry_trampoline[PAGE_SIZE]; |
434 | + |
435 | +#ifdef CONFIG_X86_64 |
436 | + /* |
437 | + * Exception stacks used for IST entries. |
438 | + * |
439 | + * In the future, this should have a separate slot for each stack |
440 | + * with guard pages between them. |
441 | + */ |
442 | + char exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]; |
443 | +#endif |
444 | +}; |
445 | + |
446 | +#define CPU_ENTRY_AREA_SIZE (sizeof(struct cpu_entry_area)) |
447 | +#define CPU_ENTRY_AREA_TOT_SIZE (CPU_ENTRY_AREA_SIZE * NR_CPUS) |
448 | + |
449 | +DECLARE_PER_CPU(struct cpu_entry_area *, cpu_entry_area); |
450 | + |
451 | +extern void setup_cpu_entry_areas(void); |
452 | +extern void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags); |
453 | + |
454 | +#define CPU_ENTRY_AREA_RO_IDT CPU_ENTRY_AREA_BASE |
455 | +#define CPU_ENTRY_AREA_PER_CPU (CPU_ENTRY_AREA_RO_IDT + PAGE_SIZE) |
456 | + |
457 | +#define CPU_ENTRY_AREA_RO_IDT_VADDR ((void *)CPU_ENTRY_AREA_RO_IDT) |
458 | + |
459 | +#define CPU_ENTRY_AREA_MAP_SIZE \ |
460 | + (CPU_ENTRY_AREA_PER_CPU + CPU_ENTRY_AREA_TOT_SIZE - CPU_ENTRY_AREA_BASE) |
461 | + |
462 | +extern struct cpu_entry_area *get_cpu_entry_area(int cpu); |
463 | + |
464 | +static inline struct entry_stack *cpu_entry_stack(int cpu) |
465 | +{ |
466 | + return &get_cpu_entry_area(cpu)->entry_stack_page.stack; |
467 | +} |
468 | + |
469 | +#endif |
470 | diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h |
471 | index 2ace1f90d138..bc359dd2f7f6 100644 |
472 | --- a/arch/x86/include/asm/desc.h |
473 | +++ b/arch/x86/include/asm/desc.h |
474 | @@ -7,6 +7,7 @@ |
475 | #include <asm/mmu.h> |
476 | #include <asm/fixmap.h> |
477 | #include <asm/irq_vectors.h> |
478 | +#include <asm/cpu_entry_area.h> |
479 | |
480 | #include <linux/smp.h> |
481 | #include <linux/percpu.h> |
482 | diff --git a/arch/x86/include/asm/espfix.h b/arch/x86/include/asm/espfix.h |
483 | index 0211029076ea..6777480d8a42 100644 |
484 | --- a/arch/x86/include/asm/espfix.h |
485 | +++ b/arch/x86/include/asm/espfix.h |
486 | @@ -2,7 +2,7 @@ |
487 | #ifndef _ASM_X86_ESPFIX_H |
488 | #define _ASM_X86_ESPFIX_H |
489 | |
490 | -#ifdef CONFIG_X86_64 |
491 | +#ifdef CONFIG_X86_ESPFIX64 |
492 | |
493 | #include <asm/percpu.h> |
494 | |
495 | @@ -11,7 +11,8 @@ DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr); |
496 | |
497 | extern void init_espfix_bsp(void); |
498 | extern void init_espfix_ap(int cpu); |
499 | - |
500 | -#endif /* CONFIG_X86_64 */ |
501 | +#else |
502 | +static inline void init_espfix_ap(int cpu) { } |
503 | +#endif |
504 | |
505 | #endif /* _ASM_X86_ESPFIX_H */ |
506 | diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h |
507 | index 94fc4fa14127..64c4a30e0d39 100644 |
508 | --- a/arch/x86/include/asm/fixmap.h |
509 | +++ b/arch/x86/include/asm/fixmap.h |
510 | @@ -44,46 +44,6 @@ extern unsigned long __FIXADDR_TOP; |
511 | PAGE_SIZE) |
512 | #endif |
513 | |
514 | -/* |
515 | - * cpu_entry_area is a percpu region in the fixmap that contains things |
516 | - * needed by the CPU and early entry/exit code. Real types aren't used |
517 | - * for all fields here to avoid circular header dependencies. |
518 | - * |
519 | - * Every field is a virtual alias of some other allocated backing store. |
520 | - * There is no direct allocation of a struct cpu_entry_area. |
521 | - */ |
522 | -struct cpu_entry_area { |
523 | - char gdt[PAGE_SIZE]; |
524 | - |
525 | - /* |
526 | - * The GDT is just below SYSENTER_stack and thus serves (on x86_64) as |
527 | - * a a read-only guard page. |
528 | - */ |
529 | - struct SYSENTER_stack_page SYSENTER_stack_page; |
530 | - |
531 | - /* |
532 | - * On x86_64, the TSS is mapped RO. On x86_32, it's mapped RW because |
533 | - * we need task switches to work, and task switches write to the TSS. |
534 | - */ |
535 | - struct tss_struct tss; |
536 | - |
537 | - char entry_trampoline[PAGE_SIZE]; |
538 | - |
539 | -#ifdef CONFIG_X86_64 |
540 | - /* |
541 | - * Exception stacks used for IST entries. |
542 | - * |
543 | - * In the future, this should have a separate slot for each stack |
544 | - * with guard pages between them. |
545 | - */ |
546 | - char exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]; |
547 | -#endif |
548 | -}; |
549 | - |
550 | -#define CPU_ENTRY_AREA_PAGES (sizeof(struct cpu_entry_area) / PAGE_SIZE) |
551 | - |
552 | -extern void setup_cpu_entry_areas(void); |
553 | - |
554 | /* |
555 | * Here we define all the compile-time 'special' virtual |
556 | * addresses. The point is to have a constant address at |
557 | @@ -123,7 +83,6 @@ enum fixed_addresses { |
558 | FIX_IO_APIC_BASE_0, |
559 | FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1, |
560 | #endif |
561 | - FIX_RO_IDT, /* Virtual mapping for read-only IDT */ |
562 | #ifdef CONFIG_X86_32 |
563 | FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ |
564 | FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, |
565 | @@ -139,9 +98,6 @@ enum fixed_addresses { |
566 | #ifdef CONFIG_X86_INTEL_MID |
567 | FIX_LNW_VRTC, |
568 | #endif |
569 | - /* Fixmap entries to remap the GDTs, one per processor. */ |
570 | - FIX_CPU_ENTRY_AREA_TOP, |
571 | - FIX_CPU_ENTRY_AREA_BOTTOM = FIX_CPU_ENTRY_AREA_TOP + (CPU_ENTRY_AREA_PAGES * NR_CPUS) - 1, |
572 | |
573 | #ifdef CONFIG_ACPI_APEI_GHES |
574 | /* Used for GHES mapping from assorted contexts */ |
575 | @@ -182,7 +138,7 @@ enum fixed_addresses { |
576 | extern void reserve_top_address(unsigned long reserve); |
577 | |
578 | #define FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) |
579 | -#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) |
580 | +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) |
581 | |
582 | extern int fixmaps_set; |
583 | |
584 | @@ -230,30 +186,5 @@ void __init *early_memremap_decrypted_wp(resource_size_t phys_addr, |
585 | void __early_set_fixmap(enum fixed_addresses idx, |
586 | phys_addr_t phys, pgprot_t flags); |
587 | |
588 | -static inline unsigned int __get_cpu_entry_area_page_index(int cpu, int page) |
589 | -{ |
590 | - BUILD_BUG_ON(sizeof(struct cpu_entry_area) % PAGE_SIZE != 0); |
591 | - |
592 | - return FIX_CPU_ENTRY_AREA_BOTTOM - cpu*CPU_ENTRY_AREA_PAGES - page; |
593 | -} |
594 | - |
595 | -#define __get_cpu_entry_area_offset_index(cpu, offset) ({ \ |
596 | - BUILD_BUG_ON(offset % PAGE_SIZE != 0); \ |
597 | - __get_cpu_entry_area_page_index(cpu, offset / PAGE_SIZE); \ |
598 | - }) |
599 | - |
600 | -#define get_cpu_entry_area_index(cpu, field) \ |
601 | - __get_cpu_entry_area_offset_index((cpu), offsetof(struct cpu_entry_area, field)) |
602 | - |
603 | -static inline struct cpu_entry_area *get_cpu_entry_area(int cpu) |
604 | -{ |
605 | - return (struct cpu_entry_area *)__fix_to_virt(__get_cpu_entry_area_page_index(cpu, 0)); |
606 | -} |
607 | - |
608 | -static inline struct SYSENTER_stack *cpu_SYSENTER_stack(int cpu) |
609 | -{ |
610 | - return &get_cpu_entry_area(cpu)->SYSENTER_stack_page.stack; |
611 | -} |
612 | - |
613 | #endif /* !__ASSEMBLY__ */ |
614 | #endif /* _ASM_X86_FIXMAP_H */ |
615 | diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h |
616 | index 02aff0867211..1c78580e58be 100644 |
617 | --- a/arch/x86/include/asm/inat.h |
618 | +++ b/arch/x86/include/asm/inat.h |
619 | @@ -97,6 +97,16 @@ |
620 | #define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM) |
621 | #define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS) |
622 | |
623 | +/* Identifiers for segment registers */ |
624 | +#define INAT_SEG_REG_IGNORE 0 |
625 | +#define INAT_SEG_REG_DEFAULT 1 |
626 | +#define INAT_SEG_REG_CS 2 |
627 | +#define INAT_SEG_REG_SS 3 |
628 | +#define INAT_SEG_REG_DS 4 |
629 | +#define INAT_SEG_REG_ES 5 |
630 | +#define INAT_SEG_REG_FS 6 |
631 | +#define INAT_SEG_REG_GS 7 |
632 | + |
633 | /* Attribute search APIs */ |
634 | extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode); |
635 | extern int inat_get_last_prefix_id(insn_byte_t last_pfx); |
636 | diff --git a/arch/x86/include/asm/invpcid.h b/arch/x86/include/asm/invpcid.h |
637 | new file mode 100644 |
638 | index 000000000000..989cfa86de85 |
639 | --- /dev/null |
640 | +++ b/arch/x86/include/asm/invpcid.h |
641 | @@ -0,0 +1,53 @@ |
642 | +/* SPDX-License-Identifier: GPL-2.0 */ |
643 | +#ifndef _ASM_X86_INVPCID |
644 | +#define _ASM_X86_INVPCID |
645 | + |
646 | +static inline void __invpcid(unsigned long pcid, unsigned long addr, |
647 | + unsigned long type) |
648 | +{ |
649 | + struct { u64 d[2]; } desc = { { pcid, addr } }; |
650 | + |
651 | + /* |
652 | + * The memory clobber is because the whole point is to invalidate |
653 | + * stale TLB entries and, especially if we're flushing global |
654 | + * mappings, we don't want the compiler to reorder any subsequent |
655 | + * memory accesses before the TLB flush. |
656 | + * |
657 | + * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and |
658 | + * invpcid (%rcx), %rax in long mode. |
659 | + */ |
660 | + asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01" |
661 | + : : "m" (desc), "a" (type), "c" (&desc) : "memory"); |
662 | +} |
663 | + |
664 | +#define INVPCID_TYPE_INDIV_ADDR 0 |
665 | +#define INVPCID_TYPE_SINGLE_CTXT 1 |
666 | +#define INVPCID_TYPE_ALL_INCL_GLOBAL 2 |
667 | +#define INVPCID_TYPE_ALL_NON_GLOBAL 3 |
668 | + |
669 | +/* Flush all mappings for a given pcid and addr, not including globals. */ |
670 | +static inline void invpcid_flush_one(unsigned long pcid, |
671 | + unsigned long addr) |
672 | +{ |
673 | + __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); |
674 | +} |
675 | + |
676 | +/* Flush all mappings for a given PCID, not including globals. */ |
677 | +static inline void invpcid_flush_single_context(unsigned long pcid) |
678 | +{ |
679 | + __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); |
680 | +} |
681 | + |
682 | +/* Flush all mappings, including globals, for all PCIDs. */ |
683 | +static inline void invpcid_flush_all(void) |
684 | +{ |
685 | + __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); |
686 | +} |
687 | + |
688 | +/* Flush all mappings for all PCIDs except globals. */ |
689 | +static inline void invpcid_flush_all_nonglobals(void) |
690 | +{ |
691 | + __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); |
692 | +} |
693 | + |
694 | +#endif /* _ASM_X86_INVPCID */ |
695 | diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h |
696 | index 9ea26f167497..5ff3e8af2c20 100644 |
697 | --- a/arch/x86/include/asm/mmu.h |
698 | +++ b/arch/x86/include/asm/mmu.h |
699 | @@ -3,6 +3,7 @@ |
700 | #define _ASM_X86_MMU_H |
701 | |
702 | #include <linux/spinlock.h> |
703 | +#include <linux/rwsem.h> |
704 | #include <linux/mutex.h> |
705 | #include <linux/atomic.h> |
706 | |
707 | @@ -27,7 +28,8 @@ typedef struct { |
708 | atomic64_t tlb_gen; |
709 | |
710 | #ifdef CONFIG_MODIFY_LDT_SYSCALL |
711 | - struct ldt_struct *ldt; |
712 | + struct rw_semaphore ldt_usr_sem; |
713 | + struct ldt_struct *ldt; |
714 | #endif |
715 | |
716 | #ifdef CONFIG_X86_64 |
717 | diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h |
718 | index 6d16d15d09a0..5ede7cae1d67 100644 |
719 | --- a/arch/x86/include/asm/mmu_context.h |
720 | +++ b/arch/x86/include/asm/mmu_context.h |
721 | @@ -57,11 +57,17 @@ struct ldt_struct { |
722 | /* |
723 | * Used for LDT copy/destruction. |
724 | */ |
725 | -int init_new_context_ldt(struct task_struct *tsk, struct mm_struct *mm); |
726 | +static inline void init_new_context_ldt(struct mm_struct *mm) |
727 | +{ |
728 | + mm->context.ldt = NULL; |
729 | + init_rwsem(&mm->context.ldt_usr_sem); |
730 | +} |
731 | +int ldt_dup_context(struct mm_struct *oldmm, struct mm_struct *mm); |
732 | void destroy_context_ldt(struct mm_struct *mm); |
733 | #else /* CONFIG_MODIFY_LDT_SYSCALL */ |
734 | -static inline int init_new_context_ldt(struct task_struct *tsk, |
735 | - struct mm_struct *mm) |
736 | +static inline void init_new_context_ldt(struct mm_struct *mm) { } |
737 | +static inline int ldt_dup_context(struct mm_struct *oldmm, |
738 | + struct mm_struct *mm) |
739 | { |
740 | return 0; |
741 | } |
742 | @@ -132,18 +138,21 @@ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk); |
743 | static inline int init_new_context(struct task_struct *tsk, |
744 | struct mm_struct *mm) |
745 | { |
746 | + mutex_init(&mm->context.lock); |
747 | + |
748 | mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id); |
749 | atomic64_set(&mm->context.tlb_gen, 0); |
750 | |
751 | - #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS |
752 | +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS |
753 | if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { |
754 | /* pkey 0 is the default and always allocated */ |
755 | mm->context.pkey_allocation_map = 0x1; |
756 | /* -1 means unallocated or invalid */ |
757 | mm->context.execute_only_pkey = -1; |
758 | } |
759 | - #endif |
760 | - return init_new_context_ldt(tsk, mm); |
761 | +#endif |
762 | + init_new_context_ldt(mm); |
763 | + return 0; |
764 | } |
765 | static inline void destroy_context(struct mm_struct *mm) |
766 | { |
767 | @@ -176,10 +185,10 @@ do { \ |
768 | } while (0) |
769 | #endif |
770 | |
771 | -static inline void arch_dup_mmap(struct mm_struct *oldmm, |
772 | - struct mm_struct *mm) |
773 | +static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) |
774 | { |
775 | paravirt_arch_dup_mmap(oldmm, mm); |
776 | + return ldt_dup_context(oldmm, mm); |
777 | } |
778 | |
779 | static inline void arch_exit_mmap(struct mm_struct *mm) |
780 | @@ -281,33 +290,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, |
781 | return __pkru_allows_pkey(vma_pkey(vma), write); |
782 | } |
783 | |
784 | -/* |
785 | - * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID |
786 | - * bits. This serves two purposes. It prevents a nasty situation in |
787 | - * which PCID-unaware code saves CR3, loads some other value (with PCID |
788 | - * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if |
789 | - * the saved ASID was nonzero. It also means that any bugs involving |
790 | - * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger |
791 | - * deterministically. |
792 | - */ |
793 | - |
794 | -static inline unsigned long build_cr3(struct mm_struct *mm, u16 asid) |
795 | -{ |
796 | - if (static_cpu_has(X86_FEATURE_PCID)) { |
797 | - VM_WARN_ON_ONCE(asid > 4094); |
798 | - return __sme_pa(mm->pgd) | (asid + 1); |
799 | - } else { |
800 | - VM_WARN_ON_ONCE(asid != 0); |
801 | - return __sme_pa(mm->pgd); |
802 | - } |
803 | -} |
804 | - |
805 | -static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid) |
806 | -{ |
807 | - VM_WARN_ON_ONCE(asid > 4094); |
808 | - return __sme_pa(mm->pgd) | (asid + 1) | CR3_NOFLUSH; |
809 | -} |
810 | - |
811 | /* |
812 | * This can be used from process context to figure out what the value of |
813 | * CR3 is without needing to do a (slow) __read_cr3(). |
814 | @@ -317,7 +299,7 @@ static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid) |
815 | */ |
816 | static inline unsigned long __get_current_cr3_fast(void) |
817 | { |
818 | - unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm), |
819 | + unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm)->pgd, |
820 | this_cpu_read(cpu_tlbstate.loaded_mm_asid)); |
821 | |
822 | /* For now, be very restrictive about when this can be called. */ |
823 | diff --git a/arch/x86/include/asm/pgtable_32_types.h b/arch/x86/include/asm/pgtable_32_types.h |
824 | index f2ca9b28fd68..ce245b0cdfca 100644 |
825 | --- a/arch/x86/include/asm/pgtable_32_types.h |
826 | +++ b/arch/x86/include/asm/pgtable_32_types.h |
827 | @@ -38,13 +38,22 @@ extern bool __vmalloc_start_set; /* set once high_memory is set */ |
828 | #define LAST_PKMAP 1024 |
829 | #endif |
830 | |
831 | -#define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE * (LAST_PKMAP + 1)) \ |
832 | - & PMD_MASK) |
833 | +/* |
834 | + * Define this here and validate with BUILD_BUG_ON() in pgtable_32.c |
835 | + * to avoid include recursion hell |
836 | + */ |
837 | +#define CPU_ENTRY_AREA_PAGES (NR_CPUS * 40) |
838 | + |
839 | +#define CPU_ENTRY_AREA_BASE \ |
840 | + ((FIXADDR_START - PAGE_SIZE * (CPU_ENTRY_AREA_PAGES + 1)) & PMD_MASK) |
841 | + |
842 | +#define PKMAP_BASE \ |
843 | + ((CPU_ENTRY_AREA_BASE - PAGE_SIZE) & PMD_MASK) |
844 | |
845 | #ifdef CONFIG_HIGHMEM |
846 | # define VMALLOC_END (PKMAP_BASE - 2 * PAGE_SIZE) |
847 | #else |
848 | -# define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE) |
849 | +# define VMALLOC_END (CPU_ENTRY_AREA_BASE - 2 * PAGE_SIZE) |
850 | #endif |
851 | |
852 | #define MODULES_VADDR VMALLOC_START |
853 | diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h |
854 | index 6d5f45dcd4a1..3d27831bc58d 100644 |
855 | --- a/arch/x86/include/asm/pgtable_64_types.h |
856 | +++ b/arch/x86/include/asm/pgtable_64_types.h |
857 | @@ -76,32 +76,41 @@ typedef struct { pteval_t pte; } pte_t; |
858 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) |
859 | |
860 | /* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */ |
861 | -#define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL) |
862 | +#define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL) |
863 | + |
864 | #ifdef CONFIG_X86_5LEVEL |
865 | -#define VMALLOC_SIZE_TB _AC(16384, UL) |
866 | -#define __VMALLOC_BASE _AC(0xff92000000000000, UL) |
867 | -#define __VMEMMAP_BASE _AC(0xffd4000000000000, UL) |
868 | +# define VMALLOC_SIZE_TB _AC(16384, UL) |
869 | +# define __VMALLOC_BASE _AC(0xff92000000000000, UL) |
870 | +# define __VMEMMAP_BASE _AC(0xffd4000000000000, UL) |
871 | #else |
872 | -#define VMALLOC_SIZE_TB _AC(32, UL) |
873 | -#define __VMALLOC_BASE _AC(0xffffc90000000000, UL) |
874 | -#define __VMEMMAP_BASE _AC(0xffffea0000000000, UL) |
875 | +# define VMALLOC_SIZE_TB _AC(32, UL) |
876 | +# define __VMALLOC_BASE _AC(0xffffc90000000000, UL) |
877 | +# define __VMEMMAP_BASE _AC(0xffffea0000000000, UL) |
878 | #endif |
879 | + |
880 | #ifdef CONFIG_RANDOMIZE_MEMORY |
881 | -#define VMALLOC_START vmalloc_base |
882 | -#define VMEMMAP_START vmemmap_base |
883 | +# define VMALLOC_START vmalloc_base |
884 | +# define VMEMMAP_START vmemmap_base |
885 | #else |
886 | -#define VMALLOC_START __VMALLOC_BASE |
887 | -#define VMEMMAP_START __VMEMMAP_BASE |
888 | +# define VMALLOC_START __VMALLOC_BASE |
889 | +# define VMEMMAP_START __VMEMMAP_BASE |
890 | #endif /* CONFIG_RANDOMIZE_MEMORY */ |
891 | -#define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL)) |
892 | -#define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE) |
893 | + |
894 | +#define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL)) |
895 | + |
896 | +#define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE) |
897 | /* The module sections ends with the start of the fixmap */ |
898 | -#define MODULES_END __fix_to_virt(__end_of_fixed_addresses + 1) |
899 | -#define MODULES_LEN (MODULES_END - MODULES_VADDR) |
900 | -#define ESPFIX_PGD_ENTRY _AC(-2, UL) |
901 | -#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << P4D_SHIFT) |
902 | -#define EFI_VA_START ( -4 * (_AC(1, UL) << 30)) |
903 | -#define EFI_VA_END (-68 * (_AC(1, UL) << 30)) |
904 | +#define MODULES_END __fix_to_virt(__end_of_fixed_addresses + 1) |
905 | +#define MODULES_LEN (MODULES_END - MODULES_VADDR) |
906 | + |
907 | +#define ESPFIX_PGD_ENTRY _AC(-2, UL) |
908 | +#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << P4D_SHIFT) |
909 | + |
910 | +#define CPU_ENTRY_AREA_PGD _AC(-3, UL) |
911 | +#define CPU_ENTRY_AREA_BASE (CPU_ENTRY_AREA_PGD << P4D_SHIFT) |
912 | + |
913 | +#define EFI_VA_START ( -4 * (_AC(1, UL) << 30)) |
914 | +#define EFI_VA_END (-68 * (_AC(1, UL) << 30)) |
915 | |
916 | #define EARLY_DYNAMIC_PAGE_TABLES 64 |
917 | |
918 | diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h |
919 | index da943411d3d8..9e482d8b0b97 100644 |
920 | --- a/arch/x86/include/asm/processor.h |
921 | +++ b/arch/x86/include/asm/processor.h |
922 | @@ -336,12 +336,12 @@ struct x86_hw_tss { |
923 | #define IO_BITMAP_OFFSET (offsetof(struct tss_struct, io_bitmap) - offsetof(struct tss_struct, x86_tss)) |
924 | #define INVALID_IO_BITMAP_OFFSET 0x8000 |
925 | |
926 | -struct SYSENTER_stack { |
927 | +struct entry_stack { |
928 | unsigned long words[64]; |
929 | }; |
930 | |
931 | -struct SYSENTER_stack_page { |
932 | - struct SYSENTER_stack stack; |
933 | +struct entry_stack_page { |
934 | + struct entry_stack stack; |
935 | } __aligned(PAGE_SIZE); |
936 | |
937 | struct tss_struct { |
938 | diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h |
939 | index f8062bfd43a0..f73706878772 100644 |
940 | --- a/arch/x86/include/asm/stacktrace.h |
941 | +++ b/arch/x86/include/asm/stacktrace.h |
942 | @@ -16,7 +16,7 @@ enum stack_type { |
943 | STACK_TYPE_TASK, |
944 | STACK_TYPE_IRQ, |
945 | STACK_TYPE_SOFTIRQ, |
946 | - STACK_TYPE_SYSENTER, |
947 | + STACK_TYPE_ENTRY, |
948 | STACK_TYPE_EXCEPTION, |
949 | STACK_TYPE_EXCEPTION_LAST = STACK_TYPE_EXCEPTION + N_EXCEPTION_STACKS-1, |
950 | }; |
951 | @@ -29,7 +29,7 @@ struct stack_info { |
952 | bool in_task_stack(unsigned long *stack, struct task_struct *task, |
953 | struct stack_info *info); |
954 | |
955 | -bool in_sysenter_stack(unsigned long *stack, struct stack_info *info); |
956 | +bool in_entry_stack(unsigned long *stack, struct stack_info *info); |
957 | |
958 | int get_stack_info(unsigned long *stack, struct task_struct *task, |
959 | struct stack_info *info, unsigned long *visit_mask); |
960 | diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h |
961 | index 509046cfa5ce..171b429f43a2 100644 |
962 | --- a/arch/x86/include/asm/tlbflush.h |
963 | +++ b/arch/x86/include/asm/tlbflush.h |
964 | @@ -9,70 +9,66 @@ |
965 | #include <asm/cpufeature.h> |
966 | #include <asm/special_insns.h> |
967 | #include <asm/smp.h> |
968 | +#include <asm/invpcid.h> |
969 | |
970 | -static inline void __invpcid(unsigned long pcid, unsigned long addr, |
971 | - unsigned long type) |
972 | +static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) |
973 | { |
974 | - struct { u64 d[2]; } desc = { { pcid, addr } }; |
975 | - |
976 | /* |
977 | - * The memory clobber is because the whole point is to invalidate |
978 | - * stale TLB entries and, especially if we're flushing global |
979 | - * mappings, we don't want the compiler to reorder any subsequent |
980 | - * memory accesses before the TLB flush. |
981 | - * |
982 | - * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and |
983 | - * invpcid (%rcx), %rax in long mode. |
984 | + * Bump the generation count. This also serves as a full barrier |
985 | + * that synchronizes with switch_mm(): callers are required to order |
986 | + * their read of mm_cpumask after their writes to the paging |
987 | + * structures. |
988 | */ |
989 | - asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01" |
990 | - : : "m" (desc), "a" (type), "c" (&desc) : "memory"); |
991 | + return atomic64_inc_return(&mm->context.tlb_gen); |
992 | } |
993 | |
994 | -#define INVPCID_TYPE_INDIV_ADDR 0 |
995 | -#define INVPCID_TYPE_SINGLE_CTXT 1 |
996 | -#define INVPCID_TYPE_ALL_INCL_GLOBAL 2 |
997 | -#define INVPCID_TYPE_ALL_NON_GLOBAL 3 |
998 | - |
999 | -/* Flush all mappings for a given pcid and addr, not including globals. */ |
1000 | -static inline void invpcid_flush_one(unsigned long pcid, |
1001 | - unsigned long addr) |
1002 | -{ |
1003 | - __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); |
1004 | -} |
1005 | +/* There are 12 bits of space for ASIDS in CR3 */ |
1006 | +#define CR3_HW_ASID_BITS 12 |
1007 | +/* |
1008 | + * When enabled, PAGE_TABLE_ISOLATION consumes a single bit for |
1009 | + * user/kernel switches |
1010 | + */ |
1011 | +#define PTI_CONSUMED_ASID_BITS 0 |
1012 | |
1013 | -/* Flush all mappings for a given PCID, not including globals. */ |
1014 | -static inline void invpcid_flush_single_context(unsigned long pcid) |
1015 | -{ |
1016 | - __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); |
1017 | -} |
1018 | +#define CR3_AVAIL_ASID_BITS (CR3_HW_ASID_BITS - PTI_CONSUMED_ASID_BITS) |
1019 | +/* |
1020 | + * ASIDs are zero-based: 0->MAX_AVAIL_ASID are valid. -1 below to account |
1021 | + * for them being zero-based. Another -1 is because ASID 0 is reserved for |
1022 | + * use by non-PCID-aware users. |
1023 | + */ |
1024 | +#define MAX_ASID_AVAILABLE ((1 << CR3_AVAIL_ASID_BITS) - 2) |
1025 | |
1026 | -/* Flush all mappings, including globals, for all PCIDs. */ |
1027 | -static inline void invpcid_flush_all(void) |
1028 | +static inline u16 kern_pcid(u16 asid) |
1029 | { |
1030 | - __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); |
1031 | + VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE); |
1032 | + /* |
1033 | + * If PCID is on, ASID-aware code paths put the ASID+1 into the |
1034 | + * PCID bits. This serves two purposes. It prevents a nasty |
1035 | + * situation in which PCID-unaware code saves CR3, loads some other |
1036 | + * value (with PCID == 0), and then restores CR3, thus corrupting |
1037 | + * the TLB for ASID 0 if the saved ASID was nonzero. It also means |
1038 | + * that any bugs involving loading a PCID-enabled CR3 with |
1039 | + * CR4.PCIDE off will trigger deterministically. |
1040 | + */ |
1041 | + return asid + 1; |
1042 | } |
1043 | |
1044 | -/* Flush all mappings for all PCIDs except globals. */ |
1045 | -static inline void invpcid_flush_all_nonglobals(void) |
1046 | +struct pgd_t; |
1047 | +static inline unsigned long build_cr3(pgd_t *pgd, u16 asid) |
1048 | { |
1049 | - __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); |
1050 | + if (static_cpu_has(X86_FEATURE_PCID)) { |
1051 | + return __sme_pa(pgd) | kern_pcid(asid); |
1052 | + } else { |
1053 | + VM_WARN_ON_ONCE(asid != 0); |
1054 | + return __sme_pa(pgd); |
1055 | + } |
1056 | } |
1057 | |
1058 | -static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) |
1059 | +static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid) |
1060 | { |
1061 | - u64 new_tlb_gen; |
1062 | - |
1063 | - /* |
1064 | - * Bump the generation count. This also serves as a full barrier |
1065 | - * that synchronizes with switch_mm(): callers are required to order |
1066 | - * their read of mm_cpumask after their writes to the paging |
1067 | - * structures. |
1068 | - */ |
1069 | - smp_mb__before_atomic(); |
1070 | - new_tlb_gen = atomic64_inc_return(&mm->context.tlb_gen); |
1071 | - smp_mb__after_atomic(); |
1072 | - |
1073 | - return new_tlb_gen; |
1074 | + VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE); |
1075 | + VM_WARN_ON_ONCE(!this_cpu_has(X86_FEATURE_PCID)); |
1076 | + return __sme_pa(pgd) | kern_pcid(asid) | CR3_NOFLUSH; |
1077 | } |
1078 | |
1079 | #ifdef CONFIG_PARAVIRT |
1080 | @@ -234,6 +230,9 @@ static inline void cr4_set_bits_and_update_boot(unsigned long mask) |
1081 | |
1082 | extern void initialize_tlbstate_and_flush(void); |
1083 | |
1084 | +/* |
1085 | + * flush the entire current user mapping |
1086 | + */ |
1087 | static inline void __native_flush_tlb(void) |
1088 | { |
1089 | /* |
1090 | @@ -246,20 +245,12 @@ static inline void __native_flush_tlb(void) |
1091 | preempt_enable(); |
1092 | } |
1093 | |
1094 | -static inline void __native_flush_tlb_global_irq_disabled(void) |
1095 | -{ |
1096 | - unsigned long cr4; |
1097 | - |
1098 | - cr4 = this_cpu_read(cpu_tlbstate.cr4); |
1099 | - /* clear PGE */ |
1100 | - native_write_cr4(cr4 & ~X86_CR4_PGE); |
1101 | - /* write old PGE again and flush TLBs */ |
1102 | - native_write_cr4(cr4); |
1103 | -} |
1104 | - |
1105 | +/* |
1106 | + * flush everything |
1107 | + */ |
1108 | static inline void __native_flush_tlb_global(void) |
1109 | { |
1110 | - unsigned long flags; |
1111 | + unsigned long cr4, flags; |
1112 | |
1113 | if (static_cpu_has(X86_FEATURE_INVPCID)) { |
1114 | /* |
1115 | @@ -277,22 +268,36 @@ static inline void __native_flush_tlb_global(void) |
1116 | */ |
1117 | raw_local_irq_save(flags); |
1118 | |
1119 | - __native_flush_tlb_global_irq_disabled(); |
1120 | + cr4 = this_cpu_read(cpu_tlbstate.cr4); |
1121 | + /* toggle PGE */ |
1122 | + native_write_cr4(cr4 ^ X86_CR4_PGE); |
1123 | + /* write old PGE again and flush TLBs */ |
1124 | + native_write_cr4(cr4); |
1125 | |
1126 | raw_local_irq_restore(flags); |
1127 | } |
1128 | |
1129 | +/* |
1130 | + * flush one page in the user mapping |
1131 | + */ |
1132 | static inline void __native_flush_tlb_single(unsigned long addr) |
1133 | { |
1134 | asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); |
1135 | } |
1136 | |
1137 | +/* |
1138 | + * flush everything |
1139 | + */ |
1140 | static inline void __flush_tlb_all(void) |
1141 | { |
1142 | - if (boot_cpu_has(X86_FEATURE_PGE)) |
1143 | + if (boot_cpu_has(X86_FEATURE_PGE)) { |
1144 | __flush_tlb_global(); |
1145 | - else |
1146 | + } else { |
1147 | + /* |
1148 | + * !PGE -> !PCID (setup_pcid()), thus every flush is total. |
1149 | + */ |
1150 | __flush_tlb(); |
1151 | + } |
1152 | |
1153 | /* |
1154 | * Note: if we somehow had PCID but not PGE, then this wouldn't work -- |
1155 | @@ -303,6 +308,9 @@ static inline void __flush_tlb_all(void) |
1156 | */ |
1157 | } |
1158 | |
1159 | +/* |
1160 | + * flush one page in the kernel mapping |
1161 | + */ |
1162 | static inline void __flush_tlb_one(unsigned long addr) |
1163 | { |
1164 | count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE); |
1165 | diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c |
1166 | index cd360a5e0dca..676b7cf4b62b 100644 |
1167 | --- a/arch/x86/kernel/asm-offsets.c |
1168 | +++ b/arch/x86/kernel/asm-offsets.c |
1169 | @@ -97,6 +97,6 @@ void common(void) { |
1170 | /* Layout info for cpu_entry_area */ |
1171 | OFFSET(CPU_ENTRY_AREA_tss, cpu_entry_area, tss); |
1172 | OFFSET(CPU_ENTRY_AREA_entry_trampoline, cpu_entry_area, entry_trampoline); |
1173 | - OFFSET(CPU_ENTRY_AREA_SYSENTER_stack, cpu_entry_area, SYSENTER_stack_page); |
1174 | - DEFINE(SIZEOF_SYSENTER_stack, sizeof(struct SYSENTER_stack)); |
1175 | + OFFSET(CPU_ENTRY_AREA_entry_stack, cpu_entry_area, entry_stack_page); |
1176 | + DEFINE(SIZEOF_entry_stack, sizeof(struct entry_stack)); |
1177 | } |
1178 | diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c |
1179 | index 7d20d9c0b3d6..fa1261eefa16 100644 |
1180 | --- a/arch/x86/kernel/asm-offsets_32.c |
1181 | +++ b/arch/x86/kernel/asm-offsets_32.c |
1182 | @@ -48,7 +48,7 @@ void foo(void) |
1183 | |
1184 | /* Offset from the sysenter stack to tss.sp0 */ |
1185 | DEFINE(TSS_sysenter_sp0, offsetof(struct cpu_entry_area, tss.x86_tss.sp0) - |
1186 | - offsetofend(struct cpu_entry_area, SYSENTER_stack_page.stack)); |
1187 | + offsetofend(struct cpu_entry_area, entry_stack_page.stack)); |
1188 | |
1189 | #ifdef CONFIG_CC_STACKPROTECTOR |
1190 | BLANK(); |
1191 | diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c |
1192 | index 034900623adf..8ddcfa4d4165 100644 |
1193 | --- a/arch/x86/kernel/cpu/common.c |
1194 | +++ b/arch/x86/kernel/cpu/common.c |
1195 | @@ -482,102 +482,8 @@ static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { |
1196 | [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, |
1197 | [DEBUG_STACK - 1] = DEBUG_STKSZ |
1198 | }; |
1199 | - |
1200 | -static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks |
1201 | - [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]); |
1202 | -#endif |
1203 | - |
1204 | -static DEFINE_PER_CPU_PAGE_ALIGNED(struct SYSENTER_stack_page, |
1205 | - SYSENTER_stack_storage); |
1206 | - |
1207 | -static void __init |
1208 | -set_percpu_fixmap_pages(int idx, void *ptr, int pages, pgprot_t prot) |
1209 | -{ |
1210 | - for ( ; pages; pages--, idx--, ptr += PAGE_SIZE) |
1211 | - __set_fixmap(idx, per_cpu_ptr_to_phys(ptr), prot); |
1212 | -} |
1213 | - |
1214 | -/* Setup the fixmap mappings only once per-processor */ |
1215 | -static void __init setup_cpu_entry_area(int cpu) |
1216 | -{ |
1217 | -#ifdef CONFIG_X86_64 |
1218 | - extern char _entry_trampoline[]; |
1219 | - |
1220 | - /* On 64-bit systems, we use a read-only fixmap GDT and TSS. */ |
1221 | - pgprot_t gdt_prot = PAGE_KERNEL_RO; |
1222 | - pgprot_t tss_prot = PAGE_KERNEL_RO; |
1223 | -#else |
1224 | - /* |
1225 | - * On native 32-bit systems, the GDT cannot be read-only because |
1226 | - * our double fault handler uses a task gate, and entering through |
1227 | - * a task gate needs to change an available TSS to busy. If the |
1228 | - * GDT is read-only, that will triple fault. The TSS cannot be |
1229 | - * read-only because the CPU writes to it on task switches. |
1230 | - * |
1231 | - * On Xen PV, the GDT must be read-only because the hypervisor |
1232 | - * requires it. |
1233 | - */ |
1234 | - pgprot_t gdt_prot = boot_cpu_has(X86_FEATURE_XENPV) ? |
1235 | - PAGE_KERNEL_RO : PAGE_KERNEL; |
1236 | - pgprot_t tss_prot = PAGE_KERNEL; |
1237 | -#endif |
1238 | - |
1239 | - __set_fixmap(get_cpu_entry_area_index(cpu, gdt), get_cpu_gdt_paddr(cpu), gdt_prot); |
1240 | - set_percpu_fixmap_pages(get_cpu_entry_area_index(cpu, SYSENTER_stack_page), |
1241 | - per_cpu_ptr(&SYSENTER_stack_storage, cpu), 1, |
1242 | - PAGE_KERNEL); |
1243 | - |
1244 | - /* |
1245 | - * The Intel SDM says (Volume 3, 7.2.1): |
1246 | - * |
1247 | - * Avoid placing a page boundary in the part of the TSS that the |
1248 | - * processor reads during a task switch (the first 104 bytes). The |
1249 | - * processor may not correctly perform address translations if a |
1250 | - * boundary occurs in this area. During a task switch, the processor |
1251 | - * reads and writes into the first 104 bytes of each TSS (using |
1252 | - * contiguous physical addresses beginning with the physical address |
1253 | - * of the first byte of the TSS). So, after TSS access begins, if |
1254 | - * part of the 104 bytes is not physically contiguous, the processor |
1255 | - * will access incorrect information without generating a page-fault |
1256 | - * exception. |
1257 | - * |
1258 | - * There are also a lot of errata involving the TSS spanning a page |
1259 | - * boundary. Assert that we're not doing that. |
1260 | - */ |
1261 | - BUILD_BUG_ON((offsetof(struct tss_struct, x86_tss) ^ |
1262 | - offsetofend(struct tss_struct, x86_tss)) & PAGE_MASK); |
1263 | - BUILD_BUG_ON(sizeof(struct tss_struct) % PAGE_SIZE != 0); |
1264 | - set_percpu_fixmap_pages(get_cpu_entry_area_index(cpu, tss), |
1265 | - &per_cpu(cpu_tss_rw, cpu), |
1266 | - sizeof(struct tss_struct) / PAGE_SIZE, |
1267 | - tss_prot); |
1268 | - |
1269 | -#ifdef CONFIG_X86_32 |
1270 | - per_cpu(cpu_entry_area, cpu) = get_cpu_entry_area(cpu); |
1271 | #endif |
1272 | |
1273 | -#ifdef CONFIG_X86_64 |
1274 | - BUILD_BUG_ON(sizeof(exception_stacks) % PAGE_SIZE != 0); |
1275 | - BUILD_BUG_ON(sizeof(exception_stacks) != |
1276 | - sizeof(((struct cpu_entry_area *)0)->exception_stacks)); |
1277 | - set_percpu_fixmap_pages(get_cpu_entry_area_index(cpu, exception_stacks), |
1278 | - &per_cpu(exception_stacks, cpu), |
1279 | - sizeof(exception_stacks) / PAGE_SIZE, |
1280 | - PAGE_KERNEL); |
1281 | - |
1282 | - __set_fixmap(get_cpu_entry_area_index(cpu, entry_trampoline), |
1283 | - __pa_symbol(_entry_trampoline), PAGE_KERNEL_RX); |
1284 | -#endif |
1285 | -} |
1286 | - |
1287 | -void __init setup_cpu_entry_areas(void) |
1288 | -{ |
1289 | - unsigned int cpu; |
1290 | - |
1291 | - for_each_possible_cpu(cpu) |
1292 | - setup_cpu_entry_area(cpu); |
1293 | -} |
1294 | - |
1295 | /* Load the original GDT from the per-cpu structure */ |
1296 | void load_direct_gdt(int cpu) |
1297 | { |
1298 | @@ -1323,7 +1229,7 @@ void enable_sep_cpu(void) |
1299 | |
1300 | tss->x86_tss.ss1 = __KERNEL_CS; |
1301 | wrmsr(MSR_IA32_SYSENTER_CS, tss->x86_tss.ss1, 0); |
1302 | - wrmsr(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_SYSENTER_stack(cpu) + 1), 0); |
1303 | + wrmsr(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_entry_stack(cpu) + 1), 0); |
1304 | wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long)entry_SYSENTER_32, 0); |
1305 | |
1306 | put_cpu(); |
1307 | @@ -1440,7 +1346,7 @@ void syscall_init(void) |
1308 | * AMD doesn't allow SYSENTER in long mode (either 32- or 64-bit). |
1309 | */ |
1310 | wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); |
1311 | - wrmsrl_safe(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_SYSENTER_stack(cpu) + 1)); |
1312 | + wrmsrl_safe(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_entry_stack(cpu) + 1)); |
1313 | wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)entry_SYSENTER_compat); |
1314 | #else |
1315 | wrmsrl(MSR_CSTAR, (unsigned long)ignore_sysret); |
1316 | @@ -1655,7 +1561,7 @@ void cpu_init(void) |
1317 | */ |
1318 | set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss); |
1319 | load_TR_desc(); |
1320 | - load_sp0((unsigned long)(cpu_SYSENTER_stack(cpu) + 1)); |
1321 | + load_sp0((unsigned long)(cpu_entry_stack(cpu) + 1)); |
1322 | |
1323 | load_mm_ldt(&init_mm); |
1324 | |
1325 | diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c |
1326 | index 7dbcb7adf797..8ccdca6d3f9e 100644 |
1327 | --- a/arch/x86/kernel/cpu/microcode/intel.c |
1328 | +++ b/arch/x86/kernel/cpu/microcode/intel.c |
1329 | @@ -565,15 +565,6 @@ static void print_ucode(struct ucode_cpu_info *uci) |
1330 | } |
1331 | #else |
1332 | |
1333 | -/* |
1334 | - * Flush global tlb. We only do this in x86_64 where paging has been enabled |
1335 | - * already and PGE should be enabled as well. |
1336 | - */ |
1337 | -static inline void flush_tlb_early(void) |
1338 | -{ |
1339 | - __native_flush_tlb_global_irq_disabled(); |
1340 | -} |
1341 | - |
1342 | static inline void print_ucode(struct ucode_cpu_info *uci) |
1343 | { |
1344 | struct microcode_intel *mc; |
1345 | @@ -602,10 +593,6 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) |
1346 | if (rev != mc->hdr.rev) |
1347 | return -1; |
1348 | |
1349 | -#ifdef CONFIG_X86_64 |
1350 | - /* Flush global tlb. This is precaution. */ |
1351 | - flush_tlb_early(); |
1352 | -#endif |
1353 | uci->cpu_sig.rev = rev; |
1354 | |
1355 | if (early) |
1356 | diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c |
1357 | index bbd6d986e2d0..36b17e0febe8 100644 |
1358 | --- a/arch/x86/kernel/dumpstack.c |
1359 | +++ b/arch/x86/kernel/dumpstack.c |
1360 | @@ -18,6 +18,7 @@ |
1361 | #include <linux/nmi.h> |
1362 | #include <linux/sysfs.h> |
1363 | |
1364 | +#include <asm/cpu_entry_area.h> |
1365 | #include <asm/stacktrace.h> |
1366 | #include <asm/unwind.h> |
1367 | |
1368 | @@ -43,9 +44,9 @@ bool in_task_stack(unsigned long *stack, struct task_struct *task, |
1369 | return true; |
1370 | } |
1371 | |
1372 | -bool in_sysenter_stack(unsigned long *stack, struct stack_info *info) |
1373 | +bool in_entry_stack(unsigned long *stack, struct stack_info *info) |
1374 | { |
1375 | - struct SYSENTER_stack *ss = cpu_SYSENTER_stack(smp_processor_id()); |
1376 | + struct entry_stack *ss = cpu_entry_stack(smp_processor_id()); |
1377 | |
1378 | void *begin = ss; |
1379 | void *end = ss + 1; |
1380 | @@ -53,7 +54,7 @@ bool in_sysenter_stack(unsigned long *stack, struct stack_info *info) |
1381 | if ((void *)stack < begin || (void *)stack >= end) |
1382 | return false; |
1383 | |
1384 | - info->type = STACK_TYPE_SYSENTER; |
1385 | + info->type = STACK_TYPE_ENTRY; |
1386 | info->begin = begin; |
1387 | info->end = end; |
1388 | info->next_sp = NULL; |
1389 | @@ -111,13 +112,13 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, |
1390 | * - task stack |
1391 | * - interrupt stack |
1392 | * - HW exception stacks (double fault, nmi, debug, mce) |
1393 | - * - SYSENTER stack |
1394 | + * - entry stack |
1395 | * |
1396 | * x86-32 can have up to four stacks: |
1397 | * - task stack |
1398 | * - softirq stack |
1399 | * - hardirq stack |
1400 | - * - SYSENTER stack |
1401 | + * - entry stack |
1402 | */ |
1403 | for (regs = NULL; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { |
1404 | const char *stack_name; |
1405 | diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c |
1406 | index 5ff13a6b3680..04170f63e3a1 100644 |
1407 | --- a/arch/x86/kernel/dumpstack_32.c |
1408 | +++ b/arch/x86/kernel/dumpstack_32.c |
1409 | @@ -26,8 +26,8 @@ const char *stack_type_name(enum stack_type type) |
1410 | if (type == STACK_TYPE_SOFTIRQ) |
1411 | return "SOFTIRQ"; |
1412 | |
1413 | - if (type == STACK_TYPE_SYSENTER) |
1414 | - return "SYSENTER"; |
1415 | + if (type == STACK_TYPE_ENTRY) |
1416 | + return "ENTRY_TRAMPOLINE"; |
1417 | |
1418 | return NULL; |
1419 | } |
1420 | @@ -96,7 +96,7 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, |
1421 | if (task != current) |
1422 | goto unknown; |
1423 | |
1424 | - if (in_sysenter_stack(stack, info)) |
1425 | + if (in_entry_stack(stack, info)) |
1426 | goto recursion_check; |
1427 | |
1428 | if (in_hardirq_stack(stack, info)) |
1429 | diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c |
1430 | index abc828f8c297..563e28d14f2c 100644 |
1431 | --- a/arch/x86/kernel/dumpstack_64.c |
1432 | +++ b/arch/x86/kernel/dumpstack_64.c |
1433 | @@ -37,8 +37,14 @@ const char *stack_type_name(enum stack_type type) |
1434 | if (type == STACK_TYPE_IRQ) |
1435 | return "IRQ"; |
1436 | |
1437 | - if (type == STACK_TYPE_SYSENTER) |
1438 | - return "SYSENTER"; |
1439 | + if (type == STACK_TYPE_ENTRY) { |
1440 | + /* |
1441 | + * On 64-bit, we have a generic entry stack that we |
1442 | + * use for all the kernel entry points, including |
1443 | + * SYSENTER. |
1444 | + */ |
1445 | + return "ENTRY_TRAMPOLINE"; |
1446 | + } |
1447 | |
1448 | if (type >= STACK_TYPE_EXCEPTION && type <= STACK_TYPE_EXCEPTION_LAST) |
1449 | return exception_stack_names[type - STACK_TYPE_EXCEPTION]; |
1450 | @@ -118,7 +124,7 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, |
1451 | if (in_irq_stack(stack, info)) |
1452 | goto recursion_check; |
1453 | |
1454 | - if (in_sysenter_stack(stack, info)) |
1455 | + if (in_entry_stack(stack, info)) |
1456 | goto recursion_check; |
1457 | |
1458 | goto unknown; |
1459 | diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c |
1460 | index 1c1eae961340..a6b5d62f45a7 100644 |
1461 | --- a/arch/x86/kernel/ldt.c |
1462 | +++ b/arch/x86/kernel/ldt.c |
1463 | @@ -5,6 +5,11 @@ |
1464 | * Copyright (C) 2002 Andi Kleen |
1465 | * |
1466 | * This handles calls from both 32bit and 64bit mode. |
1467 | + * |
1468 | + * Lock order: |
1469 | + * contex.ldt_usr_sem |
1470 | + * mmap_sem |
1471 | + * context.lock |
1472 | */ |
1473 | |
1474 | #include <linux/errno.h> |
1475 | @@ -42,7 +47,7 @@ static void refresh_ldt_segments(void) |
1476 | #endif |
1477 | } |
1478 | |
1479 | -/* context.lock is held for us, so we don't need any locking. */ |
1480 | +/* context.lock is held by the task which issued the smp function call */ |
1481 | static void flush_ldt(void *__mm) |
1482 | { |
1483 | struct mm_struct *mm = __mm; |
1484 | @@ -99,15 +104,17 @@ static void finalize_ldt_struct(struct ldt_struct *ldt) |
1485 | paravirt_alloc_ldt(ldt->entries, ldt->nr_entries); |
1486 | } |
1487 | |
1488 | -/* context.lock is held */ |
1489 | -static void install_ldt(struct mm_struct *current_mm, |
1490 | - struct ldt_struct *ldt) |
1491 | +static void install_ldt(struct mm_struct *mm, struct ldt_struct *ldt) |
1492 | { |
1493 | + mutex_lock(&mm->context.lock); |
1494 | + |
1495 | /* Synchronizes with READ_ONCE in load_mm_ldt. */ |
1496 | - smp_store_release(¤t_mm->context.ldt, ldt); |
1497 | + smp_store_release(&mm->context.ldt, ldt); |
1498 | |
1499 | - /* Activate the LDT for all CPUs using current_mm. */ |
1500 | - on_each_cpu_mask(mm_cpumask(current_mm), flush_ldt, current_mm, true); |
1501 | + /* Activate the LDT for all CPUs using currents mm. */ |
1502 | + on_each_cpu_mask(mm_cpumask(mm), flush_ldt, mm, true); |
1503 | + |
1504 | + mutex_unlock(&mm->context.lock); |
1505 | } |
1506 | |
1507 | static void free_ldt_struct(struct ldt_struct *ldt) |
1508 | @@ -124,27 +131,20 @@ static void free_ldt_struct(struct ldt_struct *ldt) |
1509 | } |
1510 | |
1511 | /* |
1512 | - * we do not have to muck with descriptors here, that is |
1513 | - * done in switch_mm() as needed. |
1514 | + * Called on fork from arch_dup_mmap(). Just copy the current LDT state, |
1515 | + * the new task is not running, so nothing can be installed. |
1516 | */ |
1517 | -int init_new_context_ldt(struct task_struct *tsk, struct mm_struct *mm) |
1518 | +int ldt_dup_context(struct mm_struct *old_mm, struct mm_struct *mm) |
1519 | { |
1520 | struct ldt_struct *new_ldt; |
1521 | - struct mm_struct *old_mm; |
1522 | int retval = 0; |
1523 | |
1524 | - mutex_init(&mm->context.lock); |
1525 | - old_mm = current->mm; |
1526 | - if (!old_mm) { |
1527 | - mm->context.ldt = NULL; |
1528 | + if (!old_mm) |
1529 | return 0; |
1530 | - } |
1531 | |
1532 | mutex_lock(&old_mm->context.lock); |
1533 | - if (!old_mm->context.ldt) { |
1534 | - mm->context.ldt = NULL; |
1535 | + if (!old_mm->context.ldt) |
1536 | goto out_unlock; |
1537 | - } |
1538 | |
1539 | new_ldt = alloc_ldt_struct(old_mm->context.ldt->nr_entries); |
1540 | if (!new_ldt) { |
1541 | @@ -180,7 +180,7 @@ static int read_ldt(void __user *ptr, unsigned long bytecount) |
1542 | unsigned long entries_size; |
1543 | int retval; |
1544 | |
1545 | - mutex_lock(&mm->context.lock); |
1546 | + down_read(&mm->context.ldt_usr_sem); |
1547 | |
1548 | if (!mm->context.ldt) { |
1549 | retval = 0; |
1550 | @@ -209,7 +209,7 @@ static int read_ldt(void __user *ptr, unsigned long bytecount) |
1551 | retval = bytecount; |
1552 | |
1553 | out_unlock: |
1554 | - mutex_unlock(&mm->context.lock); |
1555 | + up_read(&mm->context.ldt_usr_sem); |
1556 | return retval; |
1557 | } |
1558 | |
1559 | @@ -269,7 +269,8 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) |
1560 | ldt.avl = 0; |
1561 | } |
1562 | |
1563 | - mutex_lock(&mm->context.lock); |
1564 | + if (down_write_killable(&mm->context.ldt_usr_sem)) |
1565 | + return -EINTR; |
1566 | |
1567 | old_ldt = mm->context.ldt; |
1568 | old_nr_entries = old_ldt ? old_ldt->nr_entries : 0; |
1569 | @@ -291,7 +292,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) |
1570 | error = 0; |
1571 | |
1572 | out_unlock: |
1573 | - mutex_unlock(&mm->context.lock); |
1574 | + up_write(&mm->context.ldt_usr_sem); |
1575 | out: |
1576 | return error; |
1577 | } |
1578 | diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c |
1579 | index 142126ab5aae..12bf07d44dfe 100644 |
1580 | --- a/arch/x86/kernel/smpboot.c |
1581 | +++ b/arch/x86/kernel/smpboot.c |
1582 | @@ -990,12 +990,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle, |
1583 | initial_code = (unsigned long)start_secondary; |
1584 | initial_stack = idle->thread.sp; |
1585 | |
1586 | - /* |
1587 | - * Enable the espfix hack for this CPU |
1588 | - */ |
1589 | -#ifdef CONFIG_X86_ESPFIX64 |
1590 | + /* Enable the espfix hack for this CPU */ |
1591 | init_espfix_ap(cpu); |
1592 | -#endif |
1593 | |
1594 | /* So we see what's up */ |
1595 | announce_cpu(cpu, apicid); |
1596 | diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c |
1597 | index 74136fd16f49..7c16fe0b60c2 100644 |
1598 | --- a/arch/x86/kernel/traps.c |
1599 | +++ b/arch/x86/kernel/traps.c |
1600 | @@ -52,6 +52,7 @@ |
1601 | #include <asm/traps.h> |
1602 | #include <asm/desc.h> |
1603 | #include <asm/fpu/internal.h> |
1604 | +#include <asm/cpu_entry_area.h> |
1605 | #include <asm/mce.h> |
1606 | #include <asm/fixmap.h> |
1607 | #include <asm/mach_traps.h> |
1608 | @@ -950,8 +951,9 @@ void __init trap_init(void) |
1609 | * "sidt" instruction will not leak the location of the kernel, and |
1610 | * to defend the IDT against arbitrary memory write vulnerabilities. |
1611 | * It will be reloaded in cpu_init() */ |
1612 | - __set_fixmap(FIX_RO_IDT, __pa_symbol(idt_table), PAGE_KERNEL_RO); |
1613 | - idt_descr.address = fix_to_virt(FIX_RO_IDT); |
1614 | + cea_set_pte(CPU_ENTRY_AREA_RO_IDT_VADDR, __pa_symbol(idt_table), |
1615 | + PAGE_KERNEL_RO); |
1616 | + idt_descr.address = CPU_ENTRY_AREA_RO_IDT; |
1617 | |
1618 | /* |
1619 | * Should be a barrier for any external CPU state: |
1620 | diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c |
1621 | index d90cdc77e077..7bbb5da2b49d 100644 |
1622 | --- a/arch/x86/kvm/emulate.c |
1623 | +++ b/arch/x86/kvm/emulate.c |
1624 | @@ -2404,9 +2404,21 @@ static int rsm_load_seg_64(struct x86_emulate_ctxt *ctxt, u64 smbase, int n) |
1625 | } |
1626 | |
1627 | static int rsm_enter_protected_mode(struct x86_emulate_ctxt *ctxt, |
1628 | - u64 cr0, u64 cr4) |
1629 | + u64 cr0, u64 cr3, u64 cr4) |
1630 | { |
1631 | int bad; |
1632 | + u64 pcid; |
1633 | + |
1634 | + /* In order to later set CR4.PCIDE, CR3[11:0] must be zero. */ |
1635 | + pcid = 0; |
1636 | + if (cr4 & X86_CR4_PCIDE) { |
1637 | + pcid = cr3 & 0xfff; |
1638 | + cr3 &= ~0xfff; |
1639 | + } |
1640 | + |
1641 | + bad = ctxt->ops->set_cr(ctxt, 3, cr3); |
1642 | + if (bad) |
1643 | + return X86EMUL_UNHANDLEABLE; |
1644 | |
1645 | /* |
1646 | * First enable PAE, long mode needs it before CR0.PG = 1 is set. |
1647 | @@ -2425,6 +2437,12 @@ static int rsm_enter_protected_mode(struct x86_emulate_ctxt *ctxt, |
1648 | bad = ctxt->ops->set_cr(ctxt, 4, cr4); |
1649 | if (bad) |
1650 | return X86EMUL_UNHANDLEABLE; |
1651 | + if (pcid) { |
1652 | + bad = ctxt->ops->set_cr(ctxt, 3, cr3 | pcid); |
1653 | + if (bad) |
1654 | + return X86EMUL_UNHANDLEABLE; |
1655 | + } |
1656 | + |
1657 | } |
1658 | |
1659 | return X86EMUL_CONTINUE; |
1660 | @@ -2435,11 +2453,11 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, u64 smbase) |
1661 | struct desc_struct desc; |
1662 | struct desc_ptr dt; |
1663 | u16 selector; |
1664 | - u32 val, cr0, cr4; |
1665 | + u32 val, cr0, cr3, cr4; |
1666 | int i; |
1667 | |
1668 | cr0 = GET_SMSTATE(u32, smbase, 0x7ffc); |
1669 | - ctxt->ops->set_cr(ctxt, 3, GET_SMSTATE(u32, smbase, 0x7ff8)); |
1670 | + cr3 = GET_SMSTATE(u32, smbase, 0x7ff8); |
1671 | ctxt->eflags = GET_SMSTATE(u32, smbase, 0x7ff4) | X86_EFLAGS_FIXED; |
1672 | ctxt->_eip = GET_SMSTATE(u32, smbase, 0x7ff0); |
1673 | |
1674 | @@ -2481,14 +2499,14 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, u64 smbase) |
1675 | |
1676 | ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smbase, 0x7ef8)); |
1677 | |
1678 | - return rsm_enter_protected_mode(ctxt, cr0, cr4); |
1679 | + return rsm_enter_protected_mode(ctxt, cr0, cr3, cr4); |
1680 | } |
1681 | |
1682 | static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase) |
1683 | { |
1684 | struct desc_struct desc; |
1685 | struct desc_ptr dt; |
1686 | - u64 val, cr0, cr4; |
1687 | + u64 val, cr0, cr3, cr4; |
1688 | u32 base3; |
1689 | u16 selector; |
1690 | int i, r; |
1691 | @@ -2505,7 +2523,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase) |
1692 | ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1); |
1693 | |
1694 | cr0 = GET_SMSTATE(u64, smbase, 0x7f58); |
1695 | - ctxt->ops->set_cr(ctxt, 3, GET_SMSTATE(u64, smbase, 0x7f50)); |
1696 | + cr3 = GET_SMSTATE(u64, smbase, 0x7f50); |
1697 | cr4 = GET_SMSTATE(u64, smbase, 0x7f48); |
1698 | ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smbase, 0x7f00)); |
1699 | val = GET_SMSTATE(u64, smbase, 0x7ed0); |
1700 | @@ -2533,7 +2551,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase) |
1701 | dt.address = GET_SMSTATE(u64, smbase, 0x7e68); |
1702 | ctxt->ops->set_gdt(ctxt, &dt); |
1703 | |
1704 | - r = rsm_enter_protected_mode(ctxt, cr0, cr4); |
1705 | + r = rsm_enter_protected_mode(ctxt, cr0, cr3, cr4); |
1706 | if (r != X86EMUL_CONTINUE) |
1707 | return r; |
1708 | |
1709 | diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c |
1710 | index 13ebeedcec07..0fce8d73403c 100644 |
1711 | --- a/arch/x86/kvm/mmu.c |
1712 | +++ b/arch/x86/kvm/mmu.c |
1713 | @@ -3382,7 +3382,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) |
1714 | spin_lock(&vcpu->kvm->mmu_lock); |
1715 | if(make_mmu_pages_available(vcpu) < 0) { |
1716 | spin_unlock(&vcpu->kvm->mmu_lock); |
1717 | - return 1; |
1718 | + return -ENOSPC; |
1719 | } |
1720 | sp = kvm_mmu_get_page(vcpu, 0, 0, |
1721 | vcpu->arch.mmu.shadow_root_level, 1, ACC_ALL); |
1722 | @@ -3397,7 +3397,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) |
1723 | spin_lock(&vcpu->kvm->mmu_lock); |
1724 | if (make_mmu_pages_available(vcpu) < 0) { |
1725 | spin_unlock(&vcpu->kvm->mmu_lock); |
1726 | - return 1; |
1727 | + return -ENOSPC; |
1728 | } |
1729 | sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT), |
1730 | i << 30, PT32_ROOT_LEVEL, 1, ACC_ALL); |
1731 | @@ -3437,7 +3437,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu) |
1732 | spin_lock(&vcpu->kvm->mmu_lock); |
1733 | if (make_mmu_pages_available(vcpu) < 0) { |
1734 | spin_unlock(&vcpu->kvm->mmu_lock); |
1735 | - return 1; |
1736 | + return -ENOSPC; |
1737 | } |
1738 | sp = kvm_mmu_get_page(vcpu, root_gfn, 0, |
1739 | vcpu->arch.mmu.shadow_root_level, 0, ACC_ALL); |
1740 | @@ -3474,7 +3474,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu) |
1741 | spin_lock(&vcpu->kvm->mmu_lock); |
1742 | if (make_mmu_pages_available(vcpu) < 0) { |
1743 | spin_unlock(&vcpu->kvm->mmu_lock); |
1744 | - return 1; |
1745 | + return -ENOSPC; |
1746 | } |
1747 | sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, PT32_ROOT_LEVEL, |
1748 | 0, ACC_ALL); |
1749 | diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c |
1750 | index df62cdc7a258..075619a92ce7 100644 |
1751 | --- a/arch/x86/kvm/x86.c |
1752 | +++ b/arch/x86/kvm/x86.c |
1753 | @@ -7359,7 +7359,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) |
1754 | #endif |
1755 | |
1756 | kvm_rip_write(vcpu, regs->rip); |
1757 | - kvm_set_rflags(vcpu, regs->rflags); |
1758 | + kvm_set_rflags(vcpu, regs->rflags | X86_EFLAGS_FIXED); |
1759 | |
1760 | vcpu->arch.exception.pending = false; |
1761 | |
1762 | diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt |
1763 | index c4d55919fac1..e0b85930dd77 100644 |
1764 | --- a/arch/x86/lib/x86-opcode-map.txt |
1765 | +++ b/arch/x86/lib/x86-opcode-map.txt |
1766 | @@ -607,7 +607,7 @@ fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) |
1767 | fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) |
1768 | fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) |
1769 | fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) |
1770 | -ff: |
1771 | +ff: UD0 |
1772 | EndTable |
1773 | |
1774 | Table: 3-byte opcode 1 (0x0f 0x38) |
1775 | @@ -717,7 +717,7 @@ AVXcode: 2 |
1776 | 7e: vpermt2d/q Vx,Hx,Wx (66),(ev) |
1777 | 7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) |
1778 | 80: INVEPT Gy,Mdq (66) |
1779 | -81: INVPID Gy,Mdq (66) |
1780 | +81: INVVPID Gy,Mdq (66) |
1781 | 82: INVPCID Gy,Mdq (66) |
1782 | 83: vpmultishiftqb Vx,Hx,Wx (66),(ev) |
1783 | 88: vexpandps/d Vpd,Wpd (66),(ev) |
1784 | @@ -970,6 +970,15 @@ GrpTable: Grp9 |
1785 | EndTable |
1786 | |
1787 | GrpTable: Grp10 |
1788 | +# all are UD1 |
1789 | +0: UD1 |
1790 | +1: UD1 |
1791 | +2: UD1 |
1792 | +3: UD1 |
1793 | +4: UD1 |
1794 | +5: UD1 |
1795 | +6: UD1 |
1796 | +7: UD1 |
1797 | EndTable |
1798 | |
1799 | # Grp11A and Grp11B are expressed as Grp11 in Intel SDM |
1800 | diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile |
1801 | index 7ba7f3d7f477..2e0017af8f9b 100644 |
1802 | --- a/arch/x86/mm/Makefile |
1803 | +++ b/arch/x86/mm/Makefile |
1804 | @@ -10,7 +10,7 @@ CFLAGS_REMOVE_mem_encrypt.o = -pg |
1805 | endif |
1806 | |
1807 | obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ |
1808 | - pat.o pgtable.o physaddr.o setup_nx.o tlb.o |
1809 | + pat.o pgtable.o physaddr.o setup_nx.o tlb.o cpu_entry_area.o |
1810 | |
1811 | # Make sure __phys_addr has no stackprotector |
1812 | nostackp := $(call cc-option, -fno-stack-protector) |
1813 | diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c |
1814 | new file mode 100644 |
1815 | index 000000000000..fe814fd5e014 |
1816 | --- /dev/null |
1817 | +++ b/arch/x86/mm/cpu_entry_area.c |
1818 | @@ -0,0 +1,139 @@ |
1819 | +// SPDX-License-Identifier: GPL-2.0 |
1820 | + |
1821 | +#include <linux/spinlock.h> |
1822 | +#include <linux/percpu.h> |
1823 | + |
1824 | +#include <asm/cpu_entry_area.h> |
1825 | +#include <asm/pgtable.h> |
1826 | +#include <asm/fixmap.h> |
1827 | +#include <asm/desc.h> |
1828 | + |
1829 | +static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_page, entry_stack_storage); |
1830 | + |
1831 | +#ifdef CONFIG_X86_64 |
1832 | +static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks |
1833 | + [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]); |
1834 | +#endif |
1835 | + |
1836 | +struct cpu_entry_area *get_cpu_entry_area(int cpu) |
1837 | +{ |
1838 | + unsigned long va = CPU_ENTRY_AREA_PER_CPU + cpu * CPU_ENTRY_AREA_SIZE; |
1839 | + BUILD_BUG_ON(sizeof(struct cpu_entry_area) % PAGE_SIZE != 0); |
1840 | + |
1841 | + return (struct cpu_entry_area *) va; |
1842 | +} |
1843 | +EXPORT_SYMBOL(get_cpu_entry_area); |
1844 | + |
1845 | +void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags) |
1846 | +{ |
1847 | + unsigned long va = (unsigned long) cea_vaddr; |
1848 | + |
1849 | + set_pte_vaddr(va, pfn_pte(pa >> PAGE_SHIFT, flags)); |
1850 | +} |
1851 | + |
1852 | +static void __init |
1853 | +cea_map_percpu_pages(void *cea_vaddr, void *ptr, int pages, pgprot_t prot) |
1854 | +{ |
1855 | + for ( ; pages; pages--, cea_vaddr+= PAGE_SIZE, ptr += PAGE_SIZE) |
1856 | + cea_set_pte(cea_vaddr, per_cpu_ptr_to_phys(ptr), prot); |
1857 | +} |
1858 | + |
1859 | +/* Setup the fixmap mappings only once per-processor */ |
1860 | +static void __init setup_cpu_entry_area(int cpu) |
1861 | +{ |
1862 | +#ifdef CONFIG_X86_64 |
1863 | + extern char _entry_trampoline[]; |
1864 | + |
1865 | + /* On 64-bit systems, we use a read-only fixmap GDT and TSS. */ |
1866 | + pgprot_t gdt_prot = PAGE_KERNEL_RO; |
1867 | + pgprot_t tss_prot = PAGE_KERNEL_RO; |
1868 | +#else |
1869 | + /* |
1870 | + * On native 32-bit systems, the GDT cannot be read-only because |
1871 | + * our double fault handler uses a task gate, and entering through |
1872 | + * a task gate needs to change an available TSS to busy. If the |
1873 | + * GDT is read-only, that will triple fault. The TSS cannot be |
1874 | + * read-only because the CPU writes to it on task switches. |
1875 | + * |
1876 | + * On Xen PV, the GDT must be read-only because the hypervisor |
1877 | + * requires it. |
1878 | + */ |
1879 | + pgprot_t gdt_prot = boot_cpu_has(X86_FEATURE_XENPV) ? |
1880 | + PAGE_KERNEL_RO : PAGE_KERNEL; |
1881 | + pgprot_t tss_prot = PAGE_KERNEL; |
1882 | +#endif |
1883 | + |
1884 | + cea_set_pte(&get_cpu_entry_area(cpu)->gdt, get_cpu_gdt_paddr(cpu), |
1885 | + gdt_prot); |
1886 | + |
1887 | + cea_map_percpu_pages(&get_cpu_entry_area(cpu)->entry_stack_page, |
1888 | + per_cpu_ptr(&entry_stack_storage, cpu), 1, |
1889 | + PAGE_KERNEL); |
1890 | + |
1891 | + /* |
1892 | + * The Intel SDM says (Volume 3, 7.2.1): |
1893 | + * |
1894 | + * Avoid placing a page boundary in the part of the TSS that the |
1895 | + * processor reads during a task switch (the first 104 bytes). The |
1896 | + * processor may not correctly perform address translations if a |
1897 | + * boundary occurs in this area. During a task switch, the processor |
1898 | + * reads and writes into the first 104 bytes of each TSS (using |
1899 | + * contiguous physical addresses beginning with the physical address |
1900 | + * of the first byte of the TSS). So, after TSS access begins, if |
1901 | + * part of the 104 bytes is not physically contiguous, the processor |
1902 | + * will access incorrect information without generating a page-fault |
1903 | + * exception. |
1904 | + * |
1905 | + * There are also a lot of errata involving the TSS spanning a page |
1906 | + * boundary. Assert that we're not doing that. |
1907 | + */ |
1908 | + BUILD_BUG_ON((offsetof(struct tss_struct, x86_tss) ^ |
1909 | + offsetofend(struct tss_struct, x86_tss)) & PAGE_MASK); |
1910 | + BUILD_BUG_ON(sizeof(struct tss_struct) % PAGE_SIZE != 0); |
1911 | + cea_map_percpu_pages(&get_cpu_entry_area(cpu)->tss, |
1912 | + &per_cpu(cpu_tss_rw, cpu), |
1913 | + sizeof(struct tss_struct) / PAGE_SIZE, tss_prot); |
1914 | + |
1915 | +#ifdef CONFIG_X86_32 |
1916 | + per_cpu(cpu_entry_area, cpu) = get_cpu_entry_area(cpu); |
1917 | +#endif |
1918 | + |
1919 | +#ifdef CONFIG_X86_64 |
1920 | + BUILD_BUG_ON(sizeof(exception_stacks) % PAGE_SIZE != 0); |
1921 | + BUILD_BUG_ON(sizeof(exception_stacks) != |
1922 | + sizeof(((struct cpu_entry_area *)0)->exception_stacks)); |
1923 | + cea_map_percpu_pages(&get_cpu_entry_area(cpu)->exception_stacks, |
1924 | + &per_cpu(exception_stacks, cpu), |
1925 | + sizeof(exception_stacks) / PAGE_SIZE, PAGE_KERNEL); |
1926 | + |
1927 | + cea_set_pte(&get_cpu_entry_area(cpu)->entry_trampoline, |
1928 | + __pa_symbol(_entry_trampoline), PAGE_KERNEL_RX); |
1929 | +#endif |
1930 | +} |
1931 | + |
1932 | +static __init void setup_cpu_entry_area_ptes(void) |
1933 | +{ |
1934 | +#ifdef CONFIG_X86_32 |
1935 | + unsigned long start, end; |
1936 | + |
1937 | + BUILD_BUG_ON(CPU_ENTRY_AREA_PAGES * PAGE_SIZE < CPU_ENTRY_AREA_MAP_SIZE); |
1938 | + BUG_ON(CPU_ENTRY_AREA_BASE & ~PMD_MASK); |
1939 | + |
1940 | + start = CPU_ENTRY_AREA_BASE; |
1941 | + end = start + CPU_ENTRY_AREA_MAP_SIZE; |
1942 | + |
1943 | + /* Careful here: start + PMD_SIZE might wrap around */ |
1944 | + for (; start < end && start >= CPU_ENTRY_AREA_BASE; start += PMD_SIZE) |
1945 | + populate_extra_pte(start); |
1946 | +#endif |
1947 | +} |
1948 | + |
1949 | +void __init setup_cpu_entry_areas(void) |
1950 | +{ |
1951 | + unsigned int cpu; |
1952 | + |
1953 | + setup_cpu_entry_area_ptes(); |
1954 | + |
1955 | + for_each_possible_cpu(cpu) |
1956 | + setup_cpu_entry_area(cpu); |
1957 | +} |
1958 | diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c |
1959 | index 5e3ac6fe6c9e..43dedbfb7257 100644 |
1960 | --- a/arch/x86/mm/dump_pagetables.c |
1961 | +++ b/arch/x86/mm/dump_pagetables.c |
1962 | @@ -44,10 +44,12 @@ struct addr_marker { |
1963 | unsigned long max_lines; |
1964 | }; |
1965 | |
1966 | -/* indices for address_markers; keep sync'd w/ address_markers below */ |
1967 | +/* Address space markers hints */ |
1968 | + |
1969 | +#ifdef CONFIG_X86_64 |
1970 | + |
1971 | enum address_markers_idx { |
1972 | USER_SPACE_NR = 0, |
1973 | -#ifdef CONFIG_X86_64 |
1974 | KERNEL_SPACE_NR, |
1975 | LOW_KERNEL_NR, |
1976 | VMALLOC_START_NR, |
1977 | @@ -56,56 +58,74 @@ enum address_markers_idx { |
1978 | KASAN_SHADOW_START_NR, |
1979 | KASAN_SHADOW_END_NR, |
1980 | #endif |
1981 | -# ifdef CONFIG_X86_ESPFIX64 |
1982 | + CPU_ENTRY_AREA_NR, |
1983 | +#ifdef CONFIG_X86_ESPFIX64 |
1984 | ESPFIX_START_NR, |
1985 | -# endif |
1986 | +#endif |
1987 | +#ifdef CONFIG_EFI |
1988 | + EFI_END_NR, |
1989 | +#endif |
1990 | HIGH_KERNEL_NR, |
1991 | MODULES_VADDR_NR, |
1992 | MODULES_END_NR, |
1993 | -#else |
1994 | + FIXADDR_START_NR, |
1995 | + END_OF_SPACE_NR, |
1996 | +}; |
1997 | + |
1998 | +static struct addr_marker address_markers[] = { |
1999 | + [USER_SPACE_NR] = { 0, "User Space" }, |
2000 | + [KERNEL_SPACE_NR] = { (1UL << 63), "Kernel Space" }, |
2001 | + [LOW_KERNEL_NR] = { 0UL, "Low Kernel Mapping" }, |
2002 | + [VMALLOC_START_NR] = { 0UL, "vmalloc() Area" }, |
2003 | + [VMEMMAP_START_NR] = { 0UL, "Vmemmap" }, |
2004 | +#ifdef CONFIG_KASAN |
2005 | + [KASAN_SHADOW_START_NR] = { KASAN_SHADOW_START, "KASAN shadow" }, |
2006 | + [KASAN_SHADOW_END_NR] = { KASAN_SHADOW_END, "KASAN shadow end" }, |
2007 | +#endif |
2008 | + [CPU_ENTRY_AREA_NR] = { CPU_ENTRY_AREA_BASE,"CPU entry Area" }, |
2009 | +#ifdef CONFIG_X86_ESPFIX64 |
2010 | + [ESPFIX_START_NR] = { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, |
2011 | +#endif |
2012 | +#ifdef CONFIG_EFI |
2013 | + [EFI_END_NR] = { EFI_VA_END, "EFI Runtime Services" }, |
2014 | +#endif |
2015 | + [HIGH_KERNEL_NR] = { __START_KERNEL_map, "High Kernel Mapping" }, |
2016 | + [MODULES_VADDR_NR] = { MODULES_VADDR, "Modules" }, |
2017 | + [MODULES_END_NR] = { MODULES_END, "End Modules" }, |
2018 | + [FIXADDR_START_NR] = { FIXADDR_START, "Fixmap Area" }, |
2019 | + [END_OF_SPACE_NR] = { -1, NULL } |
2020 | +}; |
2021 | + |
2022 | +#else /* CONFIG_X86_64 */ |
2023 | + |
2024 | +enum address_markers_idx { |
2025 | + USER_SPACE_NR = 0, |
2026 | KERNEL_SPACE_NR, |
2027 | VMALLOC_START_NR, |
2028 | VMALLOC_END_NR, |
2029 | -# ifdef CONFIG_HIGHMEM |
2030 | +#ifdef CONFIG_HIGHMEM |
2031 | PKMAP_BASE_NR, |
2032 | -# endif |
2033 | - FIXADDR_START_NR, |
2034 | #endif |
2035 | + CPU_ENTRY_AREA_NR, |
2036 | + FIXADDR_START_NR, |
2037 | + END_OF_SPACE_NR, |
2038 | }; |
2039 | |
2040 | -/* Address space markers hints */ |
2041 | static struct addr_marker address_markers[] = { |
2042 | - { 0, "User Space" }, |
2043 | -#ifdef CONFIG_X86_64 |
2044 | - { 0x8000000000000000UL, "Kernel Space" }, |
2045 | - { 0/* PAGE_OFFSET */, "Low Kernel Mapping" }, |
2046 | - { 0/* VMALLOC_START */, "vmalloc() Area" }, |
2047 | - { 0/* VMEMMAP_START */, "Vmemmap" }, |
2048 | -#ifdef CONFIG_KASAN |
2049 | - { KASAN_SHADOW_START, "KASAN shadow" }, |
2050 | - { KASAN_SHADOW_END, "KASAN shadow end" }, |
2051 | + [USER_SPACE_NR] = { 0, "User Space" }, |
2052 | + [KERNEL_SPACE_NR] = { PAGE_OFFSET, "Kernel Mapping" }, |
2053 | + [VMALLOC_START_NR] = { 0UL, "vmalloc() Area" }, |
2054 | + [VMALLOC_END_NR] = { 0UL, "vmalloc() End" }, |
2055 | +#ifdef CONFIG_HIGHMEM |
2056 | + [PKMAP_BASE_NR] = { 0UL, "Persistent kmap() Area" }, |
2057 | #endif |
2058 | -# ifdef CONFIG_X86_ESPFIX64 |
2059 | - { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, |
2060 | -# endif |
2061 | -# ifdef CONFIG_EFI |
2062 | - { EFI_VA_END, "EFI Runtime Services" }, |
2063 | -# endif |
2064 | - { __START_KERNEL_map, "High Kernel Mapping" }, |
2065 | - { MODULES_VADDR, "Modules" }, |
2066 | - { MODULES_END, "End Modules" }, |
2067 | -#else |
2068 | - { PAGE_OFFSET, "Kernel Mapping" }, |
2069 | - { 0/* VMALLOC_START */, "vmalloc() Area" }, |
2070 | - { 0/*VMALLOC_END*/, "vmalloc() End" }, |
2071 | -# ifdef CONFIG_HIGHMEM |
2072 | - { 0/*PKMAP_BASE*/, "Persistent kmap() Area" }, |
2073 | -# endif |
2074 | - { 0/*FIXADDR_START*/, "Fixmap Area" }, |
2075 | -#endif |
2076 | - { -1, NULL } /* End of list */ |
2077 | + [CPU_ENTRY_AREA_NR] = { 0UL, "CPU entry area" }, |
2078 | + [FIXADDR_START_NR] = { 0UL, "Fixmap area" }, |
2079 | + [END_OF_SPACE_NR] = { -1, NULL } |
2080 | }; |
2081 | |
2082 | +#endif /* !CONFIG_X86_64 */ |
2083 | + |
2084 | /* Multipliers for offsets within the PTEs */ |
2085 | #define PTE_LEVEL_MULT (PAGE_SIZE) |
2086 | #define PMD_LEVEL_MULT (PTRS_PER_PTE * PTE_LEVEL_MULT) |
2087 | @@ -140,7 +160,7 @@ static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg) |
2088 | static const char * const level_name[] = |
2089 | { "cr3", "pgd", "p4d", "pud", "pmd", "pte" }; |
2090 | |
2091 | - if (!pgprot_val(prot)) { |
2092 | + if (!(pr & _PAGE_PRESENT)) { |
2093 | /* Not present */ |
2094 | pt_dump_cont_printf(m, dmsg, " "); |
2095 | } else { |
2096 | @@ -525,8 +545,8 @@ static int __init pt_dump_init(void) |
2097 | address_markers[PKMAP_BASE_NR].start_address = PKMAP_BASE; |
2098 | # endif |
2099 | address_markers[FIXADDR_START_NR].start_address = FIXADDR_START; |
2100 | + address_markers[CPU_ENTRY_AREA_NR].start_address = CPU_ENTRY_AREA_BASE; |
2101 | #endif |
2102 | - |
2103 | return 0; |
2104 | } |
2105 | __initcall(pt_dump_init); |
2106 | diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c |
2107 | index 8a64a6f2848d..135c9a7898c7 100644 |
2108 | --- a/arch/x86/mm/init_32.c |
2109 | +++ b/arch/x86/mm/init_32.c |
2110 | @@ -50,6 +50,7 @@ |
2111 | #include <asm/setup.h> |
2112 | #include <asm/set_memory.h> |
2113 | #include <asm/page_types.h> |
2114 | +#include <asm/cpu_entry_area.h> |
2115 | #include <asm/init.h> |
2116 | |
2117 | #include "mm_internal.h" |
2118 | @@ -766,6 +767,7 @@ void __init mem_init(void) |
2119 | mem_init_print_info(NULL); |
2120 | printk(KERN_INFO "virtual kernel memory layout:\n" |
2121 | " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" |
2122 | + " cpu_entry : 0x%08lx - 0x%08lx (%4ld kB)\n" |
2123 | #ifdef CONFIG_HIGHMEM |
2124 | " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" |
2125 | #endif |
2126 | @@ -777,6 +779,10 @@ void __init mem_init(void) |
2127 | FIXADDR_START, FIXADDR_TOP, |
2128 | (FIXADDR_TOP - FIXADDR_START) >> 10, |
2129 | |
2130 | + CPU_ENTRY_AREA_BASE, |
2131 | + CPU_ENTRY_AREA_BASE + CPU_ENTRY_AREA_MAP_SIZE, |
2132 | + CPU_ENTRY_AREA_MAP_SIZE >> 10, |
2133 | + |
2134 | #ifdef CONFIG_HIGHMEM |
2135 | PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, |
2136 | (LAST_PKMAP*PAGE_SIZE) >> 10, |
2137 | diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c |
2138 | index 9ec70d780f1f..47388f0c0e59 100644 |
2139 | --- a/arch/x86/mm/kasan_init_64.c |
2140 | +++ b/arch/x86/mm/kasan_init_64.c |
2141 | @@ -15,6 +15,7 @@ |
2142 | #include <asm/tlbflush.h> |
2143 | #include <asm/sections.h> |
2144 | #include <asm/pgtable.h> |
2145 | +#include <asm/cpu_entry_area.h> |
2146 | |
2147 | extern struct range pfn_mapped[E820_MAX_ENTRIES]; |
2148 | |
2149 | @@ -322,31 +323,33 @@ void __init kasan_init(void) |
2150 | map_range(&pfn_mapped[i]); |
2151 | } |
2152 | |
2153 | - kasan_populate_zero_shadow( |
2154 | - kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM), |
2155 | - kasan_mem_to_shadow((void *)__START_KERNEL_map)); |
2156 | - |
2157 | - kasan_populate_shadow((unsigned long)kasan_mem_to_shadow(_stext), |
2158 | - (unsigned long)kasan_mem_to_shadow(_end), |
2159 | - early_pfn_to_nid(__pa(_stext))); |
2160 | - |
2161 | - shadow_cpu_entry_begin = (void *)__fix_to_virt(FIX_CPU_ENTRY_AREA_BOTTOM); |
2162 | + shadow_cpu_entry_begin = (void *)CPU_ENTRY_AREA_BASE; |
2163 | shadow_cpu_entry_begin = kasan_mem_to_shadow(shadow_cpu_entry_begin); |
2164 | shadow_cpu_entry_begin = (void *)round_down((unsigned long)shadow_cpu_entry_begin, |
2165 | PAGE_SIZE); |
2166 | |
2167 | - shadow_cpu_entry_end = (void *)(__fix_to_virt(FIX_CPU_ENTRY_AREA_TOP) + PAGE_SIZE); |
2168 | + shadow_cpu_entry_end = (void *)(CPU_ENTRY_AREA_BASE + |
2169 | + CPU_ENTRY_AREA_MAP_SIZE); |
2170 | shadow_cpu_entry_end = kasan_mem_to_shadow(shadow_cpu_entry_end); |
2171 | shadow_cpu_entry_end = (void *)round_up((unsigned long)shadow_cpu_entry_end, |
2172 | PAGE_SIZE); |
2173 | |
2174 | - kasan_populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END), |
2175 | - shadow_cpu_entry_begin); |
2176 | + kasan_populate_zero_shadow( |
2177 | + kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM), |
2178 | + shadow_cpu_entry_begin); |
2179 | |
2180 | kasan_populate_shadow((unsigned long)shadow_cpu_entry_begin, |
2181 | (unsigned long)shadow_cpu_entry_end, 0); |
2182 | |
2183 | - kasan_populate_zero_shadow(shadow_cpu_entry_end, (void *)KASAN_SHADOW_END); |
2184 | + kasan_populate_zero_shadow(shadow_cpu_entry_end, |
2185 | + kasan_mem_to_shadow((void *)__START_KERNEL_map)); |
2186 | + |
2187 | + kasan_populate_shadow((unsigned long)kasan_mem_to_shadow(_stext), |
2188 | + (unsigned long)kasan_mem_to_shadow(_end), |
2189 | + early_pfn_to_nid(__pa(_stext))); |
2190 | + |
2191 | + kasan_populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END), |
2192 | + (void *)KASAN_SHADOW_END); |
2193 | |
2194 | load_cr3(init_top_pgt); |
2195 | __flush_tlb_all(); |
2196 | diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c |
2197 | index 6b9bf023a700..c3c5274410a9 100644 |
2198 | --- a/arch/x86/mm/pgtable_32.c |
2199 | +++ b/arch/x86/mm/pgtable_32.c |
2200 | @@ -10,6 +10,7 @@ |
2201 | #include <linux/pagemap.h> |
2202 | #include <linux/spinlock.h> |
2203 | |
2204 | +#include <asm/cpu_entry_area.h> |
2205 | #include <asm/pgtable.h> |
2206 | #include <asm/pgalloc.h> |
2207 | #include <asm/fixmap.h> |
2208 | diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c |
2209 | index 3118392cdf75..0a1be3adc97e 100644 |
2210 | --- a/arch/x86/mm/tlb.c |
2211 | +++ b/arch/x86/mm/tlb.c |
2212 | @@ -128,7 +128,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, |
2213 | * isn't free. |
2214 | */ |
2215 | #ifdef CONFIG_DEBUG_VM |
2216 | - if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev, prev_asid))) { |
2217 | + if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev->pgd, prev_asid))) { |
2218 | /* |
2219 | * If we were to BUG here, we'd be very likely to kill |
2220 | * the system so hard that we don't see the call trace. |
2221 | @@ -195,7 +195,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, |
2222 | if (need_flush) { |
2223 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id); |
2224 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen); |
2225 | - write_cr3(build_cr3(next, new_asid)); |
2226 | + write_cr3(build_cr3(next->pgd, new_asid)); |
2227 | |
2228 | /* |
2229 | * NB: This gets called via leave_mm() in the idle path |
2230 | @@ -208,7 +208,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, |
2231 | trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL); |
2232 | } else { |
2233 | /* The new ASID is already up to date. */ |
2234 | - write_cr3(build_cr3_noflush(next, new_asid)); |
2235 | + write_cr3(build_cr3_noflush(next->pgd, new_asid)); |
2236 | |
2237 | /* See above wrt _rcuidle. */ |
2238 | trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0); |
2239 | @@ -288,7 +288,7 @@ void initialize_tlbstate_and_flush(void) |
2240 | !(cr4_read_shadow() & X86_CR4_PCIDE)); |
2241 | |
2242 | /* Force ASID 0 and force a TLB flush. */ |
2243 | - write_cr3(build_cr3(mm, 0)); |
2244 | + write_cr3(build_cr3(mm->pgd, 0)); |
2245 | |
2246 | /* Reinitialize tlbstate. */ |
2247 | this_cpu_write(cpu_tlbstate.loaded_mm_asid, 0); |
2248 | @@ -551,7 +551,7 @@ static void do_kernel_range_flush(void *info) |
2249 | |
2250 | /* flush range by one by one 'invlpg' */ |
2251 | for (addr = f->start; addr < f->end; addr += PAGE_SIZE) |
2252 | - __flush_tlb_single(addr); |
2253 | + __flush_tlb_one(addr); |
2254 | } |
2255 | |
2256 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) |
2257 | diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c |
2258 | index f44c0bc95aa2..8538a6723171 100644 |
2259 | --- a/arch/x86/platform/uv/tlb_uv.c |
2260 | +++ b/arch/x86/platform/uv/tlb_uv.c |
2261 | @@ -299,7 +299,7 @@ static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp, |
2262 | local_flush_tlb(); |
2263 | stat->d_alltlb++; |
2264 | } else { |
2265 | - __flush_tlb_one(msg->address); |
2266 | + __flush_tlb_single(msg->address); |
2267 | stat->d_onetlb++; |
2268 | } |
2269 | stat->d_requestee++; |
2270 | diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c |
2271 | index c2454237fa67..a0e2b8c6e5c7 100644 |
2272 | --- a/arch/x86/xen/mmu_pv.c |
2273 | +++ b/arch/x86/xen/mmu_pv.c |
2274 | @@ -2261,7 +2261,6 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) |
2275 | |
2276 | switch (idx) { |
2277 | case FIX_BTMAP_END ... FIX_BTMAP_BEGIN: |
2278 | - case FIX_RO_IDT: |
2279 | #ifdef CONFIG_X86_32 |
2280 | case FIX_WP_TEST: |
2281 | # ifdef CONFIG_HIGHMEM |
2282 | @@ -2272,7 +2271,6 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) |
2283 | #endif |
2284 | case FIX_TEXT_POKE0: |
2285 | case FIX_TEXT_POKE1: |
2286 | - case FIX_CPU_ENTRY_AREA_TOP ... FIX_CPU_ENTRY_AREA_BOTTOM: |
2287 | /* All local page mappings */ |
2288 | pte = pfn_pte(phys, prot); |
2289 | break; |
2290 | diff --git a/block/bio.c b/block/bio.c |
2291 | index 33fa6b4af312..7f978eac9a7a 100644 |
2292 | --- a/block/bio.c |
2293 | +++ b/block/bio.c |
2294 | @@ -599,6 +599,8 @@ void __bio_clone_fast(struct bio *bio, struct bio *bio_src) |
2295 | bio->bi_disk = bio_src->bi_disk; |
2296 | bio->bi_partno = bio_src->bi_partno; |
2297 | bio_set_flag(bio, BIO_CLONED); |
2298 | + if (bio_flagged(bio_src, BIO_THROTTLED)) |
2299 | + bio_set_flag(bio, BIO_THROTTLED); |
2300 | bio->bi_opf = bio_src->bi_opf; |
2301 | bio->bi_write_hint = bio_src->bi_write_hint; |
2302 | bio->bi_iter = bio_src->bi_iter; |
2303 | diff --git a/block/blk-throttle.c b/block/blk-throttle.c |
2304 | index 8631763866c6..a8cd7b3d9647 100644 |
2305 | --- a/block/blk-throttle.c |
2306 | +++ b/block/blk-throttle.c |
2307 | @@ -2223,13 +2223,7 @@ bool blk_throtl_bio(struct request_queue *q, struct blkcg_gq *blkg, |
2308 | out_unlock: |
2309 | spin_unlock_irq(q->queue_lock); |
2310 | out: |
2311 | - /* |
2312 | - * As multiple blk-throtls may stack in the same issue path, we |
2313 | - * don't want bios to leave with the flag set. Clear the flag if |
2314 | - * being issued. |
2315 | - */ |
2316 | - if (!throttled) |
2317 | - bio_clear_flag(bio, BIO_THROTTLED); |
2318 | + bio_set_flag(bio, BIO_THROTTLED); |
2319 | |
2320 | #ifdef CONFIG_BLK_DEV_THROTTLING_LOW |
2321 | if (throttled || !td->track_bio_latency) |
2322 | diff --git a/crypto/af_alg.c b/crypto/af_alg.c |
2323 | index e181073ef64d..6ec360213107 100644 |
2324 | --- a/crypto/af_alg.c |
2325 | +++ b/crypto/af_alg.c |
2326 | @@ -1165,12 +1165,6 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags, |
2327 | if (!af_alg_readable(sk)) |
2328 | break; |
2329 | |
2330 | - if (!ctx->used) { |
2331 | - err = af_alg_wait_for_data(sk, flags); |
2332 | - if (err) |
2333 | - return err; |
2334 | - } |
2335 | - |
2336 | seglen = min_t(size_t, (maxsize - len), |
2337 | msg_data_left(msg)); |
2338 | |
2339 | diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c |
2340 | index 3d793bc2aa82..782cb8fec323 100644 |
2341 | --- a/crypto/algif_aead.c |
2342 | +++ b/crypto/algif_aead.c |
2343 | @@ -111,6 +111,12 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, |
2344 | size_t usedpages = 0; /* [in] RX bufs to be used from user */ |
2345 | size_t processed = 0; /* [in] TX bufs to be consumed */ |
2346 | |
2347 | + if (!ctx->used) { |
2348 | + err = af_alg_wait_for_data(sk, flags); |
2349 | + if (err) |
2350 | + return err; |
2351 | + } |
2352 | + |
2353 | /* |
2354 | * Data length provided by caller via sendmsg/sendpage that has not |
2355 | * yet been processed. |
2356 | @@ -285,6 +291,10 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, |
2357 | /* AIO operation */ |
2358 | sock_hold(sk); |
2359 | areq->iocb = msg->msg_iocb; |
2360 | + |
2361 | + /* Remember output size that will be generated. */ |
2362 | + areq->outlen = outlen; |
2363 | + |
2364 | aead_request_set_callback(&areq->cra_u.aead_req, |
2365 | CRYPTO_TFM_REQ_MAY_BACKLOG, |
2366 | af_alg_async_cb, areq); |
2367 | @@ -292,12 +302,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, |
2368 | crypto_aead_decrypt(&areq->cra_u.aead_req); |
2369 | |
2370 | /* AIO operation in progress */ |
2371 | - if (err == -EINPROGRESS || err == -EBUSY) { |
2372 | - /* Remember output size that will be generated. */ |
2373 | - areq->outlen = outlen; |
2374 | - |
2375 | + if (err == -EINPROGRESS || err == -EBUSY) |
2376 | return -EIOCBQUEUED; |
2377 | - } |
2378 | |
2379 | sock_put(sk); |
2380 | } else { |
2381 | diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c |
2382 | index 30ee2a8e8f42..7a3e663d54d5 100644 |
2383 | --- a/crypto/algif_skcipher.c |
2384 | +++ b/crypto/algif_skcipher.c |
2385 | @@ -72,6 +72,12 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, |
2386 | int err = 0; |
2387 | size_t len = 0; |
2388 | |
2389 | + if (!ctx->used) { |
2390 | + err = af_alg_wait_for_data(sk, flags); |
2391 | + if (err) |
2392 | + return err; |
2393 | + } |
2394 | + |
2395 | /* Allocate cipher request for current operation. */ |
2396 | areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) + |
2397 | crypto_skcipher_reqsize(tfm)); |
2398 | @@ -119,6 +125,10 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, |
2399 | /* AIO operation */ |
2400 | sock_hold(sk); |
2401 | areq->iocb = msg->msg_iocb; |
2402 | + |
2403 | + /* Remember output size that will be generated. */ |
2404 | + areq->outlen = len; |
2405 | + |
2406 | skcipher_request_set_callback(&areq->cra_u.skcipher_req, |
2407 | CRYPTO_TFM_REQ_MAY_SLEEP, |
2408 | af_alg_async_cb, areq); |
2409 | @@ -127,12 +137,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, |
2410 | crypto_skcipher_decrypt(&areq->cra_u.skcipher_req); |
2411 | |
2412 | /* AIO operation in progress */ |
2413 | - if (err == -EINPROGRESS || err == -EBUSY) { |
2414 | - /* Remember output size that will be generated. */ |
2415 | - areq->outlen = len; |
2416 | - |
2417 | + if (err == -EINPROGRESS || err == -EBUSY) |
2418 | return -EIOCBQUEUED; |
2419 | - } |
2420 | |
2421 | sock_put(sk); |
2422 | } else { |
2423 | diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c |
2424 | index 4e6472658852..eca04d3729b3 100644 |
2425 | --- a/crypto/mcryptd.c |
2426 | +++ b/crypto/mcryptd.c |
2427 | @@ -81,6 +81,7 @@ static int mcryptd_init_queue(struct mcryptd_queue *queue, |
2428 | pr_debug("cpu_queue #%d %p\n", cpu, queue->cpu_queue); |
2429 | crypto_init_queue(&cpu_queue->queue, max_cpu_qlen); |
2430 | INIT_WORK(&cpu_queue->work, mcryptd_queue_worker); |
2431 | + spin_lock_init(&cpu_queue->q_lock); |
2432 | } |
2433 | return 0; |
2434 | } |
2435 | @@ -104,15 +105,16 @@ static int mcryptd_enqueue_request(struct mcryptd_queue *queue, |
2436 | int cpu, err; |
2437 | struct mcryptd_cpu_queue *cpu_queue; |
2438 | |
2439 | - cpu = get_cpu(); |
2440 | - cpu_queue = this_cpu_ptr(queue->cpu_queue); |
2441 | - rctx->tag.cpu = cpu; |
2442 | + cpu_queue = raw_cpu_ptr(queue->cpu_queue); |
2443 | + spin_lock(&cpu_queue->q_lock); |
2444 | + cpu = smp_processor_id(); |
2445 | + rctx->tag.cpu = smp_processor_id(); |
2446 | |
2447 | err = crypto_enqueue_request(&cpu_queue->queue, request); |
2448 | pr_debug("enqueue request: cpu %d cpu_queue %p request %p\n", |
2449 | cpu, cpu_queue, request); |
2450 | + spin_unlock(&cpu_queue->q_lock); |
2451 | queue_work_on(cpu, kcrypto_wq, &cpu_queue->work); |
2452 | - put_cpu(); |
2453 | |
2454 | return err; |
2455 | } |
2456 | @@ -161,16 +163,11 @@ static void mcryptd_queue_worker(struct work_struct *work) |
2457 | cpu_queue = container_of(work, struct mcryptd_cpu_queue, work); |
2458 | i = 0; |
2459 | while (i < MCRYPTD_BATCH || single_task_running()) { |
2460 | - /* |
2461 | - * preempt_disable/enable is used to prevent |
2462 | - * being preempted by mcryptd_enqueue_request() |
2463 | - */ |
2464 | - local_bh_disable(); |
2465 | - preempt_disable(); |
2466 | + |
2467 | + spin_lock_bh(&cpu_queue->q_lock); |
2468 | backlog = crypto_get_backlog(&cpu_queue->queue); |
2469 | req = crypto_dequeue_request(&cpu_queue->queue); |
2470 | - preempt_enable(); |
2471 | - local_bh_enable(); |
2472 | + spin_unlock_bh(&cpu_queue->q_lock); |
2473 | |
2474 | if (!req) { |
2475 | mcryptd_opportunistic_flush(); |
2476 | @@ -185,7 +182,7 @@ static void mcryptd_queue_worker(struct work_struct *work) |
2477 | ++i; |
2478 | } |
2479 | if (cpu_queue->queue.qlen) |
2480 | - queue_work(kcrypto_wq, &cpu_queue->work); |
2481 | + queue_work_on(smp_processor_id(), kcrypto_wq, &cpu_queue->work); |
2482 | } |
2483 | |
2484 | void mcryptd_flusher(struct work_struct *__work) |
2485 | diff --git a/crypto/skcipher.c b/crypto/skcipher.c |
2486 | index 778e0ff42bfa..11af5fd6a443 100644 |
2487 | --- a/crypto/skcipher.c |
2488 | +++ b/crypto/skcipher.c |
2489 | @@ -449,6 +449,8 @@ static int skcipher_walk_skcipher(struct skcipher_walk *walk, |
2490 | |
2491 | walk->total = req->cryptlen; |
2492 | walk->nbytes = 0; |
2493 | + walk->iv = req->iv; |
2494 | + walk->oiv = req->iv; |
2495 | |
2496 | if (unlikely(!walk->total)) |
2497 | return 0; |
2498 | @@ -456,9 +458,6 @@ static int skcipher_walk_skcipher(struct skcipher_walk *walk, |
2499 | scatterwalk_start(&walk->in, req->src); |
2500 | scatterwalk_start(&walk->out, req->dst); |
2501 | |
2502 | - walk->iv = req->iv; |
2503 | - walk->oiv = req->iv; |
2504 | - |
2505 | walk->flags &= ~SKCIPHER_WALK_SLEEP; |
2506 | walk->flags |= req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? |
2507 | SKCIPHER_WALK_SLEEP : 0; |
2508 | @@ -510,6 +509,8 @@ static int skcipher_walk_aead_common(struct skcipher_walk *walk, |
2509 | int err; |
2510 | |
2511 | walk->nbytes = 0; |
2512 | + walk->iv = req->iv; |
2513 | + walk->oiv = req->iv; |
2514 | |
2515 | if (unlikely(!walk->total)) |
2516 | return 0; |
2517 | @@ -525,9 +526,6 @@ static int skcipher_walk_aead_common(struct skcipher_walk *walk, |
2518 | scatterwalk_done(&walk->in, 0, walk->total); |
2519 | scatterwalk_done(&walk->out, 0, walk->total); |
2520 | |
2521 | - walk->iv = req->iv; |
2522 | - walk->oiv = req->iv; |
2523 | - |
2524 | if (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) |
2525 | walk->flags |= SKCIPHER_WALK_SLEEP; |
2526 | else |
2527 | diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c |
2528 | index 2c462beee551..a943cf17faa7 100644 |
2529 | --- a/drivers/acpi/apei/erst.c |
2530 | +++ b/drivers/acpi/apei/erst.c |
2531 | @@ -1007,7 +1007,7 @@ static ssize_t erst_reader(struct pstore_record *record) |
2532 | /* The record may be cleared by others, try read next record */ |
2533 | if (len == -ENOENT) |
2534 | goto skip; |
2535 | - else if (len < sizeof(*rcd)) { |
2536 | + else if (len < 0 || len < sizeof(*rcd)) { |
2537 | rc = -EIO; |
2538 | goto out; |
2539 | } |
2540 | diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c |
2541 | index 9c2c49b6a240..dea0fb3d6f64 100644 |
2542 | --- a/drivers/acpi/nfit/core.c |
2543 | +++ b/drivers/acpi/nfit/core.c |
2544 | @@ -1457,6 +1457,11 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, |
2545 | dev_name(&adev_dimm->dev)); |
2546 | return -ENXIO; |
2547 | } |
2548 | + /* |
2549 | + * Record nfit_mem for the notification path to track back to |
2550 | + * the nfit sysfs attributes for this dimm device object. |
2551 | + */ |
2552 | + dev_set_drvdata(&adev_dimm->dev, nfit_mem); |
2553 | |
2554 | /* |
2555 | * Until standardization materializes we need to consider 4 |
2556 | @@ -1516,9 +1521,11 @@ static void shutdown_dimm_notify(void *data) |
2557 | sysfs_put(nfit_mem->flags_attr); |
2558 | nfit_mem->flags_attr = NULL; |
2559 | } |
2560 | - if (adev_dimm) |
2561 | + if (adev_dimm) { |
2562 | acpi_remove_notify_handler(adev_dimm->handle, |
2563 | ACPI_DEVICE_NOTIFY, acpi_nvdimm_notify); |
2564 | + dev_set_drvdata(&adev_dimm->dev, NULL); |
2565 | + } |
2566 | } |
2567 | mutex_unlock(&acpi_desc->init_mutex); |
2568 | } |
2569 | diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c |
2570 | index e1cbb78c6806..c04aa11f0e21 100644 |
2571 | --- a/drivers/char/ipmi/ipmi_si_intf.c |
2572 | +++ b/drivers/char/ipmi/ipmi_si_intf.c |
2573 | @@ -3469,7 +3469,6 @@ static int add_smi(struct smi_info *new_smi) |
2574 | ipmi_addr_src_to_str(new_smi->addr_source), |
2575 | si_to_str[new_smi->si_type]); |
2576 | rv = -EBUSY; |
2577 | - kfree(new_smi); |
2578 | goto out_err; |
2579 | } |
2580 | } |
2581 | diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c |
2582 | index 6041bdba2e97..f69f9e8c6f38 100644 |
2583 | --- a/drivers/clk/sunxi/clk-sun9i-mmc.c |
2584 | +++ b/drivers/clk/sunxi/clk-sun9i-mmc.c |
2585 | @@ -16,6 +16,7 @@ |
2586 | |
2587 | #include <linux/clk.h> |
2588 | #include <linux/clk-provider.h> |
2589 | +#include <linux/delay.h> |
2590 | #include <linux/init.h> |
2591 | #include <linux/of.h> |
2592 | #include <linux/of_device.h> |
2593 | @@ -83,9 +84,20 @@ static int sun9i_mmc_reset_deassert(struct reset_controller_dev *rcdev, |
2594 | return 0; |
2595 | } |
2596 | |
2597 | +static int sun9i_mmc_reset_reset(struct reset_controller_dev *rcdev, |
2598 | + unsigned long id) |
2599 | +{ |
2600 | + sun9i_mmc_reset_assert(rcdev, id); |
2601 | + udelay(10); |
2602 | + sun9i_mmc_reset_deassert(rcdev, id); |
2603 | + |
2604 | + return 0; |
2605 | +} |
2606 | + |
2607 | static const struct reset_control_ops sun9i_mmc_reset_ops = { |
2608 | .assert = sun9i_mmc_reset_assert, |
2609 | .deassert = sun9i_mmc_reset_deassert, |
2610 | + .reset = sun9i_mmc_reset_reset, |
2611 | }; |
2612 | |
2613 | static int sun9i_a80_mmc_config_clk_probe(struct platform_device *pdev) |
2614 | diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c |
2615 | index dc1faa49687d..3b2c0538e48d 100644 |
2616 | --- a/drivers/gpu/drm/i915/i915_gem.c |
2617 | +++ b/drivers/gpu/drm/i915/i915_gem.c |
2618 | @@ -325,17 +325,10 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj) |
2619 | * must wait for all rendering to complete to the object (as unbinding |
2620 | * must anyway), and retire the requests. |
2621 | */ |
2622 | - ret = i915_gem_object_wait(obj, |
2623 | - I915_WAIT_INTERRUPTIBLE | |
2624 | - I915_WAIT_LOCKED | |
2625 | - I915_WAIT_ALL, |
2626 | - MAX_SCHEDULE_TIMEOUT, |
2627 | - NULL); |
2628 | + ret = i915_gem_object_set_to_cpu_domain(obj, false); |
2629 | if (ret) |
2630 | return ret; |
2631 | |
2632 | - i915_gem_retire_requests(to_i915(obj->base.dev)); |
2633 | - |
2634 | while ((vma = list_first_entry_or_null(&obj->vma_list, |
2635 | struct i915_vma, |
2636 | obj_link))) { |
2637 | diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c |
2638 | index d9791292553e..7b909d814d38 100644 |
2639 | --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c |
2640 | +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c |
2641 | @@ -567,12 +567,12 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, |
2642 | if (IS_ERR(tcon->crtc)) { |
2643 | dev_err(dev, "Couldn't create our CRTC\n"); |
2644 | ret = PTR_ERR(tcon->crtc); |
2645 | - goto err_free_clocks; |
2646 | + goto err_free_dotclock; |
2647 | } |
2648 | |
2649 | ret = sun4i_rgb_init(drm, tcon); |
2650 | if (ret < 0) |
2651 | - goto err_free_clocks; |
2652 | + goto err_free_dotclock; |
2653 | |
2654 | list_add_tail(&tcon->list, &drv->tcon_list); |
2655 | |
2656 | diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c |
2657 | index c9714072e224..a14196e95e9b 100644 |
2658 | --- a/drivers/mfd/cros_ec_spi.c |
2659 | +++ b/drivers/mfd/cros_ec_spi.c |
2660 | @@ -667,6 +667,7 @@ static int cros_ec_spi_probe(struct spi_device *spi) |
2661 | sizeof(struct ec_response_get_protocol_info); |
2662 | ec_dev->dout_size = sizeof(struct ec_host_request); |
2663 | |
2664 | + ec_spi->last_transfer_ns = ktime_get_ns(); |
2665 | |
2666 | err = cros_ec_register(ec_dev); |
2667 | if (err) { |
2668 | diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c |
2669 | index da16bf45fab4..dc94ffc6321a 100644 |
2670 | --- a/drivers/mfd/twl4030-audio.c |
2671 | +++ b/drivers/mfd/twl4030-audio.c |
2672 | @@ -159,13 +159,18 @@ unsigned int twl4030_audio_get_mclk(void) |
2673 | EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk); |
2674 | |
2675 | static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata, |
2676 | - struct device_node *node) |
2677 | + struct device_node *parent) |
2678 | { |
2679 | + struct device_node *node; |
2680 | + |
2681 | if (pdata && pdata->codec) |
2682 | return true; |
2683 | |
2684 | - if (of_find_node_by_name(node, "codec")) |
2685 | + node = of_get_child_by_name(parent, "codec"); |
2686 | + if (node) { |
2687 | + of_node_put(node); |
2688 | return true; |
2689 | + } |
2690 | |
2691 | return false; |
2692 | } |
2693 | diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c |
2694 | index d66502d36ba0..dd19f17a1b63 100644 |
2695 | --- a/drivers/mfd/twl6040.c |
2696 | +++ b/drivers/mfd/twl6040.c |
2697 | @@ -97,12 +97,16 @@ static struct reg_sequence twl6040_patch[] = { |
2698 | }; |
2699 | |
2700 | |
2701 | -static bool twl6040_has_vibra(struct device_node *node) |
2702 | +static bool twl6040_has_vibra(struct device_node *parent) |
2703 | { |
2704 | -#ifdef CONFIG_OF |
2705 | - if (of_find_node_by_name(node, "vibra")) |
2706 | + struct device_node *node; |
2707 | + |
2708 | + node = of_get_child_by_name(parent, "vibra"); |
2709 | + if (node) { |
2710 | + of_node_put(node); |
2711 | return true; |
2712 | -#endif |
2713 | + } |
2714 | + |
2715 | return false; |
2716 | } |
2717 | |
2718 | diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c |
2719 | index bc93b69cfd1e..a539263cd79c 100644 |
2720 | --- a/drivers/net/ethernet/marvell/mvneta.c |
2721 | +++ b/drivers/net/ethernet/marvell/mvneta.c |
2722 | @@ -1214,6 +1214,10 @@ static void mvneta_port_disable(struct mvneta_port *pp) |
2723 | val &= ~MVNETA_GMAC0_PORT_ENABLE; |
2724 | mvreg_write(pp, MVNETA_GMAC_CTRL_0, val); |
2725 | |
2726 | + pp->link = 0; |
2727 | + pp->duplex = -1; |
2728 | + pp->speed = 0; |
2729 | + |
2730 | udelay(200); |
2731 | } |
2732 | |
2733 | @@ -1958,9 +1962,9 @@ static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo, |
2734 | |
2735 | if (!mvneta_rxq_desc_is_first_last(rx_status) || |
2736 | (rx_status & MVNETA_RXD_ERR_SUMMARY)) { |
2737 | + mvneta_rx_error(pp, rx_desc); |
2738 | err_drop_frame: |
2739 | dev->stats.rx_errors++; |
2740 | - mvneta_rx_error(pp, rx_desc); |
2741 | /* leave the descriptor untouched */ |
2742 | continue; |
2743 | } |
2744 | @@ -3011,7 +3015,7 @@ static void mvneta_cleanup_rxqs(struct mvneta_port *pp) |
2745 | { |
2746 | int queue; |
2747 | |
2748 | - for (queue = 0; queue < txq_number; queue++) |
2749 | + for (queue = 0; queue < rxq_number; queue++) |
2750 | mvneta_rxq_deinit(pp, &pp->rxqs[queue]); |
2751 | } |
2752 | |
2753 | diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c |
2754 | index d5612bd1cc81..09428ebd315b 100644 |
2755 | --- a/drivers/nvdimm/btt.c |
2756 | +++ b/drivers/nvdimm/btt.c |
2757 | @@ -210,12 +210,12 @@ static int btt_map_read(struct arena_info *arena, u32 lba, u32 *mapping, |
2758 | return ret; |
2759 | } |
2760 | |
2761 | -static int btt_log_read_pair(struct arena_info *arena, u32 lane, |
2762 | - struct log_entry *ent) |
2763 | +static int btt_log_group_read(struct arena_info *arena, u32 lane, |
2764 | + struct log_group *log) |
2765 | { |
2766 | return arena_read_bytes(arena, |
2767 | - arena->logoff + (2 * lane * LOG_ENT_SIZE), ent, |
2768 | - 2 * LOG_ENT_SIZE, 0); |
2769 | + arena->logoff + (lane * LOG_GRP_SIZE), log, |
2770 | + LOG_GRP_SIZE, 0); |
2771 | } |
2772 | |
2773 | static struct dentry *debugfs_root; |
2774 | @@ -255,6 +255,8 @@ static void arena_debugfs_init(struct arena_info *a, struct dentry *parent, |
2775 | debugfs_create_x64("logoff", S_IRUGO, d, &a->logoff); |
2776 | debugfs_create_x64("info2off", S_IRUGO, d, &a->info2off); |
2777 | debugfs_create_x32("flags", S_IRUGO, d, &a->flags); |
2778 | + debugfs_create_u32("log_index_0", S_IRUGO, d, &a->log_index[0]); |
2779 | + debugfs_create_u32("log_index_1", S_IRUGO, d, &a->log_index[1]); |
2780 | } |
2781 | |
2782 | static void btt_debugfs_init(struct btt *btt) |
2783 | @@ -273,6 +275,11 @@ static void btt_debugfs_init(struct btt *btt) |
2784 | } |
2785 | } |
2786 | |
2787 | +static u32 log_seq(struct log_group *log, int log_idx) |
2788 | +{ |
2789 | + return le32_to_cpu(log->ent[log_idx].seq); |
2790 | +} |
2791 | + |
2792 | /* |
2793 | * This function accepts two log entries, and uses the |
2794 | * sequence number to find the 'older' entry. |
2795 | @@ -282,8 +289,10 @@ static void btt_debugfs_init(struct btt *btt) |
2796 | * |
2797 | * TODO The logic feels a bit kludge-y. make it better.. |
2798 | */ |
2799 | -static int btt_log_get_old(struct log_entry *ent) |
2800 | +static int btt_log_get_old(struct arena_info *a, struct log_group *log) |
2801 | { |
2802 | + int idx0 = a->log_index[0]; |
2803 | + int idx1 = a->log_index[1]; |
2804 | int old; |
2805 | |
2806 | /* |
2807 | @@ -291,23 +300,23 @@ static int btt_log_get_old(struct log_entry *ent) |
2808 | * the next time, the following logic works out to put this |
2809 | * (next) entry into [1] |
2810 | */ |
2811 | - if (ent[0].seq == 0) { |
2812 | - ent[0].seq = cpu_to_le32(1); |
2813 | + if (log_seq(log, idx0) == 0) { |
2814 | + log->ent[idx0].seq = cpu_to_le32(1); |
2815 | return 0; |
2816 | } |
2817 | |
2818 | - if (ent[0].seq == ent[1].seq) |
2819 | + if (log_seq(log, idx0) == log_seq(log, idx1)) |
2820 | return -EINVAL; |
2821 | - if (le32_to_cpu(ent[0].seq) + le32_to_cpu(ent[1].seq) > 5) |
2822 | + if (log_seq(log, idx0) + log_seq(log, idx1) > 5) |
2823 | return -EINVAL; |
2824 | |
2825 | - if (le32_to_cpu(ent[0].seq) < le32_to_cpu(ent[1].seq)) { |
2826 | - if (le32_to_cpu(ent[1].seq) - le32_to_cpu(ent[0].seq) == 1) |
2827 | + if (log_seq(log, idx0) < log_seq(log, idx1)) { |
2828 | + if ((log_seq(log, idx1) - log_seq(log, idx0)) == 1) |
2829 | old = 0; |
2830 | else |
2831 | old = 1; |
2832 | } else { |
2833 | - if (le32_to_cpu(ent[0].seq) - le32_to_cpu(ent[1].seq) == 1) |
2834 | + if ((log_seq(log, idx0) - log_seq(log, idx1)) == 1) |
2835 | old = 1; |
2836 | else |
2837 | old = 0; |
2838 | @@ -327,17 +336,18 @@ static int btt_log_read(struct arena_info *arena, u32 lane, |
2839 | { |
2840 | int ret; |
2841 | int old_ent, ret_ent; |
2842 | - struct log_entry log[2]; |
2843 | + struct log_group log; |
2844 | |
2845 | - ret = btt_log_read_pair(arena, lane, log); |
2846 | + ret = btt_log_group_read(arena, lane, &log); |
2847 | if (ret) |
2848 | return -EIO; |
2849 | |
2850 | - old_ent = btt_log_get_old(log); |
2851 | + old_ent = btt_log_get_old(arena, &log); |
2852 | if (old_ent < 0 || old_ent > 1) { |
2853 | dev_err(to_dev(arena), |
2854 | "log corruption (%d): lane %d seq [%d, %d]\n", |
2855 | - old_ent, lane, log[0].seq, log[1].seq); |
2856 | + old_ent, lane, log.ent[arena->log_index[0]].seq, |
2857 | + log.ent[arena->log_index[1]].seq); |
2858 | /* TODO set error state? */ |
2859 | return -EIO; |
2860 | } |
2861 | @@ -345,7 +355,7 @@ static int btt_log_read(struct arena_info *arena, u32 lane, |
2862 | ret_ent = (old_flag ? old_ent : (1 - old_ent)); |
2863 | |
2864 | if (ent != NULL) |
2865 | - memcpy(ent, &log[ret_ent], LOG_ENT_SIZE); |
2866 | + memcpy(ent, &log.ent[arena->log_index[ret_ent]], LOG_ENT_SIZE); |
2867 | |
2868 | return ret_ent; |
2869 | } |
2870 | @@ -359,17 +369,13 @@ static int __btt_log_write(struct arena_info *arena, u32 lane, |
2871 | u32 sub, struct log_entry *ent, unsigned long flags) |
2872 | { |
2873 | int ret; |
2874 | - /* |
2875 | - * Ignore the padding in log_entry for calculating log_half. |
2876 | - * The entry is 'committed' when we write the sequence number, |
2877 | - * and we want to ensure that that is the last thing written. |
2878 | - * We don't bother writing the padding as that would be extra |
2879 | - * media wear and write amplification |
2880 | - */ |
2881 | - unsigned int log_half = (LOG_ENT_SIZE - 2 * sizeof(u64)) / 2; |
2882 | - u64 ns_off = arena->logoff + (((2 * lane) + sub) * LOG_ENT_SIZE); |
2883 | + u32 group_slot = arena->log_index[sub]; |
2884 | + unsigned int log_half = LOG_ENT_SIZE / 2; |
2885 | void *src = ent; |
2886 | + u64 ns_off; |
2887 | |
2888 | + ns_off = arena->logoff + (lane * LOG_GRP_SIZE) + |
2889 | + (group_slot * LOG_ENT_SIZE); |
2890 | /* split the 16B write into atomic, durable halves */ |
2891 | ret = arena_write_bytes(arena, ns_off, src, log_half, flags); |
2892 | if (ret) |
2893 | @@ -452,7 +458,7 @@ static int btt_log_init(struct arena_info *arena) |
2894 | { |
2895 | size_t logsize = arena->info2off - arena->logoff; |
2896 | size_t chunk_size = SZ_4K, offset = 0; |
2897 | - struct log_entry log; |
2898 | + struct log_entry ent; |
2899 | void *zerobuf; |
2900 | int ret; |
2901 | u32 i; |
2902 | @@ -484,11 +490,11 @@ static int btt_log_init(struct arena_info *arena) |
2903 | } |
2904 | |
2905 | for (i = 0; i < arena->nfree; i++) { |
2906 | - log.lba = cpu_to_le32(i); |
2907 | - log.old_map = cpu_to_le32(arena->external_nlba + i); |
2908 | - log.new_map = cpu_to_le32(arena->external_nlba + i); |
2909 | - log.seq = cpu_to_le32(LOG_SEQ_INIT); |
2910 | - ret = __btt_log_write(arena, i, 0, &log, 0); |
2911 | + ent.lba = cpu_to_le32(i); |
2912 | + ent.old_map = cpu_to_le32(arena->external_nlba + i); |
2913 | + ent.new_map = cpu_to_le32(arena->external_nlba + i); |
2914 | + ent.seq = cpu_to_le32(LOG_SEQ_INIT); |
2915 | + ret = __btt_log_write(arena, i, 0, &ent, 0); |
2916 | if (ret) |
2917 | goto free; |
2918 | } |
2919 | @@ -593,6 +599,123 @@ static int btt_freelist_init(struct arena_info *arena) |
2920 | return 0; |
2921 | } |
2922 | |
2923 | +static bool ent_is_padding(struct log_entry *ent) |
2924 | +{ |
2925 | + return (ent->lba == 0) && (ent->old_map == 0) && (ent->new_map == 0) |
2926 | + && (ent->seq == 0); |
2927 | +} |
2928 | + |
2929 | +/* |
2930 | + * Detecting valid log indices: We read a log group (see the comments in btt.h |
2931 | + * for a description of a 'log_group' and its 'slots'), and iterate over its |
2932 | + * four slots. We expect that a padding slot will be all-zeroes, and use this |
2933 | + * to detect a padding slot vs. an actual entry. |
2934 | + * |
2935 | + * If a log_group is in the initial state, i.e. hasn't been used since the |
2936 | + * creation of this BTT layout, it will have three of the four slots with |
2937 | + * zeroes. We skip over these log_groups for the detection of log_index. If |
2938 | + * all log_groups are in the initial state (i.e. the BTT has never been |
2939 | + * written to), it is safe to assume the 'new format' of log entries in slots |
2940 | + * (0, 1). |
2941 | + */ |
2942 | +static int log_set_indices(struct arena_info *arena) |
2943 | +{ |
2944 | + bool idx_set = false, initial_state = true; |
2945 | + int ret, log_index[2] = {-1, -1}; |
2946 | + u32 i, j, next_idx = 0; |
2947 | + struct log_group log; |
2948 | + u32 pad_count = 0; |
2949 | + |
2950 | + for (i = 0; i < arena->nfree; i++) { |
2951 | + ret = btt_log_group_read(arena, i, &log); |
2952 | + if (ret < 0) |
2953 | + return ret; |
2954 | + |
2955 | + for (j = 0; j < 4; j++) { |
2956 | + if (!idx_set) { |
2957 | + if (ent_is_padding(&log.ent[j])) { |
2958 | + pad_count++; |
2959 | + continue; |
2960 | + } else { |
2961 | + /* Skip if index has been recorded */ |
2962 | + if ((next_idx == 1) && |
2963 | + (j == log_index[0])) |
2964 | + continue; |
2965 | + /* valid entry, record index */ |
2966 | + log_index[next_idx] = j; |
2967 | + next_idx++; |
2968 | + } |
2969 | + if (next_idx == 2) { |
2970 | + /* two valid entries found */ |
2971 | + idx_set = true; |
2972 | + } else if (next_idx > 2) { |
2973 | + /* too many valid indices */ |
2974 | + return -ENXIO; |
2975 | + } |
2976 | + } else { |
2977 | + /* |
2978 | + * once the indices have been set, just verify |
2979 | + * that all subsequent log groups are either in |
2980 | + * their initial state or follow the same |
2981 | + * indices. |
2982 | + */ |
2983 | + if (j == log_index[0]) { |
2984 | + /* entry must be 'valid' */ |
2985 | + if (ent_is_padding(&log.ent[j])) |
2986 | + return -ENXIO; |
2987 | + } else if (j == log_index[1]) { |
2988 | + ; |
2989 | + /* |
2990 | + * log_index[1] can be padding if the |
2991 | + * lane never got used and it is still |
2992 | + * in the initial state (three 'padding' |
2993 | + * entries) |
2994 | + */ |
2995 | + } else { |
2996 | + /* entry must be invalid (padding) */ |
2997 | + if (!ent_is_padding(&log.ent[j])) |
2998 | + return -ENXIO; |
2999 | + } |
3000 | + } |
3001 | + } |
3002 | + /* |
3003 | + * If any of the log_groups have more than one valid, |
3004 | + * non-padding entry, then the we are no longer in the |
3005 | + * initial_state |
3006 | + */ |
3007 | + if (pad_count < 3) |
3008 | + initial_state = false; |
3009 | + pad_count = 0; |
3010 | + } |
3011 | + |
3012 | + if (!initial_state && !idx_set) |
3013 | + return -ENXIO; |
3014 | + |
3015 | + /* |
3016 | + * If all the entries in the log were in the initial state, |
3017 | + * assume new padding scheme |
3018 | + */ |
3019 | + if (initial_state) |
3020 | + log_index[1] = 1; |
3021 | + |
3022 | + /* |
3023 | + * Only allow the known permutations of log/padding indices, |
3024 | + * i.e. (0, 1), and (0, 2) |
3025 | + */ |
3026 | + if ((log_index[0] == 0) && ((log_index[1] == 1) || (log_index[1] == 2))) |
3027 | + ; /* known index possibilities */ |
3028 | + else { |
3029 | + dev_err(to_dev(arena), "Found an unknown padding scheme\n"); |
3030 | + return -ENXIO; |
3031 | + } |
3032 | + |
3033 | + arena->log_index[0] = log_index[0]; |
3034 | + arena->log_index[1] = log_index[1]; |
3035 | + dev_dbg(to_dev(arena), "log_index_0 = %d\n", log_index[0]); |
3036 | + dev_dbg(to_dev(arena), "log_index_1 = %d\n", log_index[1]); |
3037 | + return 0; |
3038 | +} |
3039 | + |
3040 | static int btt_rtt_init(struct arena_info *arena) |
3041 | { |
3042 | arena->rtt = kcalloc(arena->nfree, sizeof(u32), GFP_KERNEL); |
3043 | @@ -649,8 +772,7 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size, |
3044 | available -= 2 * BTT_PG_SIZE; |
3045 | |
3046 | /* The log takes a fixed amount of space based on nfree */ |
3047 | - logsize = roundup(2 * arena->nfree * sizeof(struct log_entry), |
3048 | - BTT_PG_SIZE); |
3049 | + logsize = roundup(arena->nfree * LOG_GRP_SIZE, BTT_PG_SIZE); |
3050 | available -= logsize; |
3051 | |
3052 | /* Calculate optimal split between map and data area */ |
3053 | @@ -667,6 +789,10 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size, |
3054 | arena->mapoff = arena->dataoff + datasize; |
3055 | arena->logoff = arena->mapoff + mapsize; |
3056 | arena->info2off = arena->logoff + logsize; |
3057 | + |
3058 | + /* Default log indices are (0,1) */ |
3059 | + arena->log_index[0] = 0; |
3060 | + arena->log_index[1] = 1; |
3061 | return arena; |
3062 | } |
3063 | |
3064 | @@ -757,6 +883,13 @@ static int discover_arenas(struct btt *btt) |
3065 | arena->external_lba_start = cur_nlba; |
3066 | parse_arena_meta(arena, super, cur_off); |
3067 | |
3068 | + ret = log_set_indices(arena); |
3069 | + if (ret) { |
3070 | + dev_err(to_dev(arena), |
3071 | + "Unable to deduce log/padding indices\n"); |
3072 | + goto out; |
3073 | + } |
3074 | + |
3075 | mutex_init(&arena->err_lock); |
3076 | ret = btt_freelist_init(arena); |
3077 | if (ret) |
3078 | diff --git a/drivers/nvdimm/btt.h b/drivers/nvdimm/btt.h |
3079 | index 578c2057524d..2609683c4167 100644 |
3080 | --- a/drivers/nvdimm/btt.h |
3081 | +++ b/drivers/nvdimm/btt.h |
3082 | @@ -27,6 +27,7 @@ |
3083 | #define MAP_ERR_MASK (1 << MAP_ERR_SHIFT) |
3084 | #define MAP_LBA_MASK (~((1 << MAP_TRIM_SHIFT) | (1 << MAP_ERR_SHIFT))) |
3085 | #define MAP_ENT_NORMAL 0xC0000000 |
3086 | +#define LOG_GRP_SIZE sizeof(struct log_group) |
3087 | #define LOG_ENT_SIZE sizeof(struct log_entry) |
3088 | #define ARENA_MIN_SIZE (1UL << 24) /* 16 MB */ |
3089 | #define ARENA_MAX_SIZE (1ULL << 39) /* 512 GB */ |
3090 | @@ -50,12 +51,52 @@ enum btt_init_state { |
3091 | INIT_READY |
3092 | }; |
3093 | |
3094 | +/* |
3095 | + * A log group represents one log 'lane', and consists of four log entries. |
3096 | + * Two of the four entries are valid entries, and the remaining two are |
3097 | + * padding. Due to an old bug in the padding location, we need to perform a |
3098 | + * test to determine the padding scheme being used, and use that scheme |
3099 | + * thereafter. |
3100 | + * |
3101 | + * In kernels prior to 4.15, 'log group' would have actual log entries at |
3102 | + * indices (0, 2) and padding at indices (1, 3), where as the correct/updated |
3103 | + * format has log entries at indices (0, 1) and padding at indices (2, 3). |
3104 | + * |
3105 | + * Old (pre 4.15) format: |
3106 | + * +-----------------+-----------------+ |
3107 | + * | ent[0] | ent[1] | |
3108 | + * | 16B | 16B | |
3109 | + * | lba/old/new/seq | pad | |
3110 | + * +-----------------------------------+ |
3111 | + * | ent[2] | ent[3] | |
3112 | + * | 16B | 16B | |
3113 | + * | lba/old/new/seq | pad | |
3114 | + * +-----------------+-----------------+ |
3115 | + * |
3116 | + * New format: |
3117 | + * +-----------------+-----------------+ |
3118 | + * | ent[0] | ent[1] | |
3119 | + * | 16B | 16B | |
3120 | + * | lba/old/new/seq | lba/old/new/seq | |
3121 | + * +-----------------------------------+ |
3122 | + * | ent[2] | ent[3] | |
3123 | + * | 16B | 16B | |
3124 | + * | pad | pad | |
3125 | + * +-----------------+-----------------+ |
3126 | + * |
3127 | + * We detect during start-up which format is in use, and set |
3128 | + * arena->log_index[(0, 1)] with the detected format. |
3129 | + */ |
3130 | + |
3131 | struct log_entry { |
3132 | __le32 lba; |
3133 | __le32 old_map; |
3134 | __le32 new_map; |
3135 | __le32 seq; |
3136 | - __le64 padding[2]; |
3137 | +}; |
3138 | + |
3139 | +struct log_group { |
3140 | + struct log_entry ent[4]; |
3141 | }; |
3142 | |
3143 | struct btt_sb { |
3144 | @@ -125,6 +166,7 @@ struct aligned_lock { |
3145 | * @list: List head for list of arenas |
3146 | * @debugfs_dir: Debugfs dentry |
3147 | * @flags: Arena flags - may signify error states. |
3148 | + * @log_index: Indices of the valid log entries in a log_group |
3149 | * |
3150 | * arena_info is a per-arena handle. Once an arena is narrowed down for an |
3151 | * IO, this struct is passed around for the duration of the IO. |
3152 | @@ -157,6 +199,7 @@ struct arena_info { |
3153 | /* Arena flags */ |
3154 | u32 flags; |
3155 | struct mutex err_lock; |
3156 | + int log_index[2]; |
3157 | }; |
3158 | |
3159 | /** |
3160 | diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c |
3161 | index 65cc171c721d..2adada1a5855 100644 |
3162 | --- a/drivers/nvdimm/pfn_devs.c |
3163 | +++ b/drivers/nvdimm/pfn_devs.c |
3164 | @@ -364,9 +364,9 @@ struct device *nd_pfn_create(struct nd_region *nd_region) |
3165 | int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) |
3166 | { |
3167 | u64 checksum, offset; |
3168 | - unsigned long align; |
3169 | enum nd_pfn_mode mode; |
3170 | struct nd_namespace_io *nsio; |
3171 | + unsigned long align, start_pad; |
3172 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; |
3173 | struct nd_namespace_common *ndns = nd_pfn->ndns; |
3174 | const u8 *parent_uuid = nd_dev_to_uuid(&ndns->dev); |
3175 | @@ -410,6 +410,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) |
3176 | |
3177 | align = le32_to_cpu(pfn_sb->align); |
3178 | offset = le64_to_cpu(pfn_sb->dataoff); |
3179 | + start_pad = le32_to_cpu(pfn_sb->start_pad); |
3180 | if (align == 0) |
3181 | align = 1UL << ilog2(offset); |
3182 | mode = le32_to_cpu(pfn_sb->mode); |
3183 | @@ -468,7 +469,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) |
3184 | return -EBUSY; |
3185 | } |
3186 | |
3187 | - if ((align && !IS_ALIGNED(offset, align)) |
3188 | + if ((align && !IS_ALIGNED(nsio->res.start + offset + start_pad, align)) |
3189 | || !IS_ALIGNED(offset, PAGE_SIZE)) { |
3190 | dev_err(&nd_pfn->dev, |
3191 | "bad offset: %#llx dax disabled align: %#lx\n", |
3192 | @@ -582,6 +583,12 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn, |
3193 | return altmap; |
3194 | } |
3195 | |
3196 | +static u64 phys_pmem_align_down(struct nd_pfn *nd_pfn, u64 phys) |
3197 | +{ |
3198 | + return min_t(u64, PHYS_SECTION_ALIGN_DOWN(phys), |
3199 | + ALIGN_DOWN(phys, nd_pfn->align)); |
3200 | +} |
3201 | + |
3202 | static int nd_pfn_init(struct nd_pfn *nd_pfn) |
3203 | { |
3204 | u32 dax_label_reserve = is_nd_dax(&nd_pfn->dev) ? SZ_128K : 0; |
3205 | @@ -637,13 +644,16 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) |
3206 | start = nsio->res.start; |
3207 | size = PHYS_SECTION_ALIGN_UP(start + size) - start; |
3208 | if (region_intersects(start, size, IORESOURCE_SYSTEM_RAM, |
3209 | - IORES_DESC_NONE) == REGION_MIXED) { |
3210 | + IORES_DESC_NONE) == REGION_MIXED |
3211 | + || !IS_ALIGNED(start + resource_size(&nsio->res), |
3212 | + nd_pfn->align)) { |
3213 | size = resource_size(&nsio->res); |
3214 | - end_trunc = start + size - PHYS_SECTION_ALIGN_DOWN(start + size); |
3215 | + end_trunc = start + size - phys_pmem_align_down(nd_pfn, |
3216 | + start + size); |
3217 | } |
3218 | |
3219 | if (start_pad + end_trunc) |
3220 | - dev_info(&nd_pfn->dev, "%s section collision, truncate %d bytes\n", |
3221 | + dev_info(&nd_pfn->dev, "%s alignment collision, truncate %d bytes\n", |
3222 | dev_name(&ndns->dev), start_pad + end_trunc); |
3223 | |
3224 | /* |
3225 | diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c |
3226 | index a25fed52f7e9..41b740aed3a3 100644 |
3227 | --- a/drivers/parisc/lba_pci.c |
3228 | +++ b/drivers/parisc/lba_pci.c |
3229 | @@ -1692,3 +1692,36 @@ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) |
3230 | iounmap(base_addr); |
3231 | } |
3232 | |
3233 | + |
3234 | +/* |
3235 | + * The design of the Diva management card in rp34x0 machines (rp3410, rp3440) |
3236 | + * seems rushed, so that many built-in components simply don't work. |
3237 | + * The following quirks disable the serial AUX port and the built-in ATI RV100 |
3238 | + * Radeon 7000 graphics card which both don't have any external connectors and |
3239 | + * thus are useless, and even worse, e.g. the AUX port occupies ttyS0 and as |
3240 | + * such makes those machines the only PARISC machines on which we can't use |
3241 | + * ttyS0 as boot console. |
3242 | + */ |
3243 | +static void quirk_diva_ati_card(struct pci_dev *dev) |
3244 | +{ |
3245 | + if (dev->subsystem_vendor != PCI_VENDOR_ID_HP || |
3246 | + dev->subsystem_device != 0x1292) |
3247 | + return; |
3248 | + |
3249 | + dev_info(&dev->dev, "Hiding Diva built-in ATI card"); |
3250 | + dev->device = 0; |
3251 | +} |
3252 | +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, |
3253 | + quirk_diva_ati_card); |
3254 | + |
3255 | +static void quirk_diva_aux_disable(struct pci_dev *dev) |
3256 | +{ |
3257 | + if (dev->subsystem_vendor != PCI_VENDOR_ID_HP || |
3258 | + dev->subsystem_device != 0x1291) |
3259 | + return; |
3260 | + |
3261 | + dev_info(&dev->dev, "Hiding Diva built-in AUX serial device"); |
3262 | + dev->device = 0; |
3263 | +} |
3264 | +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX, |
3265 | + quirk_diva_aux_disable); |
3266 | diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c |
3267 | index 11bd267fc137..bb0927de79dd 100644 |
3268 | --- a/drivers/pci/pci-driver.c |
3269 | +++ b/drivers/pci/pci-driver.c |
3270 | @@ -968,7 +968,12 @@ static int pci_pm_thaw_noirq(struct device *dev) |
3271 | if (pci_has_legacy_pm_support(pci_dev)) |
3272 | return pci_legacy_resume_early(dev); |
3273 | |
3274 | - pci_update_current_state(pci_dev, PCI_D0); |
3275 | + /* |
3276 | + * pci_restore_state() requires the device to be in D0 (because of MSI |
3277 | + * restoration among other things), so force it into D0 in case the |
3278 | + * driver's "freeze" callbacks put it into a low-power state directly. |
3279 | + */ |
3280 | + pci_set_power_state(pci_dev, PCI_D0); |
3281 | pci_restore_state(pci_dev); |
3282 | |
3283 | if (drv && drv->pm && drv->pm->thaw_noirq) |
3284 | diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c |
3285 | index fadbca907c7c..0907531a02ca 100644 |
3286 | --- a/drivers/pinctrl/intel/pinctrl-cherryview.c |
3287 | +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c |
3288 | @@ -1620,6 +1620,22 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) |
3289 | clear_bit(i, chip->irq_valid_mask); |
3290 | } |
3291 | |
3292 | + /* |
3293 | + * The same set of machines in chv_no_valid_mask[] have incorrectly |
3294 | + * configured GPIOs that generate spurious interrupts so we use |
3295 | + * this same list to apply another quirk for them. |
3296 | + * |
3297 | + * See also https://bugzilla.kernel.org/show_bug.cgi?id=197953. |
3298 | + */ |
3299 | + if (!need_valid_mask) { |
3300 | + /* |
3301 | + * Mask all interrupts the community is able to generate |
3302 | + * but leave the ones that can only generate GPEs unmasked. |
3303 | + */ |
3304 | + chv_writel(GENMASK(31, pctrl->community->nirqs), |
3305 | + pctrl->regs + CHV_INTMASK); |
3306 | + } |
3307 | + |
3308 | /* Clear all interrupts */ |
3309 | chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); |
3310 | |
3311 | diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c |
3312 | index 568e1c65aa82..fe3fa1e8517a 100644 |
3313 | --- a/drivers/spi/spi-armada-3700.c |
3314 | +++ b/drivers/spi/spi-armada-3700.c |
3315 | @@ -79,6 +79,7 @@ |
3316 | #define A3700_SPI_BYTE_LEN BIT(5) |
3317 | #define A3700_SPI_CLK_PRESCALE BIT(0) |
3318 | #define A3700_SPI_CLK_PRESCALE_MASK (0x1f) |
3319 | +#define A3700_SPI_CLK_EVEN_OFFS (0x10) |
3320 | |
3321 | #define A3700_SPI_WFIFO_THRS_BIT 28 |
3322 | #define A3700_SPI_RFIFO_THRS_BIT 24 |
3323 | @@ -220,6 +221,13 @@ static void a3700_spi_clock_set(struct a3700_spi *a3700_spi, |
3324 | |
3325 | prescale = DIV_ROUND_UP(clk_get_rate(a3700_spi->clk), speed_hz); |
3326 | |
3327 | + /* For prescaler values over 15, we can only set it by steps of 2. |
3328 | + * Starting from A3700_SPI_CLK_EVEN_OFFS, we set values from 0 up to |
3329 | + * 30. We only use this range from 16 to 30. |
3330 | + */ |
3331 | + if (prescale > 15) |
3332 | + prescale = A3700_SPI_CLK_EVEN_OFFS + DIV_ROUND_UP(prescale, 2); |
3333 | + |
3334 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); |
3335 | val = val & ~A3700_SPI_CLK_PRESCALE_MASK; |
3336 | |
3337 | diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c |
3338 | index bc7100b93dfc..e0b9fe1d0e37 100644 |
3339 | --- a/drivers/spi/spi-xilinx.c |
3340 | +++ b/drivers/spi/spi-xilinx.c |
3341 | @@ -271,6 +271,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) |
3342 | while (remaining_words) { |
3343 | int n_words, tx_words, rx_words; |
3344 | u32 sr; |
3345 | + int stalled; |
3346 | |
3347 | n_words = min(remaining_words, xspi->buffer_size); |
3348 | |
3349 | @@ -299,7 +300,17 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) |
3350 | |
3351 | /* Read out all the data from the Rx FIFO */ |
3352 | rx_words = n_words; |
3353 | + stalled = 10; |
3354 | while (rx_words) { |
3355 | + if (rx_words == n_words && !(stalled--) && |
3356 | + !(sr & XSPI_SR_TX_EMPTY_MASK) && |
3357 | + (sr & XSPI_SR_RX_EMPTY_MASK)) { |
3358 | + dev_err(&spi->dev, |
3359 | + "Detected stall. Check C_SPI_MODE and C_SPI_MEMORY\n"); |
3360 | + xspi_init_hw(xspi); |
3361 | + return -EIO; |
3362 | + } |
3363 | + |
3364 | if ((sr & XSPI_SR_TX_EMPTY_MASK) && (rx_words > 1)) { |
3365 | xilinx_spi_rx(xspi); |
3366 | rx_words--; |
3367 | diff --git a/include/asm-generic/mm_hooks.h b/include/asm-generic/mm_hooks.h |
3368 | index ea189d88a3cc..8ac4e68a12f0 100644 |
3369 | --- a/include/asm-generic/mm_hooks.h |
3370 | +++ b/include/asm-generic/mm_hooks.h |
3371 | @@ -7,9 +7,10 @@ |
3372 | #ifndef _ASM_GENERIC_MM_HOOKS_H |
3373 | #define _ASM_GENERIC_MM_HOOKS_H |
3374 | |
3375 | -static inline void arch_dup_mmap(struct mm_struct *oldmm, |
3376 | - struct mm_struct *mm) |
3377 | +static inline int arch_dup_mmap(struct mm_struct *oldmm, |
3378 | + struct mm_struct *mm) |
3379 | { |
3380 | + return 0; |
3381 | } |
3382 | |
3383 | static inline void arch_exit_mmap(struct mm_struct *mm) |
3384 | diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h |
3385 | index 1ac457511f4e..045a7f52ab3a 100644 |
3386 | --- a/include/asm-generic/pgtable.h |
3387 | +++ b/include/asm-generic/pgtable.h |
3388 | @@ -1025,6 +1025,11 @@ static inline int pmd_clear_huge(pmd_t *pmd) |
3389 | struct file; |
3390 | int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, |
3391 | unsigned long size, pgprot_t *vma_prot); |
3392 | + |
3393 | +#ifndef CONFIG_X86_ESPFIX64 |
3394 | +static inline void init_espfix_bsp(void) { } |
3395 | +#endif |
3396 | + |
3397 | #endif /* !__ASSEMBLY__ */ |
3398 | |
3399 | #ifndef io_remap_pfn_range |
3400 | diff --git a/include/crypto/mcryptd.h b/include/crypto/mcryptd.h |
3401 | index cceafa01f907..b67404fc4b34 100644 |
3402 | --- a/include/crypto/mcryptd.h |
3403 | +++ b/include/crypto/mcryptd.h |
3404 | @@ -27,6 +27,7 @@ static inline struct mcryptd_ahash *__mcryptd_ahash_cast( |
3405 | |
3406 | struct mcryptd_cpu_queue { |
3407 | struct crypto_queue queue; |
3408 | + spinlock_t q_lock; |
3409 | struct work_struct work; |
3410 | }; |
3411 | |
3412 | diff --git a/include/linux/bio.h b/include/linux/bio.h |
3413 | index 275c91c99516..45f00dd6323c 100644 |
3414 | --- a/include/linux/bio.h |
3415 | +++ b/include/linux/bio.h |
3416 | @@ -504,6 +504,8 @@ extern unsigned int bvec_nr_vecs(unsigned short idx); |
3417 | |
3418 | #define bio_set_dev(bio, bdev) \ |
3419 | do { \ |
3420 | + if ((bio)->bi_disk != (bdev)->bd_disk) \ |
3421 | + bio_clear_flag(bio, BIO_THROTTLED);\ |
3422 | (bio)->bi_disk = (bdev)->bd_disk; \ |
3423 | (bio)->bi_partno = (bdev)->bd_partno; \ |
3424 | } while (0) |
3425 | diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h |
3426 | index 96ac3815542c..1c8a8a2aedf7 100644 |
3427 | --- a/include/linux/blk_types.h |
3428 | +++ b/include/linux/blk_types.h |
3429 | @@ -50,8 +50,6 @@ struct blk_issue_stat { |
3430 | struct bio { |
3431 | struct bio *bi_next; /* request queue link */ |
3432 | struct gendisk *bi_disk; |
3433 | - u8 bi_partno; |
3434 | - blk_status_t bi_status; |
3435 | unsigned int bi_opf; /* bottom bits req flags, |
3436 | * top bits REQ_OP. Use |
3437 | * accessors. |
3438 | @@ -59,8 +57,8 @@ struct bio { |
3439 | unsigned short bi_flags; /* status, etc and bvec pool number */ |
3440 | unsigned short bi_ioprio; |
3441 | unsigned short bi_write_hint; |
3442 | - |
3443 | - struct bvec_iter bi_iter; |
3444 | + blk_status_t bi_status; |
3445 | + u8 bi_partno; |
3446 | |
3447 | /* Number of segments in this BIO after |
3448 | * physical address coalescing is performed. |
3449 | @@ -74,8 +72,9 @@ struct bio { |
3450 | unsigned int bi_seg_front_size; |
3451 | unsigned int bi_seg_back_size; |
3452 | |
3453 | - atomic_t __bi_remaining; |
3454 | + struct bvec_iter bi_iter; |
3455 | |
3456 | + atomic_t __bi_remaining; |
3457 | bio_end_io_t *bi_end_io; |
3458 | |
3459 | void *bi_private; |
3460 | diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h |
3461 | index 8da66379f7ea..fd47bd96b5d3 100644 |
3462 | --- a/include/linux/blkdev.h |
3463 | +++ b/include/linux/blkdev.h |
3464 | @@ -135,7 +135,7 @@ typedef __u32 __bitwise req_flags_t; |
3465 | struct request { |
3466 | struct list_head queuelist; |
3467 | union { |
3468 | - call_single_data_t csd; |
3469 | + struct __call_single_data csd; |
3470 | u64 fifo_time; |
3471 | }; |
3472 | |
3473 | diff --git a/init/main.c b/init/main.c |
3474 | index 0ee9c6866ada..8a390f60ec81 100644 |
3475 | --- a/init/main.c |
3476 | +++ b/init/main.c |
3477 | @@ -504,6 +504,8 @@ static void __init mm_init(void) |
3478 | pgtable_init(); |
3479 | vmalloc_init(); |
3480 | ioremap_huge_init(); |
3481 | + /* Should be run before the first non-init thread is created */ |
3482 | + init_espfix_bsp(); |
3483 | } |
3484 | |
3485 | asmlinkage __visible void __init start_kernel(void) |
3486 | @@ -673,10 +675,6 @@ asmlinkage __visible void __init start_kernel(void) |
3487 | #ifdef CONFIG_X86 |
3488 | if (efi_enabled(EFI_RUNTIME_SERVICES)) |
3489 | efi_enter_virtual_mode(); |
3490 | -#endif |
3491 | -#ifdef CONFIG_X86_ESPFIX64 |
3492 | - /* Should be run before the first non-init thread is created */ |
3493 | - init_espfix_bsp(); |
3494 | #endif |
3495 | thread_stack_cache_init(); |
3496 | cred_init(); |
3497 | diff --git a/kernel/fork.c b/kernel/fork.c |
3498 | index 07cc743698d3..500ce64517d9 100644 |
3499 | --- a/kernel/fork.c |
3500 | +++ b/kernel/fork.c |
3501 | @@ -721,8 +721,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, |
3502 | goto out; |
3503 | } |
3504 | /* a new mm has just been created */ |
3505 | - arch_dup_mmap(oldmm, mm); |
3506 | - retval = 0; |
3507 | + retval = arch_dup_mmap(oldmm, mm); |
3508 | out: |
3509 | up_write(&mm->mmap_sem); |
3510 | flush_tlb_mm(oldmm); |
3511 | diff --git a/net/ipv6/route.c b/net/ipv6/route.c |
3512 | index 76b47682f77f..598efa8cfe25 100644 |
3513 | --- a/net/ipv6/route.c |
3514 | +++ b/net/ipv6/route.c |
3515 | @@ -1055,6 +1055,7 @@ static struct rt6_info *rt6_get_pcpu_route(struct rt6_info *rt) |
3516 | |
3517 | static struct rt6_info *rt6_make_pcpu_route(struct rt6_info *rt) |
3518 | { |
3519 | + struct fib6_table *table = rt->rt6i_table; |
3520 | struct rt6_info *pcpu_rt, *prev, **p; |
3521 | |
3522 | pcpu_rt = ip6_rt_pcpu_alloc(rt); |
3523 | @@ -1065,20 +1066,28 @@ static struct rt6_info *rt6_make_pcpu_route(struct rt6_info *rt) |
3524 | return net->ipv6.ip6_null_entry; |
3525 | } |
3526 | |
3527 | - dst_hold(&pcpu_rt->dst); |
3528 | - p = this_cpu_ptr(rt->rt6i_pcpu); |
3529 | - prev = cmpxchg(p, NULL, pcpu_rt); |
3530 | - if (prev) { |
3531 | - /* If someone did it before us, return prev instead */ |
3532 | - /* release refcnt taken by ip6_rt_pcpu_alloc() */ |
3533 | - dst_release_immediate(&pcpu_rt->dst); |
3534 | - /* release refcnt taken by above dst_hold() */ |
3535 | + read_lock_bh(&table->tb6_lock); |
3536 | + if (rt->rt6i_pcpu) { |
3537 | + p = this_cpu_ptr(rt->rt6i_pcpu); |
3538 | + prev = cmpxchg(p, NULL, pcpu_rt); |
3539 | + if (prev) { |
3540 | + /* If someone did it before us, return prev instead */ |
3541 | + dst_release_immediate(&pcpu_rt->dst); |
3542 | + pcpu_rt = prev; |
3543 | + } |
3544 | + } else { |
3545 | + /* rt has been removed from the fib6 tree |
3546 | + * before we have a chance to acquire the read_lock. |
3547 | + * In this case, don't brother to create a pcpu rt |
3548 | + * since rt is going away anyway. The next |
3549 | + * dst_check() will trigger a re-lookup. |
3550 | + */ |
3551 | dst_release_immediate(&pcpu_rt->dst); |
3552 | - dst_hold(&prev->dst); |
3553 | - pcpu_rt = prev; |
3554 | + pcpu_rt = rt; |
3555 | } |
3556 | - |
3557 | + dst_hold(&pcpu_rt->dst); |
3558 | rt6_dst_from_metrics_check(pcpu_rt); |
3559 | + read_unlock_bh(&table->tb6_lock); |
3560 | return pcpu_rt; |
3561 | } |
3562 | |
3563 | @@ -1168,28 +1177,19 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, |
3564 | if (pcpu_rt) { |
3565 | read_unlock_bh(&table->tb6_lock); |
3566 | } else { |
3567 | - /* atomic_inc_not_zero() is needed when using rcu */ |
3568 | - if (atomic_inc_not_zero(&rt->rt6i_ref)) { |
3569 | - /* We have to do the read_unlock first |
3570 | - * because rt6_make_pcpu_route() may trigger |
3571 | - * ip6_dst_gc() which will take the write_lock. |
3572 | - * |
3573 | - * No dst_hold() on rt is needed because grabbing |
3574 | - * rt->rt6i_ref makes sure rt can't be released. |
3575 | - */ |
3576 | - read_unlock_bh(&table->tb6_lock); |
3577 | - pcpu_rt = rt6_make_pcpu_route(rt); |
3578 | - rt6_release(rt); |
3579 | - } else { |
3580 | - /* rt is already removed from tree */ |
3581 | - read_unlock_bh(&table->tb6_lock); |
3582 | - pcpu_rt = net->ipv6.ip6_null_entry; |
3583 | - dst_hold(&pcpu_rt->dst); |
3584 | - } |
3585 | + /* We have to do the read_unlock first |
3586 | + * because rt6_make_pcpu_route() may trigger |
3587 | + * ip6_dst_gc() which will take the write_lock. |
3588 | + */ |
3589 | + dst_hold(&rt->dst); |
3590 | + read_unlock_bh(&table->tb6_lock); |
3591 | + pcpu_rt = rt6_make_pcpu_route(rt); |
3592 | + dst_release(&rt->dst); |
3593 | } |
3594 | |
3595 | trace_fib6_table_lookup(net, pcpu_rt, table->tb6_id, fl6); |
3596 | return pcpu_rt; |
3597 | + |
3598 | } |
3599 | } |
3600 | EXPORT_SYMBOL_GPL(ip6_pol_route); |
3601 | diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c |
3602 | index b3b353d72527..f055ca10bbc1 100644 |
3603 | --- a/sound/core/rawmidi.c |
3604 | +++ b/sound/core/rawmidi.c |
3605 | @@ -579,15 +579,14 @@ static int snd_rawmidi_info_user(struct snd_rawmidi_substream *substream, |
3606 | return 0; |
3607 | } |
3608 | |
3609 | -int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info) |
3610 | +static int __snd_rawmidi_info_select(struct snd_card *card, |
3611 | + struct snd_rawmidi_info *info) |
3612 | { |
3613 | struct snd_rawmidi *rmidi; |
3614 | struct snd_rawmidi_str *pstr; |
3615 | struct snd_rawmidi_substream *substream; |
3616 | |
3617 | - mutex_lock(®ister_mutex); |
3618 | rmidi = snd_rawmidi_search(card, info->device); |
3619 | - mutex_unlock(®ister_mutex); |
3620 | if (!rmidi) |
3621 | return -ENXIO; |
3622 | if (info->stream < 0 || info->stream > 1) |
3623 | @@ -603,6 +602,16 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info |
3624 | } |
3625 | return -ENXIO; |
3626 | } |
3627 | + |
3628 | +int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info) |
3629 | +{ |
3630 | + int ret; |
3631 | + |
3632 | + mutex_lock(®ister_mutex); |
3633 | + ret = __snd_rawmidi_info_select(card, info); |
3634 | + mutex_unlock(®ister_mutex); |
3635 | + return ret; |
3636 | +} |
3637 | EXPORT_SYMBOL(snd_rawmidi_info_select); |
3638 | |
3639 | static int snd_rawmidi_info_select_user(struct snd_card *card, |
3640 | diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c |
3641 | index c19c81d230bd..b4f1b6e88305 100644 |
3642 | --- a/sound/pci/hda/patch_hdmi.c |
3643 | +++ b/sound/pci/hda/patch_hdmi.c |
3644 | @@ -55,10 +55,11 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); |
3645 | #define is_kabylake(codec) ((codec)->core.vendor_id == 0x8086280b) |
3646 | #define is_geminilake(codec) (((codec)->core.vendor_id == 0x8086280d) || \ |
3647 | ((codec)->core.vendor_id == 0x80862800)) |
3648 | +#define is_cannonlake(codec) ((codec)->core.vendor_id == 0x8086280c) |
3649 | #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \ |
3650 | || is_skylake(codec) || is_broxton(codec) \ |
3651 | - || is_kabylake(codec)) || is_geminilake(codec) |
3652 | - |
3653 | + || is_kabylake(codec)) || is_geminilake(codec) \ |
3654 | + || is_cannonlake(codec) |
3655 | #define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882) |
3656 | #define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883) |
3657 | #define is_valleyview_plus(codec) (is_valleyview(codec) || is_cherryview(codec)) |
3658 | @@ -3841,6 +3842,7 @@ HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_i915_hsw_hdmi), |
3659 | HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_i915_hsw_hdmi), |
3660 | HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_i915_hsw_hdmi), |
3661 | HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_i915_hsw_hdmi), |
3662 | +HDA_CODEC_ENTRY(0x8086280c, "Cannonlake HDMI", patch_i915_glk_hdmi), |
3663 | HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi), |
3664 | HDA_CODEC_ENTRY(0x80862800, "Geminilake HDMI", patch_i915_glk_hdmi), |
3665 | HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), |
3666 | diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c |
3667 | index b076386c8952..9ac4b9076ee2 100644 |
3668 | --- a/sound/pci/hda/patch_realtek.c |
3669 | +++ b/sound/pci/hda/patch_realtek.c |
3670 | @@ -5162,6 +5162,22 @@ static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec, |
3671 | } |
3672 | } |
3673 | |
3674 | +/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */ |
3675 | +static void alc274_fixup_bind_dacs(struct hda_codec *codec, |
3676 | + const struct hda_fixup *fix, int action) |
3677 | +{ |
3678 | + struct alc_spec *spec = codec->spec; |
3679 | + static hda_nid_t preferred_pairs[] = { |
3680 | + 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02, |
3681 | + 0 |
3682 | + }; |
3683 | + |
3684 | + if (action != HDA_FIXUP_ACT_PRE_PROBE) |
3685 | + return; |
3686 | + |
3687 | + spec->gen.preferred_dacs = preferred_pairs; |
3688 | +} |
3689 | + |
3690 | /* for hda_fixup_thinkpad_acpi() */ |
3691 | #include "thinkpad_helper.c" |
3692 | |
3693 | @@ -5279,6 +5295,8 @@ enum { |
3694 | ALC233_FIXUP_LENOVO_MULTI_CODECS, |
3695 | ALC294_FIXUP_LENOVO_MIC_LOCATION, |
3696 | ALC700_FIXUP_INTEL_REFERENCE, |
3697 | + ALC274_FIXUP_DELL_BIND_DACS, |
3698 | + ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, |
3699 | }; |
3700 | |
3701 | static const struct hda_fixup alc269_fixups[] = { |
3702 | @@ -6089,6 +6107,21 @@ static const struct hda_fixup alc269_fixups[] = { |
3703 | {} |
3704 | } |
3705 | }, |
3706 | + [ALC274_FIXUP_DELL_BIND_DACS] = { |
3707 | + .type = HDA_FIXUP_FUNC, |
3708 | + .v.func = alc274_fixup_bind_dacs, |
3709 | + .chained = true, |
3710 | + .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE |
3711 | + }, |
3712 | + [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = { |
3713 | + .type = HDA_FIXUP_PINS, |
3714 | + .v.pins = (const struct hda_pintbl[]) { |
3715 | + { 0x1b, 0x0401102f }, |
3716 | + { } |
3717 | + }, |
3718 | + .chained = true, |
3719 | + .chain_id = ALC274_FIXUP_DELL_BIND_DACS |
3720 | + }, |
3721 | }; |
3722 | |
3723 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
3724 | @@ -6550,7 +6583,7 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { |
3725 | {0x14, 0x90170110}, |
3726 | {0x1b, 0x90a70130}, |
3727 | {0x21, 0x03211020}), |
3728 | - SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, |
3729 | + SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, |
3730 | {0x12, 0xb7a60130}, |
3731 | {0x13, 0xb8a61140}, |
3732 | {0x16, 0x90170110}, |
3733 | diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
3734 | index 4fde4f8d4444..75bce127d768 100644 |
3735 | --- a/sound/usb/mixer.c |
3736 | +++ b/sound/usb/mixer.c |
3737 | @@ -2173,20 +2173,25 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, |
3738 | kctl->private_value = (unsigned long)namelist; |
3739 | kctl->private_free = usb_mixer_selector_elem_free; |
3740 | |
3741 | - nameid = uac_selector_unit_iSelector(desc); |
3742 | + /* check the static mapping table at first */ |
3743 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); |
3744 | - if (len) |
3745 | - ; |
3746 | - else if (nameid) |
3747 | - len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, |
3748 | - sizeof(kctl->id.name)); |
3749 | - else |
3750 | - len = get_term_name(state, &state->oterm, |
3751 | - kctl->id.name, sizeof(kctl->id.name), 0); |
3752 | - |
3753 | if (!len) { |
3754 | - strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name)); |
3755 | + /* no mapping ? */ |
3756 | + /* if iSelector is given, use it */ |
3757 | + nameid = uac_selector_unit_iSelector(desc); |
3758 | + if (nameid) |
3759 | + len = snd_usb_copy_string_desc(state, nameid, |
3760 | + kctl->id.name, |
3761 | + sizeof(kctl->id.name)); |
3762 | + /* ... or pick up the terminal name at next */ |
3763 | + if (!len) |
3764 | + len = get_term_name(state, &state->oterm, |
3765 | + kctl->id.name, sizeof(kctl->id.name), 0); |
3766 | + /* ... or use the fixed string "USB" as the last resort */ |
3767 | + if (!len) |
3768 | + strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name)); |
3769 | |
3770 | + /* and add the proper suffix */ |
3771 | if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) |
3772 | append_ctl_name(kctl, " Clock Source"); |
3773 | else if ((state->oterm.type & 0xff00) == 0x0100) |
3774 | diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c |
3775 | index 20624320b753..8d7db7cd4f88 100644 |
3776 | --- a/sound/usb/quirks.c |
3777 | +++ b/sound/usb/quirks.c |
3778 | @@ -1172,10 +1172,11 @@ static bool is_marantz_denon_dac(unsigned int id) |
3779 | /* TEAC UD-501/UD-503/NT-503 USB DACs need a vendor cmd to switch |
3780 | * between PCM/DOP and native DSD mode |
3781 | */ |
3782 | -static bool is_teac_50X_dac(unsigned int id) |
3783 | +static bool is_teac_dsd_dac(unsigned int id) |
3784 | { |
3785 | switch (id) { |
3786 | case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */ |
3787 | + case USB_ID(0x0644, 0x8044): /* Esoteric D-05X */ |
3788 | return true; |
3789 | } |
3790 | return false; |
3791 | @@ -1208,7 +1209,7 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, |
3792 | break; |
3793 | } |
3794 | mdelay(20); |
3795 | - } else if (is_teac_50X_dac(subs->stream->chip->usb_id)) { |
3796 | + } else if (is_teac_dsd_dac(subs->stream->chip->usb_id)) { |
3797 | /* Vendor mode switch cmd is required. */ |
3798 | switch (fmt->altsetting) { |
3799 | case 3: /* DSD mode (DSD_U32) requested */ |
3800 | @@ -1398,7 +1399,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, |
3801 | } |
3802 | |
3803 | /* TEAC devices with USB DAC functionality */ |
3804 | - if (is_teac_50X_dac(chip->usb_id)) { |
3805 | + if (is_teac_dsd_dac(chip->usb_id)) { |
3806 | if (fp->altsetting == 3) |
3807 | return SNDRV_PCM_FMTBIT_DSD_U32_BE; |
3808 | } |
3809 | diff --git a/tools/objtool/.gitignore b/tools/objtool/.gitignore |
3810 | index d3102c865a95..914cff12899b 100644 |
3811 | --- a/tools/objtool/.gitignore |
3812 | +++ b/tools/objtool/.gitignore |
3813 | @@ -1,3 +1,3 @@ |
3814 | -arch/x86/insn/inat-tables.c |
3815 | +arch/x86/lib/inat-tables.c |
3816 | objtool |
3817 | fixdep |
3818 | diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile |
3819 | index 424b1965d06f..ae0272f9a091 100644 |
3820 | --- a/tools/objtool/Makefile |
3821 | +++ b/tools/objtool/Makefile |
3822 | @@ -7,9 +7,11 @@ ARCH := x86 |
3823 | endif |
3824 | |
3825 | # always use the host compiler |
3826 | -CC = gcc |
3827 | -LD = ld |
3828 | -AR = ar |
3829 | +HOSTCC ?= gcc |
3830 | +HOSTLD ?= ld |
3831 | +CC = $(HOSTCC) |
3832 | +LD = $(HOSTLD) |
3833 | +AR = ar |
3834 | |
3835 | ifeq ($(srctree),) |
3836 | srctree := $(patsubst %/,%,$(dir $(CURDIR))) |
3837 | @@ -25,7 +27,9 @@ OBJTOOL_IN := $(OBJTOOL)-in.o |
3838 | |
3839 | all: $(OBJTOOL) |
3840 | |
3841 | -INCLUDES := -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi |
3842 | +INCLUDES := -I$(srctree)/tools/include \ |
3843 | + -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \ |
3844 | + -I$(srctree)/tools/objtool/arch/$(ARCH)/include |
3845 | WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed |
3846 | CFLAGS += -Wall -Werror $(WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES) |
3847 | LDFLAGS += -lelf $(LIBSUBCMD) |
3848 | @@ -41,22 +45,8 @@ include $(srctree)/tools/build/Makefile.include |
3849 | $(OBJTOOL_IN): fixdep FORCE |
3850 | @$(MAKE) $(build)=objtool |
3851 | |
3852 | -# Busybox's diff doesn't have -I, avoid warning in that case |
3853 | -# |
3854 | $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN) |
3855 | - @(diff -I 2>&1 | grep -q 'option requires an argument' && \ |
3856 | - test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \ |
3857 | - diff -I'^#include' arch/x86/insn/insn.c ../../arch/x86/lib/insn.c >/dev/null && \ |
3858 | - diff -I'^#include' arch/x86/insn/inat.c ../../arch/x86/lib/inat.c >/dev/null && \ |
3859 | - diff arch/x86/insn/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \ |
3860 | - diff arch/x86/insn/gen-insn-attr-x86.awk ../../arch/x86/tools/gen-insn-attr-x86.awk >/dev/null && \ |
3861 | - diff -I'^#include' arch/x86/insn/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \ |
3862 | - diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \ |
3863 | - diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \ |
3864 | - || echo "warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true |
3865 | - @(test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \ |
3866 | - diff ../../arch/x86/include/asm/orc_types.h orc_types.h >/dev/null) \ |
3867 | - || echo "warning: objtool: orc_types.h differs from kernel" >&2 )) || true |
3868 | + @./sync-check.sh |
3869 | $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@ |
3870 | |
3871 | |
3872 | @@ -66,7 +56,7 @@ $(LIBSUBCMD): fixdep FORCE |
3873 | clean: |
3874 | $(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL) |
3875 | $(Q)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete |
3876 | - $(Q)$(RM) $(OUTPUT)arch/x86/insn/inat-tables.c $(OUTPUT)fixdep |
3877 | + $(Q)$(RM) $(OUTPUT)arch/x86/lib/inat-tables.c $(OUTPUT)fixdep |
3878 | |
3879 | FORCE: |
3880 | |
3881 | diff --git a/tools/objtool/arch/x86/Build b/tools/objtool/arch/x86/Build |
3882 | index debbdb0b5c43..b998412c017d 100644 |
3883 | --- a/tools/objtool/arch/x86/Build |
3884 | +++ b/tools/objtool/arch/x86/Build |
3885 | @@ -1,12 +1,12 @@ |
3886 | objtool-y += decode.o |
3887 | |
3888 | -inat_tables_script = arch/x86/insn/gen-insn-attr-x86.awk |
3889 | -inat_tables_maps = arch/x86/insn/x86-opcode-map.txt |
3890 | +inat_tables_script = arch/x86/tools/gen-insn-attr-x86.awk |
3891 | +inat_tables_maps = arch/x86/lib/x86-opcode-map.txt |
3892 | |
3893 | -$(OUTPUT)arch/x86/insn/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) |
3894 | +$(OUTPUT)arch/x86/lib/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) |
3895 | $(call rule_mkdir) |
3896 | $(Q)$(call echo-cmd,gen)$(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ |
3897 | |
3898 | -$(OUTPUT)arch/x86/decode.o: $(OUTPUT)arch/x86/insn/inat-tables.c |
3899 | +$(OUTPUT)arch/x86/decode.o: $(OUTPUT)arch/x86/lib/inat-tables.c |
3900 | |
3901 | -CFLAGS_decode.o += -I$(OUTPUT)arch/x86/insn |
3902 | +CFLAGS_decode.o += -I$(OUTPUT)arch/x86/lib |
3903 | diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c |
3904 | index 34a579f806e3..8acfc47af70e 100644 |
3905 | --- a/tools/objtool/arch/x86/decode.c |
3906 | +++ b/tools/objtool/arch/x86/decode.c |
3907 | @@ -19,9 +19,9 @@ |
3908 | #include <stdlib.h> |
3909 | |
3910 | #define unlikely(cond) (cond) |
3911 | -#include "insn/insn.h" |
3912 | -#include "insn/inat.c" |
3913 | -#include "insn/insn.c" |
3914 | +#include <asm/insn.h> |
3915 | +#include "lib/inat.c" |
3916 | +#include "lib/insn.c" |
3917 | |
3918 | #include "../../elf.h" |
3919 | #include "../../arch.h" |
3920 | diff --git a/tools/objtool/arch/x86/include/asm/inat.h b/tools/objtool/arch/x86/include/asm/inat.h |
3921 | new file mode 100644 |
3922 | index 000000000000..1c78580e58be |
3923 | --- /dev/null |
3924 | +++ b/tools/objtool/arch/x86/include/asm/inat.h |
3925 | @@ -0,0 +1,244 @@ |
3926 | +#ifndef _ASM_X86_INAT_H |
3927 | +#define _ASM_X86_INAT_H |
3928 | +/* |
3929 | + * x86 instruction attributes |
3930 | + * |
3931 | + * Written by Masami Hiramatsu <mhiramat@redhat.com> |
3932 | + * |
3933 | + * This program is free software; you can redistribute it and/or modify |
3934 | + * it under the terms of the GNU General Public License as published by |
3935 | + * the Free Software Foundation; either version 2 of the License, or |
3936 | + * (at your option) any later version. |
3937 | + * |
3938 | + * This program is distributed in the hope that it will be useful, |
3939 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3940 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3941 | + * GNU General Public License for more details. |
3942 | + * |
3943 | + * You should have received a copy of the GNU General Public License |
3944 | + * along with this program; if not, write to the Free Software |
3945 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
3946 | + * |
3947 | + */ |
3948 | +#include <asm/inat_types.h> |
3949 | + |
3950 | +/* |
3951 | + * Internal bits. Don't use bitmasks directly, because these bits are |
3952 | + * unstable. You should use checking functions. |
3953 | + */ |
3954 | + |
3955 | +#define INAT_OPCODE_TABLE_SIZE 256 |
3956 | +#define INAT_GROUP_TABLE_SIZE 8 |
3957 | + |
3958 | +/* Legacy last prefixes */ |
3959 | +#define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */ |
3960 | +#define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */ |
3961 | +#define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */ |
3962 | +/* Other Legacy prefixes */ |
3963 | +#define INAT_PFX_LOCK 4 /* 0xF0 */ |
3964 | +#define INAT_PFX_CS 5 /* 0x2E */ |
3965 | +#define INAT_PFX_DS 6 /* 0x3E */ |
3966 | +#define INAT_PFX_ES 7 /* 0x26 */ |
3967 | +#define INAT_PFX_FS 8 /* 0x64 */ |
3968 | +#define INAT_PFX_GS 9 /* 0x65 */ |
3969 | +#define INAT_PFX_SS 10 /* 0x36 */ |
3970 | +#define INAT_PFX_ADDRSZ 11 /* 0x67 */ |
3971 | +/* x86-64 REX prefix */ |
3972 | +#define INAT_PFX_REX 12 /* 0x4X */ |
3973 | +/* AVX VEX prefixes */ |
3974 | +#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ |
3975 | +#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ |
3976 | +#define INAT_PFX_EVEX 15 /* EVEX prefix */ |
3977 | + |
3978 | +#define INAT_LSTPFX_MAX 3 |
3979 | +#define INAT_LGCPFX_MAX 11 |
3980 | + |
3981 | +/* Immediate size */ |
3982 | +#define INAT_IMM_BYTE 1 |
3983 | +#define INAT_IMM_WORD 2 |
3984 | +#define INAT_IMM_DWORD 3 |
3985 | +#define INAT_IMM_QWORD 4 |
3986 | +#define INAT_IMM_PTR 5 |
3987 | +#define INAT_IMM_VWORD32 6 |
3988 | +#define INAT_IMM_VWORD 7 |
3989 | + |
3990 | +/* Legacy prefix */ |
3991 | +#define INAT_PFX_OFFS 0 |
3992 | +#define INAT_PFX_BITS 4 |
3993 | +#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1) |
3994 | +#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS) |
3995 | +/* Escape opcodes */ |
3996 | +#define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS) |
3997 | +#define INAT_ESC_BITS 2 |
3998 | +#define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1) |
3999 | +#define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS) |
4000 | +/* Group opcodes (1-16) */ |
4001 | +#define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS) |
4002 | +#define INAT_GRP_BITS 5 |
4003 | +#define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1) |
4004 | +#define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS) |
4005 | +/* Immediates */ |
4006 | +#define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS) |
4007 | +#define INAT_IMM_BITS 3 |
4008 | +#define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS) |
4009 | +/* Flags */ |
4010 | +#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS) |
4011 | +#define INAT_MODRM (1 << (INAT_FLAG_OFFS)) |
4012 | +#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1)) |
4013 | +#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2)) |
4014 | +#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3)) |
4015 | +#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) |
4016 | +#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) |
4017 | +#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) |
4018 | +#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) |
4019 | +/* Attribute making macros for attribute tables */ |
4020 | +#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) |
4021 | +#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) |
4022 | +#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM) |
4023 | +#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS) |
4024 | + |
4025 | +/* Identifiers for segment registers */ |
4026 | +#define INAT_SEG_REG_IGNORE 0 |
4027 | +#define INAT_SEG_REG_DEFAULT 1 |
4028 | +#define INAT_SEG_REG_CS 2 |
4029 | +#define INAT_SEG_REG_SS 3 |
4030 | +#define INAT_SEG_REG_DS 4 |
4031 | +#define INAT_SEG_REG_ES 5 |
4032 | +#define INAT_SEG_REG_FS 6 |
4033 | +#define INAT_SEG_REG_GS 7 |
4034 | + |
4035 | +/* Attribute search APIs */ |
4036 | +extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode); |
4037 | +extern int inat_get_last_prefix_id(insn_byte_t last_pfx); |
4038 | +extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, |
4039 | + int lpfx_id, |
4040 | + insn_attr_t esc_attr); |
4041 | +extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm, |
4042 | + int lpfx_id, |
4043 | + insn_attr_t esc_attr); |
4044 | +extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, |
4045 | + insn_byte_t vex_m, |
4046 | + insn_byte_t vex_pp); |
4047 | + |
4048 | +/* Attribute checking functions */ |
4049 | +static inline int inat_is_legacy_prefix(insn_attr_t attr) |
4050 | +{ |
4051 | + attr &= INAT_PFX_MASK; |
4052 | + return attr && attr <= INAT_LGCPFX_MAX; |
4053 | +} |
4054 | + |
4055 | +static inline int inat_is_address_size_prefix(insn_attr_t attr) |
4056 | +{ |
4057 | + return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ; |
4058 | +} |
4059 | + |
4060 | +static inline int inat_is_operand_size_prefix(insn_attr_t attr) |
4061 | +{ |
4062 | + return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ; |
4063 | +} |
4064 | + |
4065 | +static inline int inat_is_rex_prefix(insn_attr_t attr) |
4066 | +{ |
4067 | + return (attr & INAT_PFX_MASK) == INAT_PFX_REX; |
4068 | +} |
4069 | + |
4070 | +static inline int inat_last_prefix_id(insn_attr_t attr) |
4071 | +{ |
4072 | + if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX) |
4073 | + return 0; |
4074 | + else |
4075 | + return attr & INAT_PFX_MASK; |
4076 | +} |
4077 | + |
4078 | +static inline int inat_is_vex_prefix(insn_attr_t attr) |
4079 | +{ |
4080 | + attr &= INAT_PFX_MASK; |
4081 | + return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 || |
4082 | + attr == INAT_PFX_EVEX; |
4083 | +} |
4084 | + |
4085 | +static inline int inat_is_evex_prefix(insn_attr_t attr) |
4086 | +{ |
4087 | + return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX; |
4088 | +} |
4089 | + |
4090 | +static inline int inat_is_vex3_prefix(insn_attr_t attr) |
4091 | +{ |
4092 | + return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3; |
4093 | +} |
4094 | + |
4095 | +static inline int inat_is_escape(insn_attr_t attr) |
4096 | +{ |
4097 | + return attr & INAT_ESC_MASK; |
4098 | +} |
4099 | + |
4100 | +static inline int inat_escape_id(insn_attr_t attr) |
4101 | +{ |
4102 | + return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS; |
4103 | +} |
4104 | + |
4105 | +static inline int inat_is_group(insn_attr_t attr) |
4106 | +{ |
4107 | + return attr & INAT_GRP_MASK; |
4108 | +} |
4109 | + |
4110 | +static inline int inat_group_id(insn_attr_t attr) |
4111 | +{ |
4112 | + return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS; |
4113 | +} |
4114 | + |
4115 | +static inline int inat_group_common_attribute(insn_attr_t attr) |
4116 | +{ |
4117 | + return attr & ~INAT_GRP_MASK; |
4118 | +} |
4119 | + |
4120 | +static inline int inat_has_immediate(insn_attr_t attr) |
4121 | +{ |
4122 | + return attr & INAT_IMM_MASK; |
4123 | +} |
4124 | + |
4125 | +static inline int inat_immediate_size(insn_attr_t attr) |
4126 | +{ |
4127 | + return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS; |
4128 | +} |
4129 | + |
4130 | +static inline int inat_has_modrm(insn_attr_t attr) |
4131 | +{ |
4132 | + return attr & INAT_MODRM; |
4133 | +} |
4134 | + |
4135 | +static inline int inat_is_force64(insn_attr_t attr) |
4136 | +{ |
4137 | + return attr & INAT_FORCE64; |
4138 | +} |
4139 | + |
4140 | +static inline int inat_has_second_immediate(insn_attr_t attr) |
4141 | +{ |
4142 | + return attr & INAT_SCNDIMM; |
4143 | +} |
4144 | + |
4145 | +static inline int inat_has_moffset(insn_attr_t attr) |
4146 | +{ |
4147 | + return attr & INAT_MOFFSET; |
4148 | +} |
4149 | + |
4150 | +static inline int inat_has_variant(insn_attr_t attr) |
4151 | +{ |
4152 | + return attr & INAT_VARIANT; |
4153 | +} |
4154 | + |
4155 | +static inline int inat_accept_vex(insn_attr_t attr) |
4156 | +{ |
4157 | + return attr & INAT_VEXOK; |
4158 | +} |
4159 | + |
4160 | +static inline int inat_must_vex(insn_attr_t attr) |
4161 | +{ |
4162 | + return attr & (INAT_VEXONLY | INAT_EVEXONLY); |
4163 | +} |
4164 | + |
4165 | +static inline int inat_must_evex(insn_attr_t attr) |
4166 | +{ |
4167 | + return attr & INAT_EVEXONLY; |
4168 | +} |
4169 | +#endif |
4170 | diff --git a/tools/objtool/arch/x86/include/asm/inat_types.h b/tools/objtool/arch/x86/include/asm/inat_types.h |
4171 | new file mode 100644 |
4172 | index 000000000000..cb3c20ce39cf |
4173 | --- /dev/null |
4174 | +++ b/tools/objtool/arch/x86/include/asm/inat_types.h |
4175 | @@ -0,0 +1,29 @@ |
4176 | +#ifndef _ASM_X86_INAT_TYPES_H |
4177 | +#define _ASM_X86_INAT_TYPES_H |
4178 | +/* |
4179 | + * x86 instruction attributes |
4180 | + * |
4181 | + * Written by Masami Hiramatsu <mhiramat@redhat.com> |
4182 | + * |
4183 | + * This program is free software; you can redistribute it and/or modify |
4184 | + * it under the terms of the GNU General Public License as published by |
4185 | + * the Free Software Foundation; either version 2 of the License, or |
4186 | + * (at your option) any later version. |
4187 | + * |
4188 | + * This program is distributed in the hope that it will be useful, |
4189 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4190 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4191 | + * GNU General Public License for more details. |
4192 | + * |
4193 | + * You should have received a copy of the GNU General Public License |
4194 | + * along with this program; if not, write to the Free Software |
4195 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
4196 | + * |
4197 | + */ |
4198 | + |
4199 | +/* Instruction attributes */ |
4200 | +typedef unsigned int insn_attr_t; |
4201 | +typedef unsigned char insn_byte_t; |
4202 | +typedef signed int insn_value_t; |
4203 | + |
4204 | +#endif |
4205 | diff --git a/tools/objtool/arch/x86/include/asm/insn.h b/tools/objtool/arch/x86/include/asm/insn.h |
4206 | new file mode 100644 |
4207 | index 000000000000..b3e32b010ab1 |
4208 | --- /dev/null |
4209 | +++ b/tools/objtool/arch/x86/include/asm/insn.h |
4210 | @@ -0,0 +1,211 @@ |
4211 | +#ifndef _ASM_X86_INSN_H |
4212 | +#define _ASM_X86_INSN_H |
4213 | +/* |
4214 | + * x86 instruction analysis |
4215 | + * |
4216 | + * This program is free software; you can redistribute it and/or modify |
4217 | + * it under the terms of the GNU General Public License as published by |
4218 | + * the Free Software Foundation; either version 2 of the License, or |
4219 | + * (at your option) any later version. |
4220 | + * |
4221 | + * This program is distributed in the hope that it will be useful, |
4222 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4223 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4224 | + * GNU General Public License for more details. |
4225 | + * |
4226 | + * You should have received a copy of the GNU General Public License |
4227 | + * along with this program; if not, write to the Free Software |
4228 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
4229 | + * |
4230 | + * Copyright (C) IBM Corporation, 2009 |
4231 | + */ |
4232 | + |
4233 | +/* insn_attr_t is defined in inat.h */ |
4234 | +#include <asm/inat.h> |
4235 | + |
4236 | +struct insn_field { |
4237 | + union { |
4238 | + insn_value_t value; |
4239 | + insn_byte_t bytes[4]; |
4240 | + }; |
4241 | + /* !0 if we've run insn_get_xxx() for this field */ |
4242 | + unsigned char got; |
4243 | + unsigned char nbytes; |
4244 | +}; |
4245 | + |
4246 | +struct insn { |
4247 | + struct insn_field prefixes; /* |
4248 | + * Prefixes |
4249 | + * prefixes.bytes[3]: last prefix |
4250 | + */ |
4251 | + struct insn_field rex_prefix; /* REX prefix */ |
4252 | + struct insn_field vex_prefix; /* VEX prefix */ |
4253 | + struct insn_field opcode; /* |
4254 | + * opcode.bytes[0]: opcode1 |
4255 | + * opcode.bytes[1]: opcode2 |
4256 | + * opcode.bytes[2]: opcode3 |
4257 | + */ |
4258 | + struct insn_field modrm; |
4259 | + struct insn_field sib; |
4260 | + struct insn_field displacement; |
4261 | + union { |
4262 | + struct insn_field immediate; |
4263 | + struct insn_field moffset1; /* for 64bit MOV */ |
4264 | + struct insn_field immediate1; /* for 64bit imm or off16/32 */ |
4265 | + }; |
4266 | + union { |
4267 | + struct insn_field moffset2; /* for 64bit MOV */ |
4268 | + struct insn_field immediate2; /* for 64bit imm or seg16 */ |
4269 | + }; |
4270 | + |
4271 | + insn_attr_t attr; |
4272 | + unsigned char opnd_bytes; |
4273 | + unsigned char addr_bytes; |
4274 | + unsigned char length; |
4275 | + unsigned char x86_64; |
4276 | + |
4277 | + const insn_byte_t *kaddr; /* kernel address of insn to analyze */ |
4278 | + const insn_byte_t *end_kaddr; /* kernel address of last insn in buffer */ |
4279 | + const insn_byte_t *next_byte; |
4280 | +}; |
4281 | + |
4282 | +#define MAX_INSN_SIZE 15 |
4283 | + |
4284 | +#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6) |
4285 | +#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3) |
4286 | +#define X86_MODRM_RM(modrm) ((modrm) & 0x07) |
4287 | + |
4288 | +#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6) |
4289 | +#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3) |
4290 | +#define X86_SIB_BASE(sib) ((sib) & 0x07) |
4291 | + |
4292 | +#define X86_REX_W(rex) ((rex) & 8) |
4293 | +#define X86_REX_R(rex) ((rex) & 4) |
4294 | +#define X86_REX_X(rex) ((rex) & 2) |
4295 | +#define X86_REX_B(rex) ((rex) & 1) |
4296 | + |
4297 | +/* VEX bit flags */ |
4298 | +#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */ |
4299 | +#define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */ |
4300 | +#define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */ |
4301 | +#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ |
4302 | +#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ |
4303 | +/* VEX bit fields */ |
4304 | +#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */ |
4305 | +#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ |
4306 | +#define X86_VEX2_M 1 /* VEX2.M always 1 */ |
4307 | +#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ |
4308 | +#define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */ |
4309 | +#define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */ |
4310 | + |
4311 | +extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64); |
4312 | +extern void insn_get_prefixes(struct insn *insn); |
4313 | +extern void insn_get_opcode(struct insn *insn); |
4314 | +extern void insn_get_modrm(struct insn *insn); |
4315 | +extern void insn_get_sib(struct insn *insn); |
4316 | +extern void insn_get_displacement(struct insn *insn); |
4317 | +extern void insn_get_immediate(struct insn *insn); |
4318 | +extern void insn_get_length(struct insn *insn); |
4319 | + |
4320 | +/* Attribute will be determined after getting ModRM (for opcode groups) */ |
4321 | +static inline void insn_get_attribute(struct insn *insn) |
4322 | +{ |
4323 | + insn_get_modrm(insn); |
4324 | +} |
4325 | + |
4326 | +/* Instruction uses RIP-relative addressing */ |
4327 | +extern int insn_rip_relative(struct insn *insn); |
4328 | + |
4329 | +/* Init insn for kernel text */ |
4330 | +static inline void kernel_insn_init(struct insn *insn, |
4331 | + const void *kaddr, int buf_len) |
4332 | +{ |
4333 | +#ifdef CONFIG_X86_64 |
4334 | + insn_init(insn, kaddr, buf_len, 1); |
4335 | +#else /* CONFIG_X86_32 */ |
4336 | + insn_init(insn, kaddr, buf_len, 0); |
4337 | +#endif |
4338 | +} |
4339 | + |
4340 | +static inline int insn_is_avx(struct insn *insn) |
4341 | +{ |
4342 | + if (!insn->prefixes.got) |
4343 | + insn_get_prefixes(insn); |
4344 | + return (insn->vex_prefix.value != 0); |
4345 | +} |
4346 | + |
4347 | +static inline int insn_is_evex(struct insn *insn) |
4348 | +{ |
4349 | + if (!insn->prefixes.got) |
4350 | + insn_get_prefixes(insn); |
4351 | + return (insn->vex_prefix.nbytes == 4); |
4352 | +} |
4353 | + |
4354 | +/* Ensure this instruction is decoded completely */ |
4355 | +static inline int insn_complete(struct insn *insn) |
4356 | +{ |
4357 | + return insn->opcode.got && insn->modrm.got && insn->sib.got && |
4358 | + insn->displacement.got && insn->immediate.got; |
4359 | +} |
4360 | + |
4361 | +static inline insn_byte_t insn_vex_m_bits(struct insn *insn) |
4362 | +{ |
4363 | + if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ |
4364 | + return X86_VEX2_M; |
4365 | + else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */ |
4366 | + return X86_VEX3_M(insn->vex_prefix.bytes[1]); |
4367 | + else /* EVEX */ |
4368 | + return X86_EVEX_M(insn->vex_prefix.bytes[1]); |
4369 | +} |
4370 | + |
4371 | +static inline insn_byte_t insn_vex_p_bits(struct insn *insn) |
4372 | +{ |
4373 | + if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ |
4374 | + return X86_VEX_P(insn->vex_prefix.bytes[1]); |
4375 | + else |
4376 | + return X86_VEX_P(insn->vex_prefix.bytes[2]); |
4377 | +} |
4378 | + |
4379 | +/* Get the last prefix id from last prefix or VEX prefix */ |
4380 | +static inline int insn_last_prefix_id(struct insn *insn) |
4381 | +{ |
4382 | + if (insn_is_avx(insn)) |
4383 | + return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */ |
4384 | + |
4385 | + if (insn->prefixes.bytes[3]) |
4386 | + return inat_get_last_prefix_id(insn->prefixes.bytes[3]); |
4387 | + |
4388 | + return 0; |
4389 | +} |
4390 | + |
4391 | +/* Offset of each field from kaddr */ |
4392 | +static inline int insn_offset_rex_prefix(struct insn *insn) |
4393 | +{ |
4394 | + return insn->prefixes.nbytes; |
4395 | +} |
4396 | +static inline int insn_offset_vex_prefix(struct insn *insn) |
4397 | +{ |
4398 | + return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes; |
4399 | +} |
4400 | +static inline int insn_offset_opcode(struct insn *insn) |
4401 | +{ |
4402 | + return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes; |
4403 | +} |
4404 | +static inline int insn_offset_modrm(struct insn *insn) |
4405 | +{ |
4406 | + return insn_offset_opcode(insn) + insn->opcode.nbytes; |
4407 | +} |
4408 | +static inline int insn_offset_sib(struct insn *insn) |
4409 | +{ |
4410 | + return insn_offset_modrm(insn) + insn->modrm.nbytes; |
4411 | +} |
4412 | +static inline int insn_offset_displacement(struct insn *insn) |
4413 | +{ |
4414 | + return insn_offset_sib(insn) + insn->sib.nbytes; |
4415 | +} |
4416 | +static inline int insn_offset_immediate(struct insn *insn) |
4417 | +{ |
4418 | + return insn_offset_displacement(insn) + insn->displacement.nbytes; |
4419 | +} |
4420 | + |
4421 | +#endif /* _ASM_X86_INSN_H */ |
4422 | diff --git a/tools/objtool/arch/x86/include/asm/orc_types.h b/tools/objtool/arch/x86/include/asm/orc_types.h |
4423 | new file mode 100644 |
4424 | index 000000000000..9c9dc579bd7d |
4425 | --- /dev/null |
4426 | +++ b/tools/objtool/arch/x86/include/asm/orc_types.h |
4427 | @@ -0,0 +1,107 @@ |
4428 | +/* |
4429 | + * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com> |
4430 | + * |
4431 | + * This program is free software; you can redistribute it and/or |
4432 | + * modify it under the terms of the GNU General Public License |
4433 | + * as published by the Free Software Foundation; either version 2 |
4434 | + * of the License, or (at your option) any later version. |
4435 | + * |
4436 | + * This program is distributed in the hope that it will be useful, |
4437 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4438 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4439 | + * GNU General Public License for more details. |
4440 | + * |
4441 | + * You should have received a copy of the GNU General Public License |
4442 | + * along with this program; if not, see <http://www.gnu.org/licenses/>. |
4443 | + */ |
4444 | + |
4445 | +#ifndef _ORC_TYPES_H |
4446 | +#define _ORC_TYPES_H |
4447 | + |
4448 | +#include <linux/types.h> |
4449 | +#include <linux/compiler.h> |
4450 | + |
4451 | +/* |
4452 | + * The ORC_REG_* registers are base registers which are used to find other |
4453 | + * registers on the stack. |
4454 | + * |
4455 | + * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the |
4456 | + * address of the previous frame: the caller's SP before it called the current |
4457 | + * function. |
4458 | + * |
4459 | + * ORC_REG_UNDEFINED means the corresponding register's value didn't change in |
4460 | + * the current frame. |
4461 | + * |
4462 | + * The most commonly used base registers are SP and BP -- which the previous SP |
4463 | + * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is |
4464 | + * usually based on. |
4465 | + * |
4466 | + * The rest of the base registers are needed for special cases like entry code |
4467 | + * and GCC realigned stacks. |
4468 | + */ |
4469 | +#define ORC_REG_UNDEFINED 0 |
4470 | +#define ORC_REG_PREV_SP 1 |
4471 | +#define ORC_REG_DX 2 |
4472 | +#define ORC_REG_DI 3 |
4473 | +#define ORC_REG_BP 4 |
4474 | +#define ORC_REG_SP 5 |
4475 | +#define ORC_REG_R10 6 |
4476 | +#define ORC_REG_R13 7 |
4477 | +#define ORC_REG_BP_INDIRECT 8 |
4478 | +#define ORC_REG_SP_INDIRECT 9 |
4479 | +#define ORC_REG_MAX 15 |
4480 | + |
4481 | +/* |
4482 | + * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the |
4483 | + * caller's SP right before it made the call). Used for all callable |
4484 | + * functions, i.e. all C code and all callable asm functions. |
4485 | + * |
4486 | + * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points |
4487 | + * to a fully populated pt_regs from a syscall, interrupt, or exception. |
4488 | + * |
4489 | + * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset |
4490 | + * points to the iret return frame. |
4491 | + * |
4492 | + * The UNWIND_HINT macros are used only for the unwind_hint struct. They |
4493 | + * aren't used in struct orc_entry due to size and complexity constraints. |
4494 | + * Objtool converts them to real types when it converts the hints to orc |
4495 | + * entries. |
4496 | + */ |
4497 | +#define ORC_TYPE_CALL 0 |
4498 | +#define ORC_TYPE_REGS 1 |
4499 | +#define ORC_TYPE_REGS_IRET 2 |
4500 | +#define UNWIND_HINT_TYPE_SAVE 3 |
4501 | +#define UNWIND_HINT_TYPE_RESTORE 4 |
4502 | + |
4503 | +#ifndef __ASSEMBLY__ |
4504 | +/* |
4505 | + * This struct is more or less a vastly simplified version of the DWARF Call |
4506 | + * Frame Information standard. It contains only the necessary parts of DWARF |
4507 | + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the |
4508 | + * unwinder how to find the previous SP and BP (and sometimes entry regs) on |
4509 | + * the stack for a given code address. Each instance of the struct corresponds |
4510 | + * to one or more code locations. |
4511 | + */ |
4512 | +struct orc_entry { |
4513 | + s16 sp_offset; |
4514 | + s16 bp_offset; |
4515 | + unsigned sp_reg:4; |
4516 | + unsigned bp_reg:4; |
4517 | + unsigned type:2; |
4518 | +} __packed; |
4519 | + |
4520 | +/* |
4521 | + * This struct is used by asm and inline asm code to manually annotate the |
4522 | + * location of registers on the stack for the ORC unwinder. |
4523 | + * |
4524 | + * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*. |
4525 | + */ |
4526 | +struct unwind_hint { |
4527 | + u32 ip; |
4528 | + s16 sp_offset; |
4529 | + u8 sp_reg; |
4530 | + u8 type; |
4531 | +}; |
4532 | +#endif /* __ASSEMBLY__ */ |
4533 | + |
4534 | +#endif /* _ORC_TYPES_H */ |
4535 | diff --git a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk |
4536 | deleted file mode 100644 |
4537 | index b02a36b2c14f..000000000000 |
4538 | --- a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk |
4539 | +++ /dev/null |
4540 | @@ -1,393 +0,0 @@ |
4541 | -#!/bin/awk -f |
4542 | -# SPDX-License-Identifier: GPL-2.0 |
4543 | -# gen-insn-attr-x86.awk: Instruction attribute table generator |
4544 | -# Written by Masami Hiramatsu <mhiramat@redhat.com> |
4545 | -# |
4546 | -# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c |
4547 | - |
4548 | -# Awk implementation sanity check |
4549 | -function check_awk_implement() { |
4550 | - if (sprintf("%x", 0) != "0") |
4551 | - return "Your awk has a printf-format problem." |
4552 | - return "" |
4553 | -} |
4554 | - |
4555 | -# Clear working vars |
4556 | -function clear_vars() { |
4557 | - delete table |
4558 | - delete lptable2 |
4559 | - delete lptable1 |
4560 | - delete lptable3 |
4561 | - eid = -1 # escape id |
4562 | - gid = -1 # group id |
4563 | - aid = -1 # AVX id |
4564 | - tname = "" |
4565 | -} |
4566 | - |
4567 | -BEGIN { |
4568 | - # Implementation error checking |
4569 | - awkchecked = check_awk_implement() |
4570 | - if (awkchecked != "") { |
4571 | - print "Error: " awkchecked > "/dev/stderr" |
4572 | - print "Please try to use gawk." > "/dev/stderr" |
4573 | - exit 1 |
4574 | - } |
4575 | - |
4576 | - # Setup generating tables |
4577 | - print "/* x86 opcode map generated from x86-opcode-map.txt */" |
4578 | - print "/* Do not change this code. */\n" |
4579 | - ggid = 1 |
4580 | - geid = 1 |
4581 | - gaid = 0 |
4582 | - delete etable |
4583 | - delete gtable |
4584 | - delete atable |
4585 | - |
4586 | - opnd_expr = "^[A-Za-z/]" |
4587 | - ext_expr = "^\\(" |
4588 | - sep_expr = "^\\|$" |
4589 | - group_expr = "^Grp[0-9A-Za-z]+" |
4590 | - |
4591 | - imm_expr = "^[IJAOL][a-z]" |
4592 | - imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" |
4593 | - imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" |
4594 | - imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)" |
4595 | - imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)" |
4596 | - imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)" |
4597 | - imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)" |
4598 | - imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" |
4599 | - imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" |
4600 | - imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)" |
4601 | - imm_flag["Ob"] = "INAT_MOFFSET" |
4602 | - imm_flag["Ov"] = "INAT_MOFFSET" |
4603 | - imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" |
4604 | - |
4605 | - modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" |
4606 | - force64_expr = "\\([df]64\\)" |
4607 | - rex_expr = "^REX(\\.[XRWB]+)*" |
4608 | - fpu_expr = "^ESC" # TODO |
4609 | - |
4610 | - lprefix1_expr = "\\((66|!F3)\\)" |
4611 | - lprefix2_expr = "\\(F3\\)" |
4612 | - lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)" |
4613 | - lprefix_expr = "\\((66|F2|F3)\\)" |
4614 | - max_lprefix = 4 |
4615 | - |
4616 | - # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript |
4617 | - # accepts VEX prefix |
4618 | - vexok_opcode_expr = "^[vk].*" |
4619 | - vexok_expr = "\\(v1\\)" |
4620 | - # All opcodes with (v) superscript supports *only* VEX prefix |
4621 | - vexonly_expr = "\\(v\\)" |
4622 | - # All opcodes with (ev) superscript supports *only* EVEX prefix |
4623 | - evexonly_expr = "\\(ev\\)" |
4624 | - |
4625 | - prefix_expr = "\\(Prefix\\)" |
4626 | - prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" |
4627 | - prefix_num["REPNE"] = "INAT_PFX_REPNE" |
4628 | - prefix_num["REP/REPE"] = "INAT_PFX_REPE" |
4629 | - prefix_num["XACQUIRE"] = "INAT_PFX_REPNE" |
4630 | - prefix_num["XRELEASE"] = "INAT_PFX_REPE" |
4631 | - prefix_num["LOCK"] = "INAT_PFX_LOCK" |
4632 | - prefix_num["SEG=CS"] = "INAT_PFX_CS" |
4633 | - prefix_num["SEG=DS"] = "INAT_PFX_DS" |
4634 | - prefix_num["SEG=ES"] = "INAT_PFX_ES" |
4635 | - prefix_num["SEG=FS"] = "INAT_PFX_FS" |
4636 | - prefix_num["SEG=GS"] = "INAT_PFX_GS" |
4637 | - prefix_num["SEG=SS"] = "INAT_PFX_SS" |
4638 | - prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" |
4639 | - prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" |
4640 | - prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" |
4641 | - prefix_num["EVEX"] = "INAT_PFX_EVEX" |
4642 | - |
4643 | - clear_vars() |
4644 | -} |
4645 | - |
4646 | -function semantic_error(msg) { |
4647 | - print "Semantic error at " NR ": " msg > "/dev/stderr" |
4648 | - exit 1 |
4649 | -} |
4650 | - |
4651 | -function debug(msg) { |
4652 | - print "DEBUG: " msg |
4653 | -} |
4654 | - |
4655 | -function array_size(arr, i,c) { |
4656 | - c = 0 |
4657 | - for (i in arr) |
4658 | - c++ |
4659 | - return c |
4660 | -} |
4661 | - |
4662 | -/^Table:/ { |
4663 | - print "/* " $0 " */" |
4664 | - if (tname != "") |
4665 | - semantic_error("Hit Table: before EndTable:."); |
4666 | -} |
4667 | - |
4668 | -/^Referrer:/ { |
4669 | - if (NF != 1) { |
4670 | - # escape opcode table |
4671 | - ref = "" |
4672 | - for (i = 2; i <= NF; i++) |
4673 | - ref = ref $i |
4674 | - eid = escape[ref] |
4675 | - tname = sprintf("inat_escape_table_%d", eid) |
4676 | - } |
4677 | -} |
4678 | - |
4679 | -/^AVXcode:/ { |
4680 | - if (NF != 1) { |
4681 | - # AVX/escape opcode table |
4682 | - aid = $2 |
4683 | - if (gaid <= aid) |
4684 | - gaid = aid + 1 |
4685 | - if (tname == "") # AVX only opcode table |
4686 | - tname = sprintf("inat_avx_table_%d", $2) |
4687 | - } |
4688 | - if (aid == -1 && eid == -1) # primary opcode table |
4689 | - tname = "inat_primary_table" |
4690 | -} |
4691 | - |
4692 | -/^GrpTable:/ { |
4693 | - print "/* " $0 " */" |
4694 | - if (!($2 in group)) |
4695 | - semantic_error("No group: " $2 ) |
4696 | - gid = group[$2] |
4697 | - tname = "inat_group_table_" gid |
4698 | -} |
4699 | - |
4700 | -function print_table(tbl,name,fmt,n) |
4701 | -{ |
4702 | - print "const insn_attr_t " name " = {" |
4703 | - for (i = 0; i < n; i++) { |
4704 | - id = sprintf(fmt, i) |
4705 | - if (tbl[id]) |
4706 | - print " [" id "] = " tbl[id] "," |
4707 | - } |
4708 | - print "};" |
4709 | -} |
4710 | - |
4711 | -/^EndTable/ { |
4712 | - if (gid != -1) { |
4713 | - # print group tables |
4714 | - if (array_size(table) != 0) { |
4715 | - print_table(table, tname "[INAT_GROUP_TABLE_SIZE]", |
4716 | - "0x%x", 8) |
4717 | - gtable[gid,0] = tname |
4718 | - } |
4719 | - if (array_size(lptable1) != 0) { |
4720 | - print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]", |
4721 | - "0x%x", 8) |
4722 | - gtable[gid,1] = tname "_1" |
4723 | - } |
4724 | - if (array_size(lptable2) != 0) { |
4725 | - print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]", |
4726 | - "0x%x", 8) |
4727 | - gtable[gid,2] = tname "_2" |
4728 | - } |
4729 | - if (array_size(lptable3) != 0) { |
4730 | - print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]", |
4731 | - "0x%x", 8) |
4732 | - gtable[gid,3] = tname "_3" |
4733 | - } |
4734 | - } else { |
4735 | - # print primary/escaped tables |
4736 | - if (array_size(table) != 0) { |
4737 | - print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]", |
4738 | - "0x%02x", 256) |
4739 | - etable[eid,0] = tname |
4740 | - if (aid >= 0) |
4741 | - atable[aid,0] = tname |
4742 | - } |
4743 | - if (array_size(lptable1) != 0) { |
4744 | - print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]", |
4745 | - "0x%02x", 256) |
4746 | - etable[eid,1] = tname "_1" |
4747 | - if (aid >= 0) |
4748 | - atable[aid,1] = tname "_1" |
4749 | - } |
4750 | - if (array_size(lptable2) != 0) { |
4751 | - print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]", |
4752 | - "0x%02x", 256) |
4753 | - etable[eid,2] = tname "_2" |
4754 | - if (aid >= 0) |
4755 | - atable[aid,2] = tname "_2" |
4756 | - } |
4757 | - if (array_size(lptable3) != 0) { |
4758 | - print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]", |
4759 | - "0x%02x", 256) |
4760 | - etable[eid,3] = tname "_3" |
4761 | - if (aid >= 0) |
4762 | - atable[aid,3] = tname "_3" |
4763 | - } |
4764 | - } |
4765 | - print "" |
4766 | - clear_vars() |
4767 | -} |
4768 | - |
4769 | -function add_flags(old,new) { |
4770 | - if (old && new) |
4771 | - return old " | " new |
4772 | - else if (old) |
4773 | - return old |
4774 | - else |
4775 | - return new |
4776 | -} |
4777 | - |
4778 | -# convert operands to flags. |
4779 | -function convert_operands(count,opnd, i,j,imm,mod) |
4780 | -{ |
4781 | - imm = null |
4782 | - mod = null |
4783 | - for (j = 1; j <= count; j++) { |
4784 | - i = opnd[j] |
4785 | - if (match(i, imm_expr) == 1) { |
4786 | - if (!imm_flag[i]) |
4787 | - semantic_error("Unknown imm opnd: " i) |
4788 | - if (imm) { |
4789 | - if (i != "Ib") |
4790 | - semantic_error("Second IMM error") |
4791 | - imm = add_flags(imm, "INAT_SCNDIMM") |
4792 | - } else |
4793 | - imm = imm_flag[i] |
4794 | - } else if (match(i, modrm_expr)) |
4795 | - mod = "INAT_MODRM" |
4796 | - } |
4797 | - return add_flags(imm, mod) |
4798 | -} |
4799 | - |
4800 | -/^[0-9a-f]+\:/ { |
4801 | - if (NR == 1) |
4802 | - next |
4803 | - # get index |
4804 | - idx = "0x" substr($1, 1, index($1,":") - 1) |
4805 | - if (idx in table) |
4806 | - semantic_error("Redefine " idx " in " tname) |
4807 | - |
4808 | - # check if escaped opcode |
4809 | - if ("escape" == $2) { |
4810 | - if ($3 != "#") |
4811 | - semantic_error("No escaped name") |
4812 | - ref = "" |
4813 | - for (i = 4; i <= NF; i++) |
4814 | - ref = ref $i |
4815 | - if (ref in escape) |
4816 | - semantic_error("Redefine escape (" ref ")") |
4817 | - escape[ref] = geid |
4818 | - geid++ |
4819 | - table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")" |
4820 | - next |
4821 | - } |
4822 | - |
4823 | - variant = null |
4824 | - # converts |
4825 | - i = 2 |
4826 | - while (i <= NF) { |
4827 | - opcode = $(i++) |
4828 | - delete opnds |
4829 | - ext = null |
4830 | - flags = null |
4831 | - opnd = null |
4832 | - # parse one opcode |
4833 | - if (match($i, opnd_expr)) { |
4834 | - opnd = $i |
4835 | - count = split($(i++), opnds, ",") |
4836 | - flags = convert_operands(count, opnds) |
4837 | - } |
4838 | - if (match($i, ext_expr)) |
4839 | - ext = $(i++) |
4840 | - if (match($i, sep_expr)) |
4841 | - i++ |
4842 | - else if (i < NF) |
4843 | - semantic_error($i " is not a separator") |
4844 | - |
4845 | - # check if group opcode |
4846 | - if (match(opcode, group_expr)) { |
4847 | - if (!(opcode in group)) { |
4848 | - group[opcode] = ggid |
4849 | - ggid++ |
4850 | - } |
4851 | - flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")") |
4852 | - } |
4853 | - # check force(or default) 64bit |
4854 | - if (match(ext, force64_expr)) |
4855 | - flags = add_flags(flags, "INAT_FORCE64") |
4856 | - |
4857 | - # check REX prefix |
4858 | - if (match(opcode, rex_expr)) |
4859 | - flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)") |
4860 | - |
4861 | - # check coprocessor escape : TODO |
4862 | - if (match(opcode, fpu_expr)) |
4863 | - flags = add_flags(flags, "INAT_MODRM") |
4864 | - |
4865 | - # check VEX codes |
4866 | - if (match(ext, evexonly_expr)) |
4867 | - flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") |
4868 | - else if (match(ext, vexonly_expr)) |
4869 | - flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") |
4870 | - else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) |
4871 | - flags = add_flags(flags, "INAT_VEXOK") |
4872 | - |
4873 | - # check prefixes |
4874 | - if (match(ext, prefix_expr)) { |
4875 | - if (!prefix_num[opcode]) |
4876 | - semantic_error("Unknown prefix: " opcode) |
4877 | - flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")") |
4878 | - } |
4879 | - if (length(flags) == 0) |
4880 | - continue |
4881 | - # check if last prefix |
4882 | - if (match(ext, lprefix1_expr)) { |
4883 | - lptable1[idx] = add_flags(lptable1[idx],flags) |
4884 | - variant = "INAT_VARIANT" |
4885 | - } |
4886 | - if (match(ext, lprefix2_expr)) { |
4887 | - lptable2[idx] = add_flags(lptable2[idx],flags) |
4888 | - variant = "INAT_VARIANT" |
4889 | - } |
4890 | - if (match(ext, lprefix3_expr)) { |
4891 | - lptable3[idx] = add_flags(lptable3[idx],flags) |
4892 | - variant = "INAT_VARIANT" |
4893 | - } |
4894 | - if (!match(ext, lprefix_expr)){ |
4895 | - table[idx] = add_flags(table[idx],flags) |
4896 | - } |
4897 | - } |
4898 | - if (variant) |
4899 | - table[idx] = add_flags(table[idx],variant) |
4900 | -} |
4901 | - |
4902 | -END { |
4903 | - if (awkchecked != "") |
4904 | - exit 1 |
4905 | - # print escape opcode map's array |
4906 | - print "/* Escape opcode map array */" |
4907 | - print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \ |
4908 | - "[INAT_LSTPFX_MAX + 1] = {" |
4909 | - for (i = 0; i < geid; i++) |
4910 | - for (j = 0; j < max_lprefix; j++) |
4911 | - if (etable[i,j]) |
4912 | - print " ["i"]["j"] = "etable[i,j]"," |
4913 | - print "};\n" |
4914 | - # print group opcode map's array |
4915 | - print "/* Group opcode map array */" |
4916 | - print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\ |
4917 | - "[INAT_LSTPFX_MAX + 1] = {" |
4918 | - for (i = 0; i < ggid; i++) |
4919 | - for (j = 0; j < max_lprefix; j++) |
4920 | - if (gtable[i,j]) |
4921 | - print " ["i"]["j"] = "gtable[i,j]"," |
4922 | - print "};\n" |
4923 | - # print AVX opcode map's array |
4924 | - print "/* AVX opcode map array */" |
4925 | - print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\ |
4926 | - "[INAT_LSTPFX_MAX + 1] = {" |
4927 | - for (i = 0; i < gaid; i++) |
4928 | - for (j = 0; j < max_lprefix; j++) |
4929 | - if (atable[i,j]) |
4930 | - print " ["i"]["j"] = "atable[i,j]"," |
4931 | - print "};" |
4932 | -} |
4933 | - |
4934 | diff --git a/tools/objtool/arch/x86/insn/inat.c b/tools/objtool/arch/x86/insn/inat.c |
4935 | deleted file mode 100644 |
4936 | index e4bf28e6f4c7..000000000000 |
4937 | --- a/tools/objtool/arch/x86/insn/inat.c |
4938 | +++ /dev/null |
4939 | @@ -1,97 +0,0 @@ |
4940 | -/* |
4941 | - * x86 instruction attribute tables |
4942 | - * |
4943 | - * Written by Masami Hiramatsu <mhiramat@redhat.com> |
4944 | - * |
4945 | - * This program is free software; you can redistribute it and/or modify |
4946 | - * it under the terms of the GNU General Public License as published by |
4947 | - * the Free Software Foundation; either version 2 of the License, or |
4948 | - * (at your option) any later version. |
4949 | - * |
4950 | - * This program is distributed in the hope that it will be useful, |
4951 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4952 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4953 | - * GNU General Public License for more details. |
4954 | - * |
4955 | - * You should have received a copy of the GNU General Public License |
4956 | - * along with this program; if not, write to the Free Software |
4957 | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
4958 | - * |
4959 | - */ |
4960 | -#include "insn.h" |
4961 | - |
4962 | -/* Attribute tables are generated from opcode map */ |
4963 | -#include "inat-tables.c" |
4964 | - |
4965 | -/* Attribute search APIs */ |
4966 | -insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode) |
4967 | -{ |
4968 | - return inat_primary_table[opcode]; |
4969 | -} |
4970 | - |
4971 | -int inat_get_last_prefix_id(insn_byte_t last_pfx) |
4972 | -{ |
4973 | - insn_attr_t lpfx_attr; |
4974 | - |
4975 | - lpfx_attr = inat_get_opcode_attribute(last_pfx); |
4976 | - return inat_last_prefix_id(lpfx_attr); |
4977 | -} |
4978 | - |
4979 | -insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id, |
4980 | - insn_attr_t esc_attr) |
4981 | -{ |
4982 | - const insn_attr_t *table; |
4983 | - int n; |
4984 | - |
4985 | - n = inat_escape_id(esc_attr); |
4986 | - |
4987 | - table = inat_escape_tables[n][0]; |
4988 | - if (!table) |
4989 | - return 0; |
4990 | - if (inat_has_variant(table[opcode]) && lpfx_id) { |
4991 | - table = inat_escape_tables[n][lpfx_id]; |
4992 | - if (!table) |
4993 | - return 0; |
4994 | - } |
4995 | - return table[opcode]; |
4996 | -} |
4997 | - |
4998 | -insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id, |
4999 | - insn_attr_t grp_attr) |
5000 | -{ |
5001 | - const insn_attr_t *table; |
5002 | - int n; |
5003 | - |
5004 | - n = inat_group_id(grp_attr); |
5005 | - |
5006 | - table = inat_group_tables[n][0]; |
5007 | - if (!table) |
5008 | - return inat_group_common_attribute(grp_attr); |
5009 | - if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) { |
5010 | - table = inat_group_tables[n][lpfx_id]; |
5011 | - if (!table) |
5012 | - return inat_group_common_attribute(grp_attr); |
5013 | - } |
5014 | - return table[X86_MODRM_REG(modrm)] | |
5015 | - inat_group_common_attribute(grp_attr); |
5016 | -} |
5017 | - |
5018 | -insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m, |
5019 | - insn_byte_t vex_p) |
5020 | -{ |
5021 | - const insn_attr_t *table; |
5022 | - if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX) |
5023 | - return 0; |
5024 | - /* At first, this checks the master table */ |
5025 | - table = inat_avx_tables[vex_m][0]; |
5026 | - if (!table) |
5027 | - return 0; |
5028 | - if (!inat_is_group(table[opcode]) && vex_p) { |
5029 | - /* If this is not a group, get attribute directly */ |
5030 | - table = inat_avx_tables[vex_m][vex_p]; |
5031 | - if (!table) |
5032 | - return 0; |
5033 | - } |
5034 | - return table[opcode]; |
5035 | -} |
5036 | - |
5037 | diff --git a/tools/objtool/arch/x86/insn/inat.h b/tools/objtool/arch/x86/insn/inat.h |
5038 | deleted file mode 100644 |
5039 | index 125ecd2a300d..000000000000 |
5040 | --- a/tools/objtool/arch/x86/insn/inat.h |
5041 | +++ /dev/null |
5042 | @@ -1,234 +0,0 @@ |
5043 | -#ifndef _ASM_X86_INAT_H |
5044 | -#define _ASM_X86_INAT_H |
5045 | -/* |
5046 | - * x86 instruction attributes |
5047 | - * |
5048 | - * Written by Masami Hiramatsu <mhiramat@redhat.com> |
5049 | - * |
5050 | - * This program is free software; you can redistribute it and/or modify |
5051 | - * it under the terms of the GNU General Public License as published by |
5052 | - * the Free Software Foundation; either version 2 of the License, or |
5053 | - * (at your option) any later version. |
5054 | - * |
5055 | - * This program is distributed in the hope that it will be useful, |
5056 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
5057 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
5058 | - * GNU General Public License for more details. |
5059 | - * |
5060 | - * You should have received a copy of the GNU General Public License |
5061 | - * along with this program; if not, write to the Free Software |
5062 | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
5063 | - * |
5064 | - */ |
5065 | -#include "inat_types.h" |
5066 | - |
5067 | -/* |
5068 | - * Internal bits. Don't use bitmasks directly, because these bits are |
5069 | - * unstable. You should use checking functions. |
5070 | - */ |
5071 | - |
5072 | -#define INAT_OPCODE_TABLE_SIZE 256 |
5073 | -#define INAT_GROUP_TABLE_SIZE 8 |
5074 | - |
5075 | -/* Legacy last prefixes */ |
5076 | -#define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */ |
5077 | -#define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */ |
5078 | -#define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */ |
5079 | -/* Other Legacy prefixes */ |
5080 | -#define INAT_PFX_LOCK 4 /* 0xF0 */ |
5081 | -#define INAT_PFX_CS 5 /* 0x2E */ |
5082 | -#define INAT_PFX_DS 6 /* 0x3E */ |
5083 | -#define INAT_PFX_ES 7 /* 0x26 */ |
5084 | -#define INAT_PFX_FS 8 /* 0x64 */ |
5085 | -#define INAT_PFX_GS 9 /* 0x65 */ |
5086 | -#define INAT_PFX_SS 10 /* 0x36 */ |
5087 | -#define INAT_PFX_ADDRSZ 11 /* 0x67 */ |
5088 | -/* x86-64 REX prefix */ |
5089 | -#define INAT_PFX_REX 12 /* 0x4X */ |
5090 | -/* AVX VEX prefixes */ |
5091 | -#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ |
5092 | -#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ |
5093 | -#define INAT_PFX_EVEX 15 /* EVEX prefix */ |
5094 | - |
5095 | -#define INAT_LSTPFX_MAX 3 |
5096 | -#define INAT_LGCPFX_MAX 11 |
5097 | - |
5098 | -/* Immediate size */ |
5099 | -#define INAT_IMM_BYTE 1 |
5100 | -#define INAT_IMM_WORD 2 |
5101 | -#define INAT_IMM_DWORD 3 |
5102 | -#define INAT_IMM_QWORD 4 |
5103 | -#define INAT_IMM_PTR 5 |
5104 | -#define INAT_IMM_VWORD32 6 |
5105 | -#define INAT_IMM_VWORD 7 |
5106 | - |
5107 | -/* Legacy prefix */ |
5108 | -#define INAT_PFX_OFFS 0 |
5109 | -#define INAT_PFX_BITS 4 |
5110 | -#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1) |
5111 | -#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS) |
5112 | -/* Escape opcodes */ |
5113 | -#define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS) |
5114 | -#define INAT_ESC_BITS 2 |
5115 | -#define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1) |
5116 | -#define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS) |
5117 | -/* Group opcodes (1-16) */ |
5118 | -#define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS) |
5119 | -#define INAT_GRP_BITS 5 |
5120 | -#define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1) |
5121 | -#define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS) |
5122 | -/* Immediates */ |
5123 | -#define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS) |
5124 | -#define INAT_IMM_BITS 3 |
5125 | -#define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS) |
5126 | -/* Flags */ |
5127 | -#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS) |
5128 | -#define INAT_MODRM (1 << (INAT_FLAG_OFFS)) |
5129 | -#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1)) |
5130 | -#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2)) |
5131 | -#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3)) |
5132 | -#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) |
5133 | -#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) |
5134 | -#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) |
5135 | -#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) |
5136 | -/* Attribute making macros for attribute tables */ |
5137 | -#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) |
5138 | -#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) |
5139 | -#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM) |
5140 | -#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS) |
5141 | - |
5142 | -/* Attribute search APIs */ |
5143 | -extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode); |
5144 | -extern int inat_get_last_prefix_id(insn_byte_t last_pfx); |
5145 | -extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, |
5146 | - int lpfx_id, |
5147 | - insn_attr_t esc_attr); |
5148 | -extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm, |
5149 | - int lpfx_id, |
5150 | - insn_attr_t esc_attr); |
5151 | -extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, |
5152 | - insn_byte_t vex_m, |
5153 | - insn_byte_t vex_pp); |
5154 | - |
5155 | -/* Attribute checking functions */ |
5156 | -static inline int inat_is_legacy_prefix(insn_attr_t attr) |
5157 | -{ |
5158 | - attr &= INAT_PFX_MASK; |
5159 | - return attr && attr <= INAT_LGCPFX_MAX; |
5160 | -} |
5161 | - |
5162 | -static inline int inat_is_address_size_prefix(insn_attr_t attr) |
5163 | -{ |
5164 | - return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ; |
5165 | -} |
5166 | - |
5167 | -static inline int inat_is_operand_size_prefix(insn_attr_t attr) |
5168 | -{ |
5169 | - return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ; |
5170 | -} |
5171 | - |
5172 | -static inline int inat_is_rex_prefix(insn_attr_t attr) |
5173 | -{ |
5174 | - return (attr & INAT_PFX_MASK) == INAT_PFX_REX; |
5175 | -} |
5176 | - |
5177 | -static inline int inat_last_prefix_id(insn_attr_t attr) |
5178 | -{ |
5179 | - if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX) |
5180 | - return 0; |
5181 | - else |
5182 | - return attr & INAT_PFX_MASK; |
5183 | -} |
5184 | - |
5185 | -static inline int inat_is_vex_prefix(insn_attr_t attr) |
5186 | -{ |
5187 | - attr &= INAT_PFX_MASK; |
5188 | - return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 || |
5189 | - attr == INAT_PFX_EVEX; |
5190 | -} |
5191 | - |
5192 | -static inline int inat_is_evex_prefix(insn_attr_t attr) |
5193 | -{ |
5194 | - return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX; |
5195 | -} |
5196 | - |
5197 | -static inline int inat_is_vex3_prefix(insn_attr_t attr) |
5198 | -{ |
5199 | - return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3; |
5200 | -} |
5201 | - |
5202 | -static inline int inat_is_escape(insn_attr_t attr) |
5203 | -{ |
5204 | - return attr & INAT_ESC_MASK; |
5205 | -} |
5206 | - |
5207 | -static inline int inat_escape_id(insn_attr_t attr) |
5208 | -{ |
5209 | - return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS; |
5210 | -} |
5211 | - |
5212 | -static inline int inat_is_group(insn_attr_t attr) |
5213 | -{ |
5214 | - return attr & INAT_GRP_MASK; |
5215 | -} |
5216 | - |
5217 | -static inline int inat_group_id(insn_attr_t attr) |
5218 | -{ |
5219 | - return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS; |
5220 | -} |
5221 | - |
5222 | -static inline int inat_group_common_attribute(insn_attr_t attr) |
5223 | -{ |
5224 | - return attr & ~INAT_GRP_MASK; |
5225 | -} |
5226 | - |
5227 | -static inline int inat_has_immediate(insn_attr_t attr) |
5228 | -{ |
5229 | - return attr & INAT_IMM_MASK; |
5230 | -} |
5231 | - |
5232 | -static inline int inat_immediate_size(insn_attr_t attr) |
5233 | -{ |
5234 | - return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS; |
5235 | -} |
5236 | - |
5237 | -static inline int inat_has_modrm(insn_attr_t attr) |
5238 | -{ |
5239 | - return attr & INAT_MODRM; |
5240 | -} |
5241 | - |
5242 | -static inline int inat_is_force64(insn_attr_t attr) |
5243 | -{ |
5244 | - return attr & INAT_FORCE64; |
5245 | -} |
5246 | - |
5247 | -static inline int inat_has_second_immediate(insn_attr_t attr) |
5248 | -{ |
5249 | - return attr & INAT_SCNDIMM; |
5250 | -} |
5251 | - |
5252 | -static inline int inat_has_moffset(insn_attr_t attr) |
5253 | -{ |
5254 | - return attr & INAT_MOFFSET; |
5255 | -} |
5256 | - |
5257 | -static inline int inat_has_variant(insn_attr_t attr) |
5258 | -{ |
5259 | - return attr & INAT_VARIANT; |
5260 | -} |
5261 | - |
5262 | -static inline int inat_accept_vex(insn_attr_t attr) |
5263 | -{ |
5264 | - return attr & INAT_VEXOK; |
5265 | -} |
5266 | - |
5267 | -static inline int inat_must_vex(insn_attr_t attr) |
5268 | -{ |
5269 | - return attr & (INAT_VEXONLY | INAT_EVEXONLY); |
5270 | -} |
5271 | - |
5272 | -static inline int inat_must_evex(insn_attr_t attr) |
5273 | -{ |
5274 | - return attr & INAT_EVEXONLY; |
5275 | -} |
5276 | -#endif |
5277 | diff --git a/tools/objtool/arch/x86/insn/inat_types.h b/tools/objtool/arch/x86/insn/inat_types.h |
5278 | deleted file mode 100644 |
5279 | index cb3c20ce39cf..000000000000 |
5280 | --- a/tools/objtool/arch/x86/insn/inat_types.h |
5281 | +++ /dev/null |
5282 | @@ -1,29 +0,0 @@ |
5283 | -#ifndef _ASM_X86_INAT_TYPES_H |
5284 | -#define _ASM_X86_INAT_TYPES_H |
5285 | -/* |
5286 | - * x86 instruction attributes |
5287 | - * |
5288 | - * Written by Masami Hiramatsu <mhiramat@redhat.com> |
5289 | - * |
5290 | - * This program is free software; you can redistribute it and/or modify |
5291 | - * it under the terms of the GNU General Public License as published by |
5292 | - * the Free Software Foundation; either version 2 of the License, or |
5293 | - * (at your option) any later version. |
5294 | - * |
5295 | - * This program is distributed in the hope that it will be useful, |
5296 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
5297 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
5298 | - * GNU General Public License for more details. |
5299 | - * |
5300 | - * You should have received a copy of the GNU General Public License |
5301 | - * along with this program; if not, write to the Free Software |
5302 | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
5303 | - * |
5304 | - */ |
5305 | - |
5306 | -/* Instruction attributes */ |
5307 | -typedef unsigned int insn_attr_t; |
5308 | -typedef unsigned char insn_byte_t; |
5309 | -typedef signed int insn_value_t; |
5310 | - |
5311 | -#endif |
5312 | diff --git a/tools/objtool/arch/x86/insn/insn.c b/tools/objtool/arch/x86/insn/insn.c |
5313 | deleted file mode 100644 |
5314 | index ca983e2bea8b..000000000000 |
5315 | --- a/tools/objtool/arch/x86/insn/insn.c |
5316 | +++ /dev/null |
5317 | @@ -1,606 +0,0 @@ |
5318 | -/* |
5319 | - * x86 instruction analysis |
5320 | - * |
5321 | - * This program is free software; you can redistribute it and/or modify |
5322 | - * it under the terms of the GNU General Public License as published by |
5323 | - * the Free Software Foundation; either version 2 of the License, or |
5324 | - * (at your option) any later version. |
5325 | - * |
5326 | - * This program is distributed in the hope that it will be useful, |
5327 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
5328 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
5329 | - * GNU General Public License for more details. |
5330 | - * |
5331 | - * You should have received a copy of the GNU General Public License |
5332 | - * along with this program; if not, write to the Free Software |
5333 | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
5334 | - * |
5335 | - * Copyright (C) IBM Corporation, 2002, 2004, 2009 |
5336 | - */ |
5337 | - |
5338 | -#ifdef __KERNEL__ |
5339 | -#include <linux/string.h> |
5340 | -#else |
5341 | -#include <string.h> |
5342 | -#endif |
5343 | -#include "inat.h" |
5344 | -#include "insn.h" |
5345 | - |
5346 | -/* Verify next sizeof(t) bytes can be on the same instruction */ |
5347 | -#define validate_next(t, insn, n) \ |
5348 | - ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) |
5349 | - |
5350 | -#define __get_next(t, insn) \ |
5351 | - ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) |
5352 | - |
5353 | -#define __peek_nbyte_next(t, insn, n) \ |
5354 | - ({ t r = *(t*)((insn)->next_byte + n); r; }) |
5355 | - |
5356 | -#define get_next(t, insn) \ |
5357 | - ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) |
5358 | - |
5359 | -#define peek_nbyte_next(t, insn, n) \ |
5360 | - ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); }) |
5361 | - |
5362 | -#define peek_next(t, insn) peek_nbyte_next(t, insn, 0) |
5363 | - |
5364 | -/** |
5365 | - * insn_init() - initialize struct insn |
5366 | - * @insn: &struct insn to be initialized |
5367 | - * @kaddr: address (in kernel memory) of instruction (or copy thereof) |
5368 | - * @x86_64: !0 for 64-bit kernel or 64-bit app |
5369 | - */ |
5370 | -void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64) |
5371 | -{ |
5372 | - /* |
5373 | - * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid |
5374 | - * even if the input buffer is long enough to hold them. |
5375 | - */ |
5376 | - if (buf_len > MAX_INSN_SIZE) |
5377 | - buf_len = MAX_INSN_SIZE; |
5378 | - |
5379 | - memset(insn, 0, sizeof(*insn)); |
5380 | - insn->kaddr = kaddr; |
5381 | - insn->end_kaddr = kaddr + buf_len; |
5382 | - insn->next_byte = kaddr; |
5383 | - insn->x86_64 = x86_64 ? 1 : 0; |
5384 | - insn->opnd_bytes = 4; |
5385 | - if (x86_64) |
5386 | - insn->addr_bytes = 8; |
5387 | - else |
5388 | - insn->addr_bytes = 4; |
5389 | -} |
5390 | - |
5391 | -/** |
5392 | - * insn_get_prefixes - scan x86 instruction prefix bytes |
5393 | - * @insn: &struct insn containing instruction |
5394 | - * |
5395 | - * Populates the @insn->prefixes bitmap, and updates @insn->next_byte |
5396 | - * to point to the (first) opcode. No effect if @insn->prefixes.got |
5397 | - * is already set. |
5398 | - */ |
5399 | -void insn_get_prefixes(struct insn *insn) |
5400 | -{ |
5401 | - struct insn_field *prefixes = &insn->prefixes; |
5402 | - insn_attr_t attr; |
5403 | - insn_byte_t b, lb; |
5404 | - int i, nb; |
5405 | - |
5406 | - if (prefixes->got) |
5407 | - return; |
5408 | - |
5409 | - nb = 0; |
5410 | - lb = 0; |
5411 | - b = peek_next(insn_byte_t, insn); |
5412 | - attr = inat_get_opcode_attribute(b); |
5413 | - while (inat_is_legacy_prefix(attr)) { |
5414 | - /* Skip if same prefix */ |
5415 | - for (i = 0; i < nb; i++) |
5416 | - if (prefixes->bytes[i] == b) |
5417 | - goto found; |
5418 | - if (nb == 4) |
5419 | - /* Invalid instruction */ |
5420 | - break; |
5421 | - prefixes->bytes[nb++] = b; |
5422 | - if (inat_is_address_size_prefix(attr)) { |
5423 | - /* address size switches 2/4 or 4/8 */ |
5424 | - if (insn->x86_64) |
5425 | - insn->addr_bytes ^= 12; |
5426 | - else |
5427 | - insn->addr_bytes ^= 6; |
5428 | - } else if (inat_is_operand_size_prefix(attr)) { |
5429 | - /* oprand size switches 2/4 */ |
5430 | - insn->opnd_bytes ^= 6; |
5431 | - } |
5432 | -found: |
5433 | - prefixes->nbytes++; |
5434 | - insn->next_byte++; |
5435 | - lb = b; |
5436 | - b = peek_next(insn_byte_t, insn); |
5437 | - attr = inat_get_opcode_attribute(b); |
5438 | - } |
5439 | - /* Set the last prefix */ |
5440 | - if (lb && lb != insn->prefixes.bytes[3]) { |
5441 | - if (unlikely(insn->prefixes.bytes[3])) { |
5442 | - /* Swap the last prefix */ |
5443 | - b = insn->prefixes.bytes[3]; |
5444 | - for (i = 0; i < nb; i++) |
5445 | - if (prefixes->bytes[i] == lb) |
5446 | - prefixes->bytes[i] = b; |
5447 | - } |
5448 | - insn->prefixes.bytes[3] = lb; |
5449 | - } |
5450 | - |
5451 | - /* Decode REX prefix */ |
5452 | - if (insn->x86_64) { |
5453 | - b = peek_next(insn_byte_t, insn); |
5454 | - attr = inat_get_opcode_attribute(b); |
5455 | - if (inat_is_rex_prefix(attr)) { |
5456 | - insn->rex_prefix.value = b; |
5457 | - insn->rex_prefix.nbytes = 1; |
5458 | - insn->next_byte++; |
5459 | - if (X86_REX_W(b)) |
5460 | - /* REX.W overrides opnd_size */ |
5461 | - insn->opnd_bytes = 8; |
5462 | - } |
5463 | - } |
5464 | - insn->rex_prefix.got = 1; |
5465 | - |
5466 | - /* Decode VEX prefix */ |
5467 | - b = peek_next(insn_byte_t, insn); |
5468 | - attr = inat_get_opcode_attribute(b); |
5469 | - if (inat_is_vex_prefix(attr)) { |
5470 | - insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1); |
5471 | - if (!insn->x86_64) { |
5472 | - /* |
5473 | - * In 32-bits mode, if the [7:6] bits (mod bits of |
5474 | - * ModRM) on the second byte are not 11b, it is |
5475 | - * LDS or LES or BOUND. |
5476 | - */ |
5477 | - if (X86_MODRM_MOD(b2) != 3) |
5478 | - goto vex_end; |
5479 | - } |
5480 | - insn->vex_prefix.bytes[0] = b; |
5481 | - insn->vex_prefix.bytes[1] = b2; |
5482 | - if (inat_is_evex_prefix(attr)) { |
5483 | - b2 = peek_nbyte_next(insn_byte_t, insn, 2); |
5484 | - insn->vex_prefix.bytes[2] = b2; |
5485 | - b2 = peek_nbyte_next(insn_byte_t, insn, 3); |
5486 | - insn->vex_prefix.bytes[3] = b2; |
5487 | - insn->vex_prefix.nbytes = 4; |
5488 | - insn->next_byte += 4; |
5489 | - if (insn->x86_64 && X86_VEX_W(b2)) |
5490 | - /* VEX.W overrides opnd_size */ |
5491 | - insn->opnd_bytes = 8; |
5492 | - } else if (inat_is_vex3_prefix(attr)) { |
5493 | - b2 = peek_nbyte_next(insn_byte_t, insn, 2); |
5494 | - insn->vex_prefix.bytes[2] = b2; |
5495 | - insn->vex_prefix.nbytes = 3; |
5496 | - insn->next_byte += 3; |
5497 | - if (insn->x86_64 && X86_VEX_W(b2)) |
5498 | - /* VEX.W overrides opnd_size */ |
5499 | - insn->opnd_bytes = 8; |
5500 | - } else { |
5501 | - /* |
5502 | - * For VEX2, fake VEX3-like byte#2. |
5503 | - * Makes it easier to decode vex.W, vex.vvvv, |
5504 | - * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0. |
5505 | - */ |
5506 | - insn->vex_prefix.bytes[2] = b2 & 0x7f; |
5507 | - insn->vex_prefix.nbytes = 2; |
5508 | - insn->next_byte += 2; |
5509 | - } |
5510 | - } |
5511 | -vex_end: |
5512 | - insn->vex_prefix.got = 1; |
5513 | - |
5514 | - prefixes->got = 1; |
5515 | - |
5516 | -err_out: |
5517 | - return; |
5518 | -} |
5519 | - |
5520 | -/** |
5521 | - * insn_get_opcode - collect opcode(s) |
5522 | - * @insn: &struct insn containing instruction |
5523 | - * |
5524 | - * Populates @insn->opcode, updates @insn->next_byte to point past the |
5525 | - * opcode byte(s), and set @insn->attr (except for groups). |
5526 | - * If necessary, first collects any preceding (prefix) bytes. |
5527 | - * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got |
5528 | - * is already 1. |
5529 | - */ |
5530 | -void insn_get_opcode(struct insn *insn) |
5531 | -{ |
5532 | - struct insn_field *opcode = &insn->opcode; |
5533 | - insn_byte_t op; |
5534 | - int pfx_id; |
5535 | - if (opcode->got) |
5536 | - return; |
5537 | - if (!insn->prefixes.got) |
5538 | - insn_get_prefixes(insn); |
5539 | - |
5540 | - /* Get first opcode */ |
5541 | - op = get_next(insn_byte_t, insn); |
5542 | - opcode->bytes[0] = op; |
5543 | - opcode->nbytes = 1; |
5544 | - |
5545 | - /* Check if there is VEX prefix or not */ |
5546 | - if (insn_is_avx(insn)) { |
5547 | - insn_byte_t m, p; |
5548 | - m = insn_vex_m_bits(insn); |
5549 | - p = insn_vex_p_bits(insn); |
5550 | - insn->attr = inat_get_avx_attribute(op, m, p); |
5551 | - if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) || |
5552 | - (!inat_accept_vex(insn->attr) && |
5553 | - !inat_is_group(insn->attr))) |
5554 | - insn->attr = 0; /* This instruction is bad */ |
5555 | - goto end; /* VEX has only 1 byte for opcode */ |
5556 | - } |
5557 | - |
5558 | - insn->attr = inat_get_opcode_attribute(op); |
5559 | - while (inat_is_escape(insn->attr)) { |
5560 | - /* Get escaped opcode */ |
5561 | - op = get_next(insn_byte_t, insn); |
5562 | - opcode->bytes[opcode->nbytes++] = op; |
5563 | - pfx_id = insn_last_prefix_id(insn); |
5564 | - insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr); |
5565 | - } |
5566 | - if (inat_must_vex(insn->attr)) |
5567 | - insn->attr = 0; /* This instruction is bad */ |
5568 | -end: |
5569 | - opcode->got = 1; |
5570 | - |
5571 | -err_out: |
5572 | - return; |
5573 | -} |
5574 | - |
5575 | -/** |
5576 | - * insn_get_modrm - collect ModRM byte, if any |
5577 | - * @insn: &struct insn containing instruction |
5578 | - * |
5579 | - * Populates @insn->modrm and updates @insn->next_byte to point past the |
5580 | - * ModRM byte, if any. If necessary, first collects the preceding bytes |
5581 | - * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1. |
5582 | - */ |
5583 | -void insn_get_modrm(struct insn *insn) |
5584 | -{ |
5585 | - struct insn_field *modrm = &insn->modrm; |
5586 | - insn_byte_t pfx_id, mod; |
5587 | - if (modrm->got) |
5588 | - return; |
5589 | - if (!insn->opcode.got) |
5590 | - insn_get_opcode(insn); |
5591 | - |
5592 | - if (inat_has_modrm(insn->attr)) { |
5593 | - mod = get_next(insn_byte_t, insn); |
5594 | - modrm->value = mod; |
5595 | - modrm->nbytes = 1; |
5596 | - if (inat_is_group(insn->attr)) { |
5597 | - pfx_id = insn_last_prefix_id(insn); |
5598 | - insn->attr = inat_get_group_attribute(mod, pfx_id, |
5599 | - insn->attr); |
5600 | - if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) |
5601 | - insn->attr = 0; /* This is bad */ |
5602 | - } |
5603 | - } |
5604 | - |
5605 | - if (insn->x86_64 && inat_is_force64(insn->attr)) |
5606 | - insn->opnd_bytes = 8; |
5607 | - modrm->got = 1; |
5608 | - |
5609 | -err_out: |
5610 | - return; |
5611 | -} |
5612 | - |
5613 | - |
5614 | -/** |
5615 | - * insn_rip_relative() - Does instruction use RIP-relative addressing mode? |
5616 | - * @insn: &struct insn containing instruction |
5617 | - * |
5618 | - * If necessary, first collects the instruction up to and including the |
5619 | - * ModRM byte. No effect if @insn->x86_64 is 0. |
5620 | - */ |
5621 | -int insn_rip_relative(struct insn *insn) |
5622 | -{ |
5623 | - struct insn_field *modrm = &insn->modrm; |
5624 | - |
5625 | - if (!insn->x86_64) |
5626 | - return 0; |
5627 | - if (!modrm->got) |
5628 | - insn_get_modrm(insn); |
5629 | - /* |
5630 | - * For rip-relative instructions, the mod field (top 2 bits) |
5631 | - * is zero and the r/m field (bottom 3 bits) is 0x5. |
5632 | - */ |
5633 | - return (modrm->nbytes && (modrm->value & 0xc7) == 0x5); |
5634 | -} |
5635 | - |
5636 | -/** |
5637 | - * insn_get_sib() - Get the SIB byte of instruction |
5638 | - * @insn: &struct insn containing instruction |
5639 | - * |
5640 | - * If necessary, first collects the instruction up to and including the |
5641 | - * ModRM byte. |
5642 | - */ |
5643 | -void insn_get_sib(struct insn *insn) |
5644 | -{ |
5645 | - insn_byte_t modrm; |
5646 | - |
5647 | - if (insn->sib.got) |
5648 | - return; |
5649 | - if (!insn->modrm.got) |
5650 | - insn_get_modrm(insn); |
5651 | - if (insn->modrm.nbytes) { |
5652 | - modrm = (insn_byte_t)insn->modrm.value; |
5653 | - if (insn->addr_bytes != 2 && |
5654 | - X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) { |
5655 | - insn->sib.value = get_next(insn_byte_t, insn); |
5656 | - insn->sib.nbytes = 1; |
5657 | - } |
5658 | - } |
5659 | - insn->sib.got = 1; |
5660 | - |
5661 | -err_out: |
5662 | - return; |
5663 | -} |
5664 | - |
5665 | - |
5666 | -/** |
5667 | - * insn_get_displacement() - Get the displacement of instruction |
5668 | - * @insn: &struct insn containing instruction |
5669 | - * |
5670 | - * If necessary, first collects the instruction up to and including the |
5671 | - * SIB byte. |
5672 | - * Displacement value is sign-expanded. |
5673 | - */ |
5674 | -void insn_get_displacement(struct insn *insn) |
5675 | -{ |
5676 | - insn_byte_t mod, rm, base; |
5677 | - |
5678 | - if (insn->displacement.got) |
5679 | - return; |
5680 | - if (!insn->sib.got) |
5681 | - insn_get_sib(insn); |
5682 | - if (insn->modrm.nbytes) { |
5683 | - /* |
5684 | - * Interpreting the modrm byte: |
5685 | - * mod = 00 - no displacement fields (exceptions below) |
5686 | - * mod = 01 - 1-byte displacement field |
5687 | - * mod = 10 - displacement field is 4 bytes, or 2 bytes if |
5688 | - * address size = 2 (0x67 prefix in 32-bit mode) |
5689 | - * mod = 11 - no memory operand |
5690 | - * |
5691 | - * If address size = 2... |
5692 | - * mod = 00, r/m = 110 - displacement field is 2 bytes |
5693 | - * |
5694 | - * If address size != 2... |
5695 | - * mod != 11, r/m = 100 - SIB byte exists |
5696 | - * mod = 00, SIB base = 101 - displacement field is 4 bytes |
5697 | - * mod = 00, r/m = 101 - rip-relative addressing, displacement |
5698 | - * field is 4 bytes |
5699 | - */ |
5700 | - mod = X86_MODRM_MOD(insn->modrm.value); |
5701 | - rm = X86_MODRM_RM(insn->modrm.value); |
5702 | - base = X86_SIB_BASE(insn->sib.value); |
5703 | - if (mod == 3) |
5704 | - goto out; |
5705 | - if (mod == 1) { |
5706 | - insn->displacement.value = get_next(signed char, insn); |
5707 | - insn->displacement.nbytes = 1; |
5708 | - } else if (insn->addr_bytes == 2) { |
5709 | - if ((mod == 0 && rm == 6) || mod == 2) { |
5710 | - insn->displacement.value = |
5711 | - get_next(short, insn); |
5712 | - insn->displacement.nbytes = 2; |
5713 | - } |
5714 | - } else { |
5715 | - if ((mod == 0 && rm == 5) || mod == 2 || |
5716 | - (mod == 0 && base == 5)) { |
5717 | - insn->displacement.value = get_next(int, insn); |
5718 | - insn->displacement.nbytes = 4; |
5719 | - } |
5720 | - } |
5721 | - } |
5722 | -out: |
5723 | - insn->displacement.got = 1; |
5724 | - |
5725 | -err_out: |
5726 | - return; |
5727 | -} |
5728 | - |
5729 | -/* Decode moffset16/32/64. Return 0 if failed */ |
5730 | -static int __get_moffset(struct insn *insn) |
5731 | -{ |
5732 | - switch (insn->addr_bytes) { |
5733 | - case 2: |
5734 | - insn->moffset1.value = get_next(short, insn); |
5735 | - insn->moffset1.nbytes = 2; |
5736 | - break; |
5737 | - case 4: |
5738 | - insn->moffset1.value = get_next(int, insn); |
5739 | - insn->moffset1.nbytes = 4; |
5740 | - break; |
5741 | - case 8: |
5742 | - insn->moffset1.value = get_next(int, insn); |
5743 | - insn->moffset1.nbytes = 4; |
5744 | - insn->moffset2.value = get_next(int, insn); |
5745 | - insn->moffset2.nbytes = 4; |
5746 | - break; |
5747 | - default: /* opnd_bytes must be modified manually */ |
5748 | - goto err_out; |
5749 | - } |
5750 | - insn->moffset1.got = insn->moffset2.got = 1; |
5751 | - |
5752 | - return 1; |
5753 | - |
5754 | -err_out: |
5755 | - return 0; |
5756 | -} |
5757 | - |
5758 | -/* Decode imm v32(Iz). Return 0 if failed */ |
5759 | -static int __get_immv32(struct insn *insn) |
5760 | -{ |
5761 | - switch (insn->opnd_bytes) { |
5762 | - case 2: |
5763 | - insn->immediate.value = get_next(short, insn); |
5764 | - insn->immediate.nbytes = 2; |
5765 | - break; |
5766 | - case 4: |
5767 | - case 8: |
5768 | - insn->immediate.value = get_next(int, insn); |
5769 | - insn->immediate.nbytes = 4; |
5770 | - break; |
5771 | - default: /* opnd_bytes must be modified manually */ |
5772 | - goto err_out; |
5773 | - } |
5774 | - |
5775 | - return 1; |
5776 | - |
5777 | -err_out: |
5778 | - return 0; |
5779 | -} |
5780 | - |
5781 | -/* Decode imm v64(Iv/Ov), Return 0 if failed */ |
5782 | -static int __get_immv(struct insn *insn) |
5783 | -{ |
5784 | - switch (insn->opnd_bytes) { |
5785 | - case 2: |
5786 | - insn->immediate1.value = get_next(short, insn); |
5787 | - insn->immediate1.nbytes = 2; |
5788 | - break; |
5789 | - case 4: |
5790 | - insn->immediate1.value = get_next(int, insn); |
5791 | - insn->immediate1.nbytes = 4; |
5792 | - break; |
5793 | - case 8: |
5794 | - insn->immediate1.value = get_next(int, insn); |
5795 | - insn->immediate1.nbytes = 4; |
5796 | - insn->immediate2.value = get_next(int, insn); |
5797 | - insn->immediate2.nbytes = 4; |
5798 | - break; |
5799 | - default: /* opnd_bytes must be modified manually */ |
5800 | - goto err_out; |
5801 | - } |
5802 | - insn->immediate1.got = insn->immediate2.got = 1; |
5803 | - |
5804 | - return 1; |
5805 | -err_out: |
5806 | - return 0; |
5807 | -} |
5808 | - |
5809 | -/* Decode ptr16:16/32(Ap) */ |
5810 | -static int __get_immptr(struct insn *insn) |
5811 | -{ |
5812 | - switch (insn->opnd_bytes) { |
5813 | - case 2: |
5814 | - insn->immediate1.value = get_next(short, insn); |
5815 | - insn->immediate1.nbytes = 2; |
5816 | - break; |
5817 | - case 4: |
5818 | - insn->immediate1.value = get_next(int, insn); |
5819 | - insn->immediate1.nbytes = 4; |
5820 | - break; |
5821 | - case 8: |
5822 | - /* ptr16:64 is not exist (no segment) */ |
5823 | - return 0; |
5824 | - default: /* opnd_bytes must be modified manually */ |
5825 | - goto err_out; |
5826 | - } |
5827 | - insn->immediate2.value = get_next(unsigned short, insn); |
5828 | - insn->immediate2.nbytes = 2; |
5829 | - insn->immediate1.got = insn->immediate2.got = 1; |
5830 | - |
5831 | - return 1; |
5832 | -err_out: |
5833 | - return 0; |
5834 | -} |
5835 | - |
5836 | -/** |
5837 | - * insn_get_immediate() - Get the immediates of instruction |
5838 | - * @insn: &struct insn containing instruction |
5839 | - * |
5840 | - * If necessary, first collects the instruction up to and including the |
5841 | - * displacement bytes. |
5842 | - * Basically, most of immediates are sign-expanded. Unsigned-value can be |
5843 | - * get by bit masking with ((1 << (nbytes * 8)) - 1) |
5844 | - */ |
5845 | -void insn_get_immediate(struct insn *insn) |
5846 | -{ |
5847 | - if (insn->immediate.got) |
5848 | - return; |
5849 | - if (!insn->displacement.got) |
5850 | - insn_get_displacement(insn); |
5851 | - |
5852 | - if (inat_has_moffset(insn->attr)) { |
5853 | - if (!__get_moffset(insn)) |
5854 | - goto err_out; |
5855 | - goto done; |
5856 | - } |
5857 | - |
5858 | - if (!inat_has_immediate(insn->attr)) |
5859 | - /* no immediates */ |
5860 | - goto done; |
5861 | - |
5862 | - switch (inat_immediate_size(insn->attr)) { |
5863 | - case INAT_IMM_BYTE: |
5864 | - insn->immediate.value = get_next(signed char, insn); |
5865 | - insn->immediate.nbytes = 1; |
5866 | - break; |
5867 | - case INAT_IMM_WORD: |
5868 | - insn->immediate.value = get_next(short, insn); |
5869 | - insn->immediate.nbytes = 2; |
5870 | - break; |
5871 | - case INAT_IMM_DWORD: |
5872 | - insn->immediate.value = get_next(int, insn); |
5873 | - insn->immediate.nbytes = 4; |
5874 | - break; |
5875 | - case INAT_IMM_QWORD: |
5876 | - insn->immediate1.value = get_next(int, insn); |
5877 | - insn->immediate1.nbytes = 4; |
5878 | - insn->immediate2.value = get_next(int, insn); |
5879 | - insn->immediate2.nbytes = 4; |
5880 | - break; |
5881 | - case INAT_IMM_PTR: |
5882 | - if (!__get_immptr(insn)) |
5883 | - goto err_out; |
5884 | - break; |
5885 | - case INAT_IMM_VWORD32: |
5886 | - if (!__get_immv32(insn)) |
5887 | - goto err_out; |
5888 | - break; |
5889 | - case INAT_IMM_VWORD: |
5890 | - if (!__get_immv(insn)) |
5891 | - goto err_out; |
5892 | - break; |
5893 | - default: |
5894 | - /* Here, insn must have an immediate, but failed */ |
5895 | - goto err_out; |
5896 | - } |
5897 | - if (inat_has_second_immediate(insn->attr)) { |
5898 | - insn->immediate2.value = get_next(signed char, insn); |
5899 | - insn->immediate2.nbytes = 1; |
5900 | - } |
5901 | -done: |
5902 | - insn->immediate.got = 1; |
5903 | - |
5904 | -err_out: |
5905 | - return; |
5906 | -} |
5907 | - |
5908 | -/** |
5909 | - * insn_get_length() - Get the length of instruction |
5910 | - * @insn: &struct insn containing instruction |
5911 | - * |
5912 | - * If necessary, first collects the instruction up to and including the |
5913 | - * immediates bytes. |
5914 | - */ |
5915 | -void insn_get_length(struct insn *insn) |
5916 | -{ |
5917 | - if (insn->length) |
5918 | - return; |
5919 | - if (!insn->immediate.got) |
5920 | - insn_get_immediate(insn); |
5921 | - insn->length = (unsigned char)((unsigned long)insn->next_byte |
5922 | - - (unsigned long)insn->kaddr); |
5923 | -} |
5924 | diff --git a/tools/objtool/arch/x86/insn/insn.h b/tools/objtool/arch/x86/insn/insn.h |
5925 | deleted file mode 100644 |
5926 | index e23578c7b1be..000000000000 |
5927 | --- a/tools/objtool/arch/x86/insn/insn.h |
5928 | +++ /dev/null |
5929 | @@ -1,211 +0,0 @@ |
5930 | -#ifndef _ASM_X86_INSN_H |
5931 | -#define _ASM_X86_INSN_H |
5932 | -/* |
5933 | - * x86 instruction analysis |
5934 | - * |
5935 | - * This program is free software; you can redistribute it and/or modify |
5936 | - * it under the terms of the GNU General Public License as published by |
5937 | - * the Free Software Foundation; either version 2 of the License, or |
5938 | - * (at your option) any later version. |
5939 | - * |
5940 | - * This program is distributed in the hope that it will be useful, |
5941 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
5942 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
5943 | - * GNU General Public License for more details. |
5944 | - * |
5945 | - * You should have received a copy of the GNU General Public License |
5946 | - * along with this program; if not, write to the Free Software |
5947 | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
5948 | - * |
5949 | - * Copyright (C) IBM Corporation, 2009 |
5950 | - */ |
5951 | - |
5952 | -/* insn_attr_t is defined in inat.h */ |
5953 | -#include "inat.h" |
5954 | - |
5955 | -struct insn_field { |
5956 | - union { |
5957 | - insn_value_t value; |
5958 | - insn_byte_t bytes[4]; |
5959 | - }; |
5960 | - /* !0 if we've run insn_get_xxx() for this field */ |
5961 | - unsigned char got; |
5962 | - unsigned char nbytes; |
5963 | -}; |
5964 | - |
5965 | -struct insn { |
5966 | - struct insn_field prefixes; /* |
5967 | - * Prefixes |
5968 | - * prefixes.bytes[3]: last prefix |
5969 | - */ |
5970 | - struct insn_field rex_prefix; /* REX prefix */ |
5971 | - struct insn_field vex_prefix; /* VEX prefix */ |
5972 | - struct insn_field opcode; /* |
5973 | - * opcode.bytes[0]: opcode1 |
5974 | - * opcode.bytes[1]: opcode2 |
5975 | - * opcode.bytes[2]: opcode3 |
5976 | - */ |
5977 | - struct insn_field modrm; |
5978 | - struct insn_field sib; |
5979 | - struct insn_field displacement; |
5980 | - union { |
5981 | - struct insn_field immediate; |
5982 | - struct insn_field moffset1; /* for 64bit MOV */ |
5983 | - struct insn_field immediate1; /* for 64bit imm or off16/32 */ |
5984 | - }; |
5985 | - union { |
5986 | - struct insn_field moffset2; /* for 64bit MOV */ |
5987 | - struct insn_field immediate2; /* for 64bit imm or seg16 */ |
5988 | - }; |
5989 | - |
5990 | - insn_attr_t attr; |
5991 | - unsigned char opnd_bytes; |
5992 | - unsigned char addr_bytes; |
5993 | - unsigned char length; |
5994 | - unsigned char x86_64; |
5995 | - |
5996 | - const insn_byte_t *kaddr; /* kernel address of insn to analyze */ |
5997 | - const insn_byte_t *end_kaddr; /* kernel address of last insn in buffer */ |
5998 | - const insn_byte_t *next_byte; |
5999 | -}; |
6000 | - |
6001 | -#define MAX_INSN_SIZE 15 |
6002 | - |
6003 | -#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6) |
6004 | -#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3) |
6005 | -#define X86_MODRM_RM(modrm) ((modrm) & 0x07) |
6006 | - |
6007 | -#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6) |
6008 | -#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3) |
6009 | -#define X86_SIB_BASE(sib) ((sib) & 0x07) |
6010 | - |
6011 | -#define X86_REX_W(rex) ((rex) & 8) |
6012 | -#define X86_REX_R(rex) ((rex) & 4) |
6013 | -#define X86_REX_X(rex) ((rex) & 2) |
6014 | -#define X86_REX_B(rex) ((rex) & 1) |
6015 | - |
6016 | -/* VEX bit flags */ |
6017 | -#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */ |
6018 | -#define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */ |
6019 | -#define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */ |
6020 | -#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ |
6021 | -#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ |
6022 | -/* VEX bit fields */ |
6023 | -#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */ |
6024 | -#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ |
6025 | -#define X86_VEX2_M 1 /* VEX2.M always 1 */ |
6026 | -#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ |
6027 | -#define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */ |
6028 | -#define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */ |
6029 | - |
6030 | -extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64); |
6031 | -extern void insn_get_prefixes(struct insn *insn); |
6032 | -extern void insn_get_opcode(struct insn *insn); |
6033 | -extern void insn_get_modrm(struct insn *insn); |
6034 | -extern void insn_get_sib(struct insn *insn); |
6035 | -extern void insn_get_displacement(struct insn *insn); |
6036 | -extern void insn_get_immediate(struct insn *insn); |
6037 | -extern void insn_get_length(struct insn *insn); |
6038 | - |
6039 | -/* Attribute will be determined after getting ModRM (for opcode groups) */ |
6040 | -static inline void insn_get_attribute(struct insn *insn) |
6041 | -{ |
6042 | - insn_get_modrm(insn); |
6043 | -} |
6044 | - |
6045 | -/* Instruction uses RIP-relative addressing */ |
6046 | -extern int insn_rip_relative(struct insn *insn); |
6047 | - |
6048 | -/* Init insn for kernel text */ |
6049 | -static inline void kernel_insn_init(struct insn *insn, |
6050 | - const void *kaddr, int buf_len) |
6051 | -{ |
6052 | -#ifdef CONFIG_X86_64 |
6053 | - insn_init(insn, kaddr, buf_len, 1); |
6054 | -#else /* CONFIG_X86_32 */ |
6055 | - insn_init(insn, kaddr, buf_len, 0); |
6056 | -#endif |
6057 | -} |
6058 | - |
6059 | -static inline int insn_is_avx(struct insn *insn) |
6060 | -{ |
6061 | - if (!insn->prefixes.got) |
6062 | - insn_get_prefixes(insn); |
6063 | - return (insn->vex_prefix.value != 0); |
6064 | -} |
6065 | - |
6066 | -static inline int insn_is_evex(struct insn *insn) |
6067 | -{ |
6068 | - if (!insn->prefixes.got) |
6069 | - insn_get_prefixes(insn); |
6070 | - return (insn->vex_prefix.nbytes == 4); |
6071 | -} |
6072 | - |
6073 | -/* Ensure this instruction is decoded completely */ |
6074 | -static inline int insn_complete(struct insn *insn) |
6075 | -{ |
6076 | - return insn->opcode.got && insn->modrm.got && insn->sib.got && |
6077 | - insn->displacement.got && insn->immediate.got; |
6078 | -} |
6079 | - |
6080 | -static inline insn_byte_t insn_vex_m_bits(struct insn *insn) |
6081 | -{ |
6082 | - if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ |
6083 | - return X86_VEX2_M; |
6084 | - else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */ |
6085 | - return X86_VEX3_M(insn->vex_prefix.bytes[1]); |
6086 | - else /* EVEX */ |
6087 | - return X86_EVEX_M(insn->vex_prefix.bytes[1]); |
6088 | -} |
6089 | - |
6090 | -static inline insn_byte_t insn_vex_p_bits(struct insn *insn) |
6091 | -{ |
6092 | - if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ |
6093 | - return X86_VEX_P(insn->vex_prefix.bytes[1]); |
6094 | - else |
6095 | - return X86_VEX_P(insn->vex_prefix.bytes[2]); |
6096 | -} |
6097 | - |
6098 | -/* Get the last prefix id from last prefix or VEX prefix */ |
6099 | -static inline int insn_last_prefix_id(struct insn *insn) |
6100 | -{ |
6101 | - if (insn_is_avx(insn)) |
6102 | - return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */ |
6103 | - |
6104 | - if (insn->prefixes.bytes[3]) |
6105 | - return inat_get_last_prefix_id(insn->prefixes.bytes[3]); |
6106 | - |
6107 | - return 0; |
6108 | -} |
6109 | - |
6110 | -/* Offset of each field from kaddr */ |
6111 | -static inline int insn_offset_rex_prefix(struct insn *insn) |
6112 | -{ |
6113 | - return insn->prefixes.nbytes; |
6114 | -} |
6115 | -static inline int insn_offset_vex_prefix(struct insn *insn) |
6116 | -{ |
6117 | - return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes; |
6118 | -} |
6119 | -static inline int insn_offset_opcode(struct insn *insn) |
6120 | -{ |
6121 | - return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes; |
6122 | -} |
6123 | -static inline int insn_offset_modrm(struct insn *insn) |
6124 | -{ |
6125 | - return insn_offset_opcode(insn) + insn->opcode.nbytes; |
6126 | -} |
6127 | -static inline int insn_offset_sib(struct insn *insn) |
6128 | -{ |
6129 | - return insn_offset_modrm(insn) + insn->modrm.nbytes; |
6130 | -} |
6131 | -static inline int insn_offset_displacement(struct insn *insn) |
6132 | -{ |
6133 | - return insn_offset_sib(insn) + insn->sib.nbytes; |
6134 | -} |
6135 | -static inline int insn_offset_immediate(struct insn *insn) |
6136 | -{ |
6137 | - return insn_offset_displacement(insn) + insn->displacement.nbytes; |
6138 | -} |
6139 | - |
6140 | -#endif /* _ASM_X86_INSN_H */ |
6141 | diff --git a/tools/objtool/arch/x86/insn/x86-opcode-map.txt b/tools/objtool/arch/x86/insn/x86-opcode-map.txt |
6142 | deleted file mode 100644 |
6143 | index 12e377184ee4..000000000000 |
6144 | --- a/tools/objtool/arch/x86/insn/x86-opcode-map.txt |
6145 | +++ /dev/null |
6146 | @@ -1,1063 +0,0 @@ |
6147 | -# x86 Opcode Maps |
6148 | -# |
6149 | -# This is (mostly) based on following documentations. |
6150 | -# - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C |
6151 | -# (#326018-047US, June 2013) |
6152 | -# |
6153 | -#<Opcode maps> |
6154 | -# Table: table-name |
6155 | -# Referrer: escaped-name |
6156 | -# AVXcode: avx-code |
6157 | -# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] |
6158 | -# (or) |
6159 | -# opcode: escape # escaped-name |
6160 | -# EndTable |
6161 | -# |
6162 | -# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix |
6163 | -# mnemonics that begin with lowercase 'k' accept a VEX prefix |
6164 | -# |
6165 | -#<group maps> |
6166 | -# GrpTable: GrpXXX |
6167 | -# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] |
6168 | -# EndTable |
6169 | -# |
6170 | -# AVX Superscripts |
6171 | -# (ev): this opcode requires EVEX prefix. |
6172 | -# (evo): this opcode is changed by EVEX prefix (EVEX opcode) |
6173 | -# (v): this opcode requires VEX prefix. |
6174 | -# (v1): this opcode only supports 128bit VEX. |
6175 | -# |
6176 | -# Last Prefix Superscripts |
6177 | -# - (66): the last prefix is 0x66 |
6178 | -# - (F3): the last prefix is 0xF3 |
6179 | -# - (F2): the last prefix is 0xF2 |
6180 | -# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) |
6181 | -# - (66&F2): Both 0x66 and 0xF2 prefixes are specified. |
6182 | - |
6183 | -Table: one byte opcode |
6184 | -Referrer: |
6185 | -AVXcode: |
6186 | -# 0x00 - 0x0f |
6187 | -00: ADD Eb,Gb |
6188 | -01: ADD Ev,Gv |
6189 | -02: ADD Gb,Eb |
6190 | -03: ADD Gv,Ev |
6191 | -04: ADD AL,Ib |
6192 | -05: ADD rAX,Iz |
6193 | -06: PUSH ES (i64) |
6194 | -07: POP ES (i64) |
6195 | -08: OR Eb,Gb |
6196 | -09: OR Ev,Gv |
6197 | -0a: OR Gb,Eb |
6198 | -0b: OR Gv,Ev |
6199 | -0c: OR AL,Ib |
6200 | -0d: OR rAX,Iz |
6201 | -0e: PUSH CS (i64) |
6202 | -0f: escape # 2-byte escape |
6203 | -# 0x10 - 0x1f |
6204 | -10: ADC Eb,Gb |
6205 | -11: ADC Ev,Gv |
6206 | -12: ADC Gb,Eb |
6207 | -13: ADC Gv,Ev |
6208 | -14: ADC AL,Ib |
6209 | -15: ADC rAX,Iz |
6210 | -16: PUSH SS (i64) |
6211 | -17: POP SS (i64) |
6212 | -18: SBB Eb,Gb |
6213 | -19: SBB Ev,Gv |
6214 | -1a: SBB Gb,Eb |
6215 | -1b: SBB Gv,Ev |
6216 | -1c: SBB AL,Ib |
6217 | -1d: SBB rAX,Iz |
6218 | -1e: PUSH DS (i64) |
6219 | -1f: POP DS (i64) |
6220 | -# 0x20 - 0x2f |
6221 | -20: AND Eb,Gb |
6222 | -21: AND Ev,Gv |
6223 | -22: AND Gb,Eb |
6224 | -23: AND Gv,Ev |
6225 | -24: AND AL,Ib |
6226 | -25: AND rAx,Iz |
6227 | -26: SEG=ES (Prefix) |
6228 | -27: DAA (i64) |
6229 | -28: SUB Eb,Gb |
6230 | -29: SUB Ev,Gv |
6231 | -2a: SUB Gb,Eb |
6232 | -2b: SUB Gv,Ev |
6233 | -2c: SUB AL,Ib |
6234 | -2d: SUB rAX,Iz |
6235 | -2e: SEG=CS (Prefix) |
6236 | -2f: DAS (i64) |
6237 | -# 0x30 - 0x3f |
6238 | -30: XOR Eb,Gb |
6239 | -31: XOR Ev,Gv |
6240 | -32: XOR Gb,Eb |
6241 | -33: XOR Gv,Ev |
6242 | -34: XOR AL,Ib |
6243 | -35: XOR rAX,Iz |
6244 | -36: SEG=SS (Prefix) |
6245 | -37: AAA (i64) |
6246 | -38: CMP Eb,Gb |
6247 | -39: CMP Ev,Gv |
6248 | -3a: CMP Gb,Eb |
6249 | -3b: CMP Gv,Ev |
6250 | -3c: CMP AL,Ib |
6251 | -3d: CMP rAX,Iz |
6252 | -3e: SEG=DS (Prefix) |
6253 | -3f: AAS (i64) |
6254 | -# 0x40 - 0x4f |
6255 | -40: INC eAX (i64) | REX (o64) |
6256 | -41: INC eCX (i64) | REX.B (o64) |
6257 | -42: INC eDX (i64) | REX.X (o64) |
6258 | -43: INC eBX (i64) | REX.XB (o64) |
6259 | -44: INC eSP (i64) | REX.R (o64) |
6260 | -45: INC eBP (i64) | REX.RB (o64) |
6261 | -46: INC eSI (i64) | REX.RX (o64) |
6262 | -47: INC eDI (i64) | REX.RXB (o64) |
6263 | -48: DEC eAX (i64) | REX.W (o64) |
6264 | -49: DEC eCX (i64) | REX.WB (o64) |
6265 | -4a: DEC eDX (i64) | REX.WX (o64) |
6266 | -4b: DEC eBX (i64) | REX.WXB (o64) |
6267 | -4c: DEC eSP (i64) | REX.WR (o64) |
6268 | -4d: DEC eBP (i64) | REX.WRB (o64) |
6269 | -4e: DEC eSI (i64) | REX.WRX (o64) |
6270 | -4f: DEC eDI (i64) | REX.WRXB (o64) |
6271 | -# 0x50 - 0x5f |
6272 | -50: PUSH rAX/r8 (d64) |
6273 | -51: PUSH rCX/r9 (d64) |
6274 | -52: PUSH rDX/r10 (d64) |
6275 | -53: PUSH rBX/r11 (d64) |
6276 | -54: PUSH rSP/r12 (d64) |
6277 | -55: PUSH rBP/r13 (d64) |
6278 | -56: PUSH rSI/r14 (d64) |
6279 | -57: PUSH rDI/r15 (d64) |
6280 | -58: POP rAX/r8 (d64) |
6281 | -59: POP rCX/r9 (d64) |
6282 | -5a: POP rDX/r10 (d64) |
6283 | -5b: POP rBX/r11 (d64) |
6284 | -5c: POP rSP/r12 (d64) |
6285 | -5d: POP rBP/r13 (d64) |
6286 | -5e: POP rSI/r14 (d64) |
6287 | -5f: POP rDI/r15 (d64) |
6288 | -# 0x60 - 0x6f |
6289 | -60: PUSHA/PUSHAD (i64) |
6290 | -61: POPA/POPAD (i64) |
6291 | -62: BOUND Gv,Ma (i64) | EVEX (Prefix) |
6292 | -63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64) |
6293 | -64: SEG=FS (Prefix) |
6294 | -65: SEG=GS (Prefix) |
6295 | -66: Operand-Size (Prefix) |
6296 | -67: Address-Size (Prefix) |
6297 | -68: PUSH Iz (d64) |
6298 | -69: IMUL Gv,Ev,Iz |
6299 | -6a: PUSH Ib (d64) |
6300 | -6b: IMUL Gv,Ev,Ib |
6301 | -6c: INS/INSB Yb,DX |
6302 | -6d: INS/INSW/INSD Yz,DX |
6303 | -6e: OUTS/OUTSB DX,Xb |
6304 | -6f: OUTS/OUTSW/OUTSD DX,Xz |
6305 | -# 0x70 - 0x7f |
6306 | -70: JO Jb |
6307 | -71: JNO Jb |
6308 | -72: JB/JNAE/JC Jb |
6309 | -73: JNB/JAE/JNC Jb |
6310 | -74: JZ/JE Jb |
6311 | -75: JNZ/JNE Jb |
6312 | -76: JBE/JNA Jb |
6313 | -77: JNBE/JA Jb |
6314 | -78: JS Jb |
6315 | -79: JNS Jb |
6316 | -7a: JP/JPE Jb |
6317 | -7b: JNP/JPO Jb |
6318 | -7c: JL/JNGE Jb |
6319 | -7d: JNL/JGE Jb |
6320 | -7e: JLE/JNG Jb |
6321 | -7f: JNLE/JG Jb |
6322 | -# 0x80 - 0x8f |
6323 | -80: Grp1 Eb,Ib (1A) |
6324 | -81: Grp1 Ev,Iz (1A) |
6325 | -82: Grp1 Eb,Ib (1A),(i64) |
6326 | -83: Grp1 Ev,Ib (1A) |
6327 | -84: TEST Eb,Gb |
6328 | -85: TEST Ev,Gv |
6329 | -86: XCHG Eb,Gb |
6330 | -87: XCHG Ev,Gv |
6331 | -88: MOV Eb,Gb |
6332 | -89: MOV Ev,Gv |
6333 | -8a: MOV Gb,Eb |
6334 | -8b: MOV Gv,Ev |
6335 | -8c: MOV Ev,Sw |
6336 | -8d: LEA Gv,M |
6337 | -8e: MOV Sw,Ew |
6338 | -8f: Grp1A (1A) | POP Ev (d64) |
6339 | -# 0x90 - 0x9f |
6340 | -90: NOP | PAUSE (F3) | XCHG r8,rAX |
6341 | -91: XCHG rCX/r9,rAX |
6342 | -92: XCHG rDX/r10,rAX |
6343 | -93: XCHG rBX/r11,rAX |
6344 | -94: XCHG rSP/r12,rAX |
6345 | -95: XCHG rBP/r13,rAX |
6346 | -96: XCHG rSI/r14,rAX |
6347 | -97: XCHG rDI/r15,rAX |
6348 | -98: CBW/CWDE/CDQE |
6349 | -99: CWD/CDQ/CQO |
6350 | -9a: CALLF Ap (i64) |
6351 | -9b: FWAIT/WAIT |
6352 | -9c: PUSHF/D/Q Fv (d64) |
6353 | -9d: POPF/D/Q Fv (d64) |
6354 | -9e: SAHF |
6355 | -9f: LAHF |
6356 | -# 0xa0 - 0xaf |
6357 | -a0: MOV AL,Ob |
6358 | -a1: MOV rAX,Ov |
6359 | -a2: MOV Ob,AL |
6360 | -a3: MOV Ov,rAX |
6361 | -a4: MOVS/B Yb,Xb |
6362 | -a5: MOVS/W/D/Q Yv,Xv |
6363 | -a6: CMPS/B Xb,Yb |
6364 | -a7: CMPS/W/D Xv,Yv |
6365 | -a8: TEST AL,Ib |
6366 | -a9: TEST rAX,Iz |
6367 | -aa: STOS/B Yb,AL |
6368 | -ab: STOS/W/D/Q Yv,rAX |
6369 | -ac: LODS/B AL,Xb |
6370 | -ad: LODS/W/D/Q rAX,Xv |
6371 | -ae: SCAS/B AL,Yb |
6372 | -# Note: The May 2011 Intel manual shows Xv for the second parameter of the |
6373 | -# next instruction but Yv is correct |
6374 | -af: SCAS/W/D/Q rAX,Yv |
6375 | -# 0xb0 - 0xbf |
6376 | -b0: MOV AL/R8L,Ib |
6377 | -b1: MOV CL/R9L,Ib |
6378 | -b2: MOV DL/R10L,Ib |
6379 | -b3: MOV BL/R11L,Ib |
6380 | -b4: MOV AH/R12L,Ib |
6381 | -b5: MOV CH/R13L,Ib |
6382 | -b6: MOV DH/R14L,Ib |
6383 | -b7: MOV BH/R15L,Ib |
6384 | -b8: MOV rAX/r8,Iv |
6385 | -b9: MOV rCX/r9,Iv |
6386 | -ba: MOV rDX/r10,Iv |
6387 | -bb: MOV rBX/r11,Iv |
6388 | -bc: MOV rSP/r12,Iv |
6389 | -bd: MOV rBP/r13,Iv |
6390 | -be: MOV rSI/r14,Iv |
6391 | -bf: MOV rDI/r15,Iv |
6392 | -# 0xc0 - 0xcf |
6393 | -c0: Grp2 Eb,Ib (1A) |
6394 | -c1: Grp2 Ev,Ib (1A) |
6395 | -c2: RETN Iw (f64) |
6396 | -c3: RETN |
6397 | -c4: LES Gz,Mp (i64) | VEX+2byte (Prefix) |
6398 | -c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix) |
6399 | -c6: Grp11A Eb,Ib (1A) |
6400 | -c7: Grp11B Ev,Iz (1A) |
6401 | -c8: ENTER Iw,Ib |
6402 | -c9: LEAVE (d64) |
6403 | -ca: RETF Iw |
6404 | -cb: RETF |
6405 | -cc: INT3 |
6406 | -cd: INT Ib |
6407 | -ce: INTO (i64) |
6408 | -cf: IRET/D/Q |
6409 | -# 0xd0 - 0xdf |
6410 | -d0: Grp2 Eb,1 (1A) |
6411 | -d1: Grp2 Ev,1 (1A) |
6412 | -d2: Grp2 Eb,CL (1A) |
6413 | -d3: Grp2 Ev,CL (1A) |
6414 | -d4: AAM Ib (i64) |
6415 | -d5: AAD Ib (i64) |
6416 | -d6: |
6417 | -d7: XLAT/XLATB |
6418 | -d8: ESC |
6419 | -d9: ESC |
6420 | -da: ESC |
6421 | -db: ESC |
6422 | -dc: ESC |
6423 | -dd: ESC |
6424 | -de: ESC |
6425 | -df: ESC |
6426 | -# 0xe0 - 0xef |
6427 | -# Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix |
6428 | -# in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation |
6429 | -# to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD. |
6430 | -e0: LOOPNE/LOOPNZ Jb (f64) |
6431 | -e1: LOOPE/LOOPZ Jb (f64) |
6432 | -e2: LOOP Jb (f64) |
6433 | -e3: JrCXZ Jb (f64) |
6434 | -e4: IN AL,Ib |
6435 | -e5: IN eAX,Ib |
6436 | -e6: OUT Ib,AL |
6437 | -e7: OUT Ib,eAX |
6438 | -# With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset |
6439 | -# in "near" jumps and calls is 16-bit. For CALL, |
6440 | -# push of return address is 16-bit wide, RSP is decremented by 2 |
6441 | -# but is not truncated to 16 bits, unlike RIP. |
6442 | -e8: CALL Jz (f64) |
6443 | -e9: JMP-near Jz (f64) |
6444 | -ea: JMP-far Ap (i64) |
6445 | -eb: JMP-short Jb (f64) |
6446 | -ec: IN AL,DX |
6447 | -ed: IN eAX,DX |
6448 | -ee: OUT DX,AL |
6449 | -ef: OUT DX,eAX |
6450 | -# 0xf0 - 0xff |
6451 | -f0: LOCK (Prefix) |
6452 | -f1: |
6453 | -f2: REPNE (Prefix) | XACQUIRE (Prefix) |
6454 | -f3: REP/REPE (Prefix) | XRELEASE (Prefix) |
6455 | -f4: HLT |
6456 | -f5: CMC |
6457 | -f6: Grp3_1 Eb (1A) |
6458 | -f7: Grp3_2 Ev (1A) |
6459 | -f8: CLC |
6460 | -f9: STC |
6461 | -fa: CLI |
6462 | -fb: STI |
6463 | -fc: CLD |
6464 | -fd: STD |
6465 | -fe: Grp4 (1A) |
6466 | -ff: Grp5 (1A) |
6467 | -EndTable |
6468 | - |
6469 | -Table: 2-byte opcode (0x0f) |
6470 | -Referrer: 2-byte escape |
6471 | -AVXcode: 1 |
6472 | -# 0x0f 0x00-0x0f |
6473 | -00: Grp6 (1A) |
6474 | -01: Grp7 (1A) |
6475 | -02: LAR Gv,Ew |
6476 | -03: LSL Gv,Ew |
6477 | -04: |
6478 | -05: SYSCALL (o64) |
6479 | -06: CLTS |
6480 | -07: SYSRET (o64) |
6481 | -08: INVD |
6482 | -09: WBINVD |
6483 | -0a: |
6484 | -0b: UD2 (1B) |
6485 | -0c: |
6486 | -# AMD's prefetch group. Intel supports prefetchw(/1) only. |
6487 | -0d: GrpP |
6488 | -0e: FEMMS |
6489 | -# 3DNow! uses the last imm byte as opcode extension. |
6490 | -0f: 3DNow! Pq,Qq,Ib |
6491 | -# 0x0f 0x10-0x1f |
6492 | -# NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands |
6493 | -# but it actually has operands. And also, vmovss and vmovsd only accept 128bit. |
6494 | -# MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form. |
6495 | -# Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming |
6496 | -# Reference A.1 |
6497 | -10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1) |
6498 | -11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1) |
6499 | -12: vmovlps Vq,Hq,Mq (v1) | vmovhlps Vq,Hq,Uq (v1) | vmovlpd Vq,Hq,Mq (66),(v1) | vmovsldup Vx,Wx (F3) | vmovddup Vx,Wx (F2) |
6500 | -13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1) |
6501 | -14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66) |
6502 | -15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66) |
6503 | -16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3) |
6504 | -17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1) |
6505 | -18: Grp16 (1A) |
6506 | -19: |
6507 | -# Intel SDM opcode map does not list MPX instructions. For now using Gv for |
6508 | -# bnd registers and Ev for everything else is OK because the instruction |
6509 | -# decoder does not use the information except as an indication that there is |
6510 | -# a ModR/M byte. |
6511 | -1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev |
6512 | -1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv |
6513 | -1c: |
6514 | -1d: |
6515 | -1e: |
6516 | -1f: NOP Ev |
6517 | -# 0x0f 0x20-0x2f |
6518 | -20: MOV Rd,Cd |
6519 | -21: MOV Rd,Dd |
6520 | -22: MOV Cd,Rd |
6521 | -23: MOV Dd,Rd |
6522 | -24: |
6523 | -25: |
6524 | -26: |
6525 | -27: |
6526 | -28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66) |
6527 | -29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66) |
6528 | -2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1) |
6529 | -2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66) |
6530 | -2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1) |
6531 | -2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1) |
6532 | -2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1) |
6533 | -2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1) |
6534 | -# 0x0f 0x30-0x3f |
6535 | -30: WRMSR |
6536 | -31: RDTSC |
6537 | -32: RDMSR |
6538 | -33: RDPMC |
6539 | -34: SYSENTER |
6540 | -35: SYSEXIT |
6541 | -36: |
6542 | -37: GETSEC |
6543 | -38: escape # 3-byte escape 1 |
6544 | -39: |
6545 | -3a: escape # 3-byte escape 2 |
6546 | -3b: |
6547 | -3c: |
6548 | -3d: |
6549 | -3e: |
6550 | -3f: |
6551 | -# 0x0f 0x40-0x4f |
6552 | -40: CMOVO Gv,Ev |
6553 | -41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66) |
6554 | -42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66) |
6555 | -43: CMOVAE/NB/NC Gv,Ev |
6556 | -44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66) |
6557 | -45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66) |
6558 | -46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66) |
6559 | -47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66) |
6560 | -48: CMOVS Gv,Ev |
6561 | -49: CMOVNS Gv,Ev |
6562 | -4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66) |
6563 | -4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk |
6564 | -4c: CMOVL/NGE Gv,Ev |
6565 | -4d: CMOVNL/GE Gv,Ev |
6566 | -4e: CMOVLE/NG Gv,Ev |
6567 | -4f: CMOVNLE/G Gv,Ev |
6568 | -# 0x0f 0x50-0x5f |
6569 | -50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66) |
6570 | -51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1) |
6571 | -52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1) |
6572 | -53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1) |
6573 | -54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66) |
6574 | -55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66) |
6575 | -56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66) |
6576 | -57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66) |
6577 | -58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1) |
6578 | -59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1) |
6579 | -5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1) |
6580 | -5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3) |
6581 | -5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1) |
6582 | -5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1) |
6583 | -5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1) |
6584 | -5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1) |
6585 | -# 0x0f 0x60-0x6f |
6586 | -60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1) |
6587 | -61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1) |
6588 | -62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1) |
6589 | -63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1) |
6590 | -64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1) |
6591 | -65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1) |
6592 | -66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1) |
6593 | -67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1) |
6594 | -68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1) |
6595 | -69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1) |
6596 | -6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1) |
6597 | -6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1) |
6598 | -6c: vpunpcklqdq Vx,Hx,Wx (66),(v1) |
6599 | -6d: vpunpckhqdq Vx,Hx,Wx (66),(v1) |
6600 | -6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1) |
6601 | -6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev) |
6602 | -# 0x0f 0x70-0x7f |
6603 | -70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1) |
6604 | -71: Grp12 (1A) |
6605 | -72: Grp13 (1A) |
6606 | -73: Grp14 (1A) |
6607 | -74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1) |
6608 | -75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1) |
6609 | -76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1) |
6610 | -# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX. |
6611 | -77: emms | vzeroupper | vzeroall |
6612 | -78: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev) |
6613 | -79: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev) |
6614 | -7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev) |
6615 | -7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev) |
6616 | -7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2) |
6617 | -7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2) |
6618 | -7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1) |
6619 | -7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev) |
6620 | -# 0x0f 0x80-0x8f |
6621 | -# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). |
6622 | -80: JO Jz (f64) |
6623 | -81: JNO Jz (f64) |
6624 | -82: JB/JC/JNAE Jz (f64) |
6625 | -83: JAE/JNB/JNC Jz (f64) |
6626 | -84: JE/JZ Jz (f64) |
6627 | -85: JNE/JNZ Jz (f64) |
6628 | -86: JBE/JNA Jz (f64) |
6629 | -87: JA/JNBE Jz (f64) |
6630 | -88: JS Jz (f64) |
6631 | -89: JNS Jz (f64) |
6632 | -8a: JP/JPE Jz (f64) |
6633 | -8b: JNP/JPO Jz (f64) |
6634 | -8c: JL/JNGE Jz (f64) |
6635 | -8d: JNL/JGE Jz (f64) |
6636 | -8e: JLE/JNG Jz (f64) |
6637 | -8f: JNLE/JG Jz (f64) |
6638 | -# 0x0f 0x90-0x9f |
6639 | -90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66) |
6640 | -91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66) |
6641 | -92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2) |
6642 | -93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2) |
6643 | -94: SETE/Z Eb |
6644 | -95: SETNE/NZ Eb |
6645 | -96: SETBE/NA Eb |
6646 | -97: SETA/NBE Eb |
6647 | -98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66) |
6648 | -99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66) |
6649 | -9a: SETP/PE Eb |
6650 | -9b: SETNP/PO Eb |
6651 | -9c: SETL/NGE Eb |
6652 | -9d: SETNL/GE Eb |
6653 | -9e: SETLE/NG Eb |
6654 | -9f: SETNLE/G Eb |
6655 | -# 0x0f 0xa0-0xaf |
6656 | -a0: PUSH FS (d64) |
6657 | -a1: POP FS (d64) |
6658 | -a2: CPUID |
6659 | -a3: BT Ev,Gv |
6660 | -a4: SHLD Ev,Gv,Ib |
6661 | -a5: SHLD Ev,Gv,CL |
6662 | -a6: GrpPDLK |
6663 | -a7: GrpRNG |
6664 | -a8: PUSH GS (d64) |
6665 | -a9: POP GS (d64) |
6666 | -aa: RSM |
6667 | -ab: BTS Ev,Gv |
6668 | -ac: SHRD Ev,Gv,Ib |
6669 | -ad: SHRD Ev,Gv,CL |
6670 | -ae: Grp15 (1A),(1C) |
6671 | -af: IMUL Gv,Ev |
6672 | -# 0x0f 0xb0-0xbf |
6673 | -b0: CMPXCHG Eb,Gb |
6674 | -b1: CMPXCHG Ev,Gv |
6675 | -b2: LSS Gv,Mp |
6676 | -b3: BTR Ev,Gv |
6677 | -b4: LFS Gv,Mp |
6678 | -b5: LGS Gv,Mp |
6679 | -b6: MOVZX Gv,Eb |
6680 | -b7: MOVZX Gv,Ew |
6681 | -b8: JMPE (!F3) | POPCNT Gv,Ev (F3) |
6682 | -b9: Grp10 (1A) |
6683 | -ba: Grp8 Ev,Ib (1A) |
6684 | -bb: BTC Ev,Gv |
6685 | -bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3) |
6686 | -bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3) |
6687 | -be: MOVSX Gv,Eb |
6688 | -bf: MOVSX Gv,Ew |
6689 | -# 0x0f 0xc0-0xcf |
6690 | -c0: XADD Eb,Gb |
6691 | -c1: XADD Ev,Gv |
6692 | -c2: vcmpps Vps,Hps,Wps,Ib | vcmppd Vpd,Hpd,Wpd,Ib (66) | vcmpss Vss,Hss,Wss,Ib (F3),(v1) | vcmpsd Vsd,Hsd,Wsd,Ib (F2),(v1) |
6693 | -c3: movnti My,Gy |
6694 | -c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1) |
6695 | -c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1) |
6696 | -c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66) |
6697 | -c7: Grp9 (1A) |
6698 | -c8: BSWAP RAX/EAX/R8/R8D |
6699 | -c9: BSWAP RCX/ECX/R9/R9D |
6700 | -ca: BSWAP RDX/EDX/R10/R10D |
6701 | -cb: BSWAP RBX/EBX/R11/R11D |
6702 | -cc: BSWAP RSP/ESP/R12/R12D |
6703 | -cd: BSWAP RBP/EBP/R13/R13D |
6704 | -ce: BSWAP RSI/ESI/R14/R14D |
6705 | -cf: BSWAP RDI/EDI/R15/R15D |
6706 | -# 0x0f 0xd0-0xdf |
6707 | -d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2) |
6708 | -d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1) |
6709 | -d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1) |
6710 | -d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1) |
6711 | -d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1) |
6712 | -d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1) |
6713 | -d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2) |
6714 | -d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1) |
6715 | -d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1) |
6716 | -d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1) |
6717 | -da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1) |
6718 | -db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo) |
6719 | -dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1) |
6720 | -dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1) |
6721 | -de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1) |
6722 | -df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo) |
6723 | -# 0x0f 0xe0-0xef |
6724 | -e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1) |
6725 | -e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1) |
6726 | -e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1) |
6727 | -e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1) |
6728 | -e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1) |
6729 | -e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1) |
6730 | -e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2) |
6731 | -e7: movntq Mq,Pq | vmovntdq Mx,Vx (66) |
6732 | -e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1) |
6733 | -e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1) |
6734 | -ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1) |
6735 | -eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo) |
6736 | -ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1) |
6737 | -ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1) |
6738 | -ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1) |
6739 | -ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo) |
6740 | -# 0x0f 0xf0-0xff |
6741 | -f0: vlddqu Vx,Mx (F2) |
6742 | -f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1) |
6743 | -f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1) |
6744 | -f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1) |
6745 | -f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1) |
6746 | -f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1) |
6747 | -f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1) |
6748 | -f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1) |
6749 | -f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1) |
6750 | -f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1) |
6751 | -fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1) |
6752 | -fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) |
6753 | -fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) |
6754 | -fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) |
6755 | -fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) |
6756 | -ff: |
6757 | -EndTable |
6758 | - |
6759 | -Table: 3-byte opcode 1 (0x0f 0x38) |
6760 | -Referrer: 3-byte escape 1 |
6761 | -AVXcode: 2 |
6762 | -# 0x0f 0x38 0x00-0x0f |
6763 | -00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1) |
6764 | -01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1) |
6765 | -02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1) |
6766 | -03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1) |
6767 | -04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1) |
6768 | -05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1) |
6769 | -06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1) |
6770 | -07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1) |
6771 | -08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1) |
6772 | -09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1) |
6773 | -0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1) |
6774 | -0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1) |
6775 | -0c: vpermilps Vx,Hx,Wx (66),(v) |
6776 | -0d: vpermilpd Vx,Hx,Wx (66),(v) |
6777 | -0e: vtestps Vx,Wx (66),(v) |
6778 | -0f: vtestpd Vx,Wx (66),(v) |
6779 | -# 0x0f 0x38 0x10-0x1f |
6780 | -10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev) |
6781 | -11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev) |
6782 | -12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev) |
6783 | -13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev) |
6784 | -14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo) |
6785 | -15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo) |
6786 | -16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo) |
6787 | -17: vptest Vx,Wx (66) |
6788 | -18: vbroadcastss Vx,Wd (66),(v) |
6789 | -19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo) |
6790 | -1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo) |
6791 | -1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev) |
6792 | -1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1) |
6793 | -1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1) |
6794 | -1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1) |
6795 | -1f: vpabsq Vx,Wx (66),(ev) |
6796 | -# 0x0f 0x38 0x20-0x2f |
6797 | -20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev) |
6798 | -21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev) |
6799 | -22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev) |
6800 | -23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev) |
6801 | -24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev) |
6802 | -25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev) |
6803 | -26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev) |
6804 | -27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev) |
6805 | -28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev) |
6806 | -29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev) |
6807 | -2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev) |
6808 | -2b: vpackusdw Vx,Hx,Wx (66),(v1) |
6809 | -2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo) |
6810 | -2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo) |
6811 | -2e: vmaskmovps Mx,Hx,Vx (66),(v) |
6812 | -2f: vmaskmovpd Mx,Hx,Vx (66),(v) |
6813 | -# 0x0f 0x38 0x30-0x3f |
6814 | -30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev) |
6815 | -31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev) |
6816 | -32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev) |
6817 | -33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev) |
6818 | -34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev) |
6819 | -35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev) |
6820 | -36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo) |
6821 | -37: vpcmpgtq Vx,Hx,Wx (66),(v1) |
6822 | -38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev) |
6823 | -39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev) |
6824 | -3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev) |
6825 | -3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo) |
6826 | -3c: vpmaxsb Vx,Hx,Wx (66),(v1) |
6827 | -3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo) |
6828 | -3e: vpmaxuw Vx,Hx,Wx (66),(v1) |
6829 | -3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo) |
6830 | -# 0x0f 0x38 0x40-0x8f |
6831 | -40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo) |
6832 | -41: vphminposuw Vdq,Wdq (66),(v1) |
6833 | -42: vgetexpps/d Vx,Wx (66),(ev) |
6834 | -43: vgetexpss/d Vx,Hx,Wx (66),(ev) |
6835 | -44: vplzcntd/q Vx,Wx (66),(ev) |
6836 | -45: vpsrlvd/q Vx,Hx,Wx (66),(v) |
6837 | -46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo) |
6838 | -47: vpsllvd/q Vx,Hx,Wx (66),(v) |
6839 | -# Skip 0x48-0x4b |
6840 | -4c: vrcp14ps/d Vpd,Wpd (66),(ev) |
6841 | -4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) |
6842 | -4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) |
6843 | -4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) |
6844 | -# Skip 0x50-0x57 |
6845 | -58: vpbroadcastd Vx,Wx (66),(v) |
6846 | -59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo) |
6847 | -5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo) |
6848 | -5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev) |
6849 | -# Skip 0x5c-0x63 |
6850 | -64: vpblendmd/q Vx,Hx,Wx (66),(ev) |
6851 | -65: vblendmps/d Vx,Hx,Wx (66),(ev) |
6852 | -66: vpblendmb/w Vx,Hx,Wx (66),(ev) |
6853 | -# Skip 0x67-0x74 |
6854 | -75: vpermi2b/w Vx,Hx,Wx (66),(ev) |
6855 | -76: vpermi2d/q Vx,Hx,Wx (66),(ev) |
6856 | -77: vpermi2ps/d Vx,Hx,Wx (66),(ev) |
6857 | -78: vpbroadcastb Vx,Wx (66),(v) |
6858 | -79: vpbroadcastw Vx,Wx (66),(v) |
6859 | -7a: vpbroadcastb Vx,Rv (66),(ev) |
6860 | -7b: vpbroadcastw Vx,Rv (66),(ev) |
6861 | -7c: vpbroadcastd/q Vx,Rv (66),(ev) |
6862 | -7d: vpermt2b/w Vx,Hx,Wx (66),(ev) |
6863 | -7e: vpermt2d/q Vx,Hx,Wx (66),(ev) |
6864 | -7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) |
6865 | -80: INVEPT Gy,Mdq (66) |
6866 | -81: INVPID Gy,Mdq (66) |
6867 | -82: INVPCID Gy,Mdq (66) |
6868 | -83: vpmultishiftqb Vx,Hx,Wx (66),(ev) |
6869 | -88: vexpandps/d Vpd,Wpd (66),(ev) |
6870 | -89: vpexpandd/q Vx,Wx (66),(ev) |
6871 | -8a: vcompressps/d Wx,Vx (66),(ev) |
6872 | -8b: vpcompressd/q Wx,Vx (66),(ev) |
6873 | -8c: vpmaskmovd/q Vx,Hx,Mx (66),(v) |
6874 | -8d: vpermb/w Vx,Hx,Wx (66),(ev) |
6875 | -8e: vpmaskmovd/q Mx,Vx,Hx (66),(v) |
6876 | -# 0x0f 0x38 0x90-0xbf (FMA) |
6877 | -90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo) |
6878 | -91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo) |
6879 | -92: vgatherdps/d Vx,Hx,Wx (66),(v) |
6880 | -93: vgatherqps/d Vx,Hx,Wx (66),(v) |
6881 | -94: |
6882 | -95: |
6883 | -96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v) |
6884 | -97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v) |
6885 | -98: vfmadd132ps/d Vx,Hx,Wx (66),(v) |
6886 | -99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1) |
6887 | -9a: vfmsub132ps/d Vx,Hx,Wx (66),(v) |
6888 | -9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1) |
6889 | -9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v) |
6890 | -9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) |
6891 | -9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) |
6892 | -9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1) |
6893 | -a0: vpscatterdd/q Wx,Vx (66),(ev) |
6894 | -a1: vpscatterqd/q Wx,Vx (66),(ev) |
6895 | -a2: vscatterdps/d Wx,Vx (66),(ev) |
6896 | -a3: vscatterqps/d Wx,Vx (66),(ev) |
6897 | -a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) |
6898 | -a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) |
6899 | -a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) |
6900 | -a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1) |
6901 | -aa: vfmsub213ps/d Vx,Hx,Wx (66),(v) |
6902 | -ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1) |
6903 | -ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v) |
6904 | -ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) |
6905 | -ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) |
6906 | -af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) |
6907 | -b4: vpmadd52luq Vx,Hx,Wx (66),(ev) |
6908 | -b5: vpmadd52huq Vx,Hx,Wx (66),(ev) |
6909 | -b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) |
6910 | -b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) |
6911 | -b8: vfmadd231ps/d Vx,Hx,Wx (66),(v) |
6912 | -b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1) |
6913 | -ba: vfmsub231ps/d Vx,Hx,Wx (66),(v) |
6914 | -bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1) |
6915 | -bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v) |
6916 | -bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1) |
6917 | -be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) |
6918 | -bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) |
6919 | -# 0x0f 0x38 0xc0-0xff |
6920 | -c4: vpconflictd/q Vx,Wx (66),(ev) |
6921 | -c6: Grp18 (1A) |
6922 | -c7: Grp19 (1A) |
6923 | -c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev) |
6924 | -c9: sha1msg1 Vdq,Wdq |
6925 | -ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev) |
6926 | -cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) |
6927 | -cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) |
6928 | -cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) |
6929 | -db: VAESIMC Vdq,Wdq (66),(v1) |
6930 | -dc: VAESENC Vdq,Hdq,Wdq (66),(v1) |
6931 | -dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) |
6932 | -de: VAESDEC Vdq,Hdq,Wdq (66),(v1) |
6933 | -df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1) |
6934 | -f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) |
6935 | -f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) |
6936 | -f2: ANDN Gy,By,Ey (v) |
6937 | -f3: Grp17 (1A) |
6938 | -f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) |
6939 | -f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) |
6940 | -f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) |
6941 | -EndTable |
6942 | - |
6943 | -Table: 3-byte opcode 2 (0x0f 0x3a) |
6944 | -Referrer: 3-byte escape 2 |
6945 | -AVXcode: 3 |
6946 | -# 0x0f 0x3a 0x00-0xff |
6947 | -00: vpermq Vqq,Wqq,Ib (66),(v) |
6948 | -01: vpermpd Vqq,Wqq,Ib (66),(v) |
6949 | -02: vpblendd Vx,Hx,Wx,Ib (66),(v) |
6950 | -03: valignd/q Vx,Hx,Wx,Ib (66),(ev) |
6951 | -04: vpermilps Vx,Wx,Ib (66),(v) |
6952 | -05: vpermilpd Vx,Wx,Ib (66),(v) |
6953 | -06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v) |
6954 | -07: |
6955 | -08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo) |
6956 | -09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo) |
6957 | -0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo) |
6958 | -0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo) |
6959 | -0c: vblendps Vx,Hx,Wx,Ib (66) |
6960 | -0d: vblendpd Vx,Hx,Wx,Ib (66) |
6961 | -0e: vpblendw Vx,Hx,Wx,Ib (66),(v1) |
6962 | -0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1) |
6963 | -14: vpextrb Rd/Mb,Vdq,Ib (66),(v1) |
6964 | -15: vpextrw Rd/Mw,Vdq,Ib (66),(v1) |
6965 | -16: vpextrd/q Ey,Vdq,Ib (66),(v1) |
6966 | -17: vextractps Ed,Vdq,Ib (66),(v1) |
6967 | -18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) |
6968 | -19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo) |
6969 | -1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) |
6970 | -1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev) |
6971 | -1d: vcvtps2ph Wx,Vx,Ib (66),(v) |
6972 | -1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev) |
6973 | -1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev) |
6974 | -20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1) |
6975 | -21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1) |
6976 | -22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1) |
6977 | -23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) |
6978 | -25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev) |
6979 | -26: vgetmantps/d Vx,Wx,Ib (66),(ev) |
6980 | -27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev) |
6981 | -30: kshiftrb/w Vk,Uk,Ib (66),(v) |
6982 | -31: kshiftrd/q Vk,Uk,Ib (66),(v) |
6983 | -32: kshiftlb/w Vk,Uk,Ib (66),(v) |
6984 | -33: kshiftld/q Vk,Uk,Ib (66),(v) |
6985 | -38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) |
6986 | -39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo) |
6987 | -3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) |
6988 | -3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev) |
6989 | -3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev) |
6990 | -3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev) |
6991 | -40: vdpps Vx,Hx,Wx,Ib (66) |
6992 | -41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) |
6993 | -42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo) |
6994 | -43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) |
6995 | -44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) |
6996 | -46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) |
6997 | -4a: vblendvps Vx,Hx,Wx,Lx (66),(v) |
6998 | -4b: vblendvpd Vx,Hx,Wx,Lx (66),(v) |
6999 | -4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1) |
7000 | -50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev) |
7001 | -51: vrangess/d Vx,Hx,Wx,Ib (66),(ev) |
7002 | -54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev) |
7003 | -55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev) |
7004 | -56: vreduceps/d Vx,Wx,Ib (66),(ev) |
7005 | -57: vreducess/d Vx,Hx,Wx,Ib (66),(ev) |
7006 | -60: vpcmpestrm Vdq,Wdq,Ib (66),(v1) |
7007 | -61: vpcmpestri Vdq,Wdq,Ib (66),(v1) |
7008 | -62: vpcmpistrm Vdq,Wdq,Ib (66),(v1) |
7009 | -63: vpcmpistri Vdq,Wdq,Ib (66),(v1) |
7010 | -66: vfpclassps/d Vk,Wx,Ib (66),(ev) |
7011 | -67: vfpclassss/d Vk,Wx,Ib (66),(ev) |
7012 | -cc: sha1rnds4 Vdq,Wdq,Ib |
7013 | -df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) |
7014 | -f0: RORX Gy,Ey,Ib (F2),(v) |
7015 | -EndTable |
7016 | - |
7017 | -GrpTable: Grp1 |
7018 | -0: ADD |
7019 | -1: OR |
7020 | -2: ADC |
7021 | -3: SBB |
7022 | -4: AND |
7023 | -5: SUB |
7024 | -6: XOR |
7025 | -7: CMP |
7026 | -EndTable |
7027 | - |
7028 | -GrpTable: Grp1A |
7029 | -0: POP |
7030 | -EndTable |
7031 | - |
7032 | -GrpTable: Grp2 |
7033 | -0: ROL |
7034 | -1: ROR |
7035 | -2: RCL |
7036 | -3: RCR |
7037 | -4: SHL/SAL |
7038 | -5: SHR |
7039 | -6: |
7040 | -7: SAR |
7041 | -EndTable |
7042 | - |
7043 | -GrpTable: Grp3_1 |
7044 | -0: TEST Eb,Ib |
7045 | -1: |
7046 | -2: NOT Eb |
7047 | -3: NEG Eb |
7048 | -4: MUL AL,Eb |
7049 | -5: IMUL AL,Eb |
7050 | -6: DIV AL,Eb |
7051 | -7: IDIV AL,Eb |
7052 | -EndTable |
7053 | - |
7054 | -GrpTable: Grp3_2 |
7055 | -0: TEST Ev,Iz |
7056 | -1: |
7057 | -2: NOT Ev |
7058 | -3: NEG Ev |
7059 | -4: MUL rAX,Ev |
7060 | -5: IMUL rAX,Ev |
7061 | -6: DIV rAX,Ev |
7062 | -7: IDIV rAX,Ev |
7063 | -EndTable |
7064 | - |
7065 | -GrpTable: Grp4 |
7066 | -0: INC Eb |
7067 | -1: DEC Eb |
7068 | -EndTable |
7069 | - |
7070 | -GrpTable: Grp5 |
7071 | -0: INC Ev |
7072 | -1: DEC Ev |
7073 | -# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). |
7074 | -2: CALLN Ev (f64) |
7075 | -3: CALLF Ep |
7076 | -4: JMPN Ev (f64) |
7077 | -5: JMPF Mp |
7078 | -6: PUSH Ev (d64) |
7079 | -7: |
7080 | -EndTable |
7081 | - |
7082 | -GrpTable: Grp6 |
7083 | -0: SLDT Rv/Mw |
7084 | -1: STR Rv/Mw |
7085 | -2: LLDT Ew |
7086 | -3: LTR Ew |
7087 | -4: VERR Ew |
7088 | -5: VERW Ew |
7089 | -EndTable |
7090 | - |
7091 | -GrpTable: Grp7 |
7092 | -0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) |
7093 | -1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) |
7094 | -2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) |
7095 | -3: LIDT Ms |
7096 | -4: SMSW Mw/Rv |
7097 | -5: rdpkru (110),(11B) | wrpkru (111),(11B) |
7098 | -6: LMSW Ew |
7099 | -7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B) |
7100 | -EndTable |
7101 | - |
7102 | -GrpTable: Grp8 |
7103 | -4: BT |
7104 | -5: BTS |
7105 | -6: BTR |
7106 | -7: BTC |
7107 | -EndTable |
7108 | - |
7109 | -GrpTable: Grp9 |
7110 | -1: CMPXCHG8B/16B Mq/Mdq |
7111 | -3: xrstors |
7112 | -4: xsavec |
7113 | -5: xsaves |
7114 | -6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) |
7115 | -7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B) |
7116 | -EndTable |
7117 | - |
7118 | -GrpTable: Grp10 |
7119 | -EndTable |
7120 | - |
7121 | -# Grp11A and Grp11B are expressed as Grp11 in Intel SDM |
7122 | -GrpTable: Grp11A |
7123 | -0: MOV Eb,Ib |
7124 | -7: XABORT Ib (000),(11B) |
7125 | -EndTable |
7126 | - |
7127 | -GrpTable: Grp11B |
7128 | -0: MOV Eb,Iz |
7129 | -7: XBEGIN Jz (000),(11B) |
7130 | -EndTable |
7131 | - |
7132 | -GrpTable: Grp12 |
7133 | -2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1) |
7134 | -4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1) |
7135 | -6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1) |
7136 | -EndTable |
7137 | - |
7138 | -GrpTable: Grp13 |
7139 | -0: vprord/q Hx,Wx,Ib (66),(ev) |
7140 | -1: vprold/q Hx,Wx,Ib (66),(ev) |
7141 | -2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1) |
7142 | -4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo) |
7143 | -6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1) |
7144 | -EndTable |
7145 | - |
7146 | -GrpTable: Grp14 |
7147 | -2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1) |
7148 | -3: vpsrldq Hx,Ux,Ib (66),(11B),(v1) |
7149 | -6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1) |
7150 | -7: vpslldq Hx,Ux,Ib (66),(11B),(v1) |
7151 | -EndTable |
7152 | - |
7153 | -GrpTable: Grp15 |
7154 | -0: fxsave | RDFSBASE Ry (F3),(11B) |
7155 | -1: fxstor | RDGSBASE Ry (F3),(11B) |
7156 | -2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B) |
7157 | -3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) |
7158 | -4: XSAVE | ptwrite Ey (F3),(11B) |
7159 | -5: XRSTOR | lfence (11B) |
7160 | -6: XSAVEOPT | clwb (66) | mfence (11B) |
7161 | -7: clflush | clflushopt (66) | sfence (11B) |
7162 | -EndTable |
7163 | - |
7164 | -GrpTable: Grp16 |
7165 | -0: prefetch NTA |
7166 | -1: prefetch T0 |
7167 | -2: prefetch T1 |
7168 | -3: prefetch T2 |
7169 | -EndTable |
7170 | - |
7171 | -GrpTable: Grp17 |
7172 | -1: BLSR By,Ey (v) |
7173 | -2: BLSMSK By,Ey (v) |
7174 | -3: BLSI By,Ey (v) |
7175 | -EndTable |
7176 | - |
7177 | -GrpTable: Grp18 |
7178 | -1: vgatherpf0dps/d Wx (66),(ev) |
7179 | -2: vgatherpf1dps/d Wx (66),(ev) |
7180 | -5: vscatterpf0dps/d Wx (66),(ev) |
7181 | -6: vscatterpf1dps/d Wx (66),(ev) |
7182 | -EndTable |
7183 | - |
7184 | -GrpTable: Grp19 |
7185 | -1: vgatherpf0qps/d Wx (66),(ev) |
7186 | -2: vgatherpf1qps/d Wx (66),(ev) |
7187 | -5: vscatterpf0qps/d Wx (66),(ev) |
7188 | -6: vscatterpf1qps/d Wx (66),(ev) |
7189 | -EndTable |
7190 | - |
7191 | -# AMD's Prefetch Group |
7192 | -GrpTable: GrpP |
7193 | -0: PREFETCH |
7194 | -1: PREFETCHW |
7195 | -EndTable |
7196 | - |
7197 | -GrpTable: GrpPDLK |
7198 | -0: MONTMUL |
7199 | -1: XSHA1 |
7200 | -2: XSHA2 |
7201 | -EndTable |
7202 | - |
7203 | -GrpTable: GrpRNG |
7204 | -0: xstore-rng |
7205 | -1: xcrypt-ecb |
7206 | -2: xcrypt-cbc |
7207 | -4: xcrypt-cfb |
7208 | -5: xcrypt-ofb |
7209 | -EndTable |
7210 | diff --git a/tools/objtool/arch/x86/lib/inat.c b/tools/objtool/arch/x86/lib/inat.c |
7211 | new file mode 100644 |
7212 | index 000000000000..c1f01a8e9f65 |
7213 | --- /dev/null |
7214 | +++ b/tools/objtool/arch/x86/lib/inat.c |
7215 | @@ -0,0 +1,97 @@ |
7216 | +/* |
7217 | + * x86 instruction attribute tables |
7218 | + * |
7219 | + * Written by Masami Hiramatsu <mhiramat@redhat.com> |
7220 | + * |
7221 | + * This program is free software; you can redistribute it and/or modify |
7222 | + * it under the terms of the GNU General Public License as published by |
7223 | + * the Free Software Foundation; either version 2 of the License, or |
7224 | + * (at your option) any later version. |
7225 | + * |
7226 | + * This program is distributed in the hope that it will be useful, |
7227 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
7228 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
7229 | + * GNU General Public License for more details. |
7230 | + * |
7231 | + * You should have received a copy of the GNU General Public License |
7232 | + * along with this program; if not, write to the Free Software |
7233 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
7234 | + * |
7235 | + */ |
7236 | +#include <asm/insn.h> |
7237 | + |
7238 | +/* Attribute tables are generated from opcode map */ |
7239 | +#include "inat-tables.c" |
7240 | + |
7241 | +/* Attribute search APIs */ |
7242 | +insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode) |
7243 | +{ |
7244 | + return inat_primary_table[opcode]; |
7245 | +} |
7246 | + |
7247 | +int inat_get_last_prefix_id(insn_byte_t last_pfx) |
7248 | +{ |
7249 | + insn_attr_t lpfx_attr; |
7250 | + |
7251 | + lpfx_attr = inat_get_opcode_attribute(last_pfx); |
7252 | + return inat_last_prefix_id(lpfx_attr); |
7253 | +} |
7254 | + |
7255 | +insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id, |
7256 | + insn_attr_t esc_attr) |
7257 | +{ |
7258 | + const insn_attr_t *table; |
7259 | + int n; |
7260 | + |
7261 | + n = inat_escape_id(esc_attr); |
7262 | + |
7263 | + table = inat_escape_tables[n][0]; |
7264 | + if (!table) |
7265 | + return 0; |
7266 | + if (inat_has_variant(table[opcode]) && lpfx_id) { |
7267 | + table = inat_escape_tables[n][lpfx_id]; |
7268 | + if (!table) |
7269 | + return 0; |
7270 | + } |
7271 | + return table[opcode]; |
7272 | +} |
7273 | + |
7274 | +insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id, |
7275 | + insn_attr_t grp_attr) |
7276 | +{ |
7277 | + const insn_attr_t *table; |
7278 | + int n; |
7279 | + |
7280 | + n = inat_group_id(grp_attr); |
7281 | + |
7282 | + table = inat_group_tables[n][0]; |
7283 | + if (!table) |
7284 | + return inat_group_common_attribute(grp_attr); |
7285 | + if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) { |
7286 | + table = inat_group_tables[n][lpfx_id]; |
7287 | + if (!table) |
7288 | + return inat_group_common_attribute(grp_attr); |
7289 | + } |
7290 | + return table[X86_MODRM_REG(modrm)] | |
7291 | + inat_group_common_attribute(grp_attr); |
7292 | +} |
7293 | + |
7294 | +insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m, |
7295 | + insn_byte_t vex_p) |
7296 | +{ |
7297 | + const insn_attr_t *table; |
7298 | + if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX) |
7299 | + return 0; |
7300 | + /* At first, this checks the master table */ |
7301 | + table = inat_avx_tables[vex_m][0]; |
7302 | + if (!table) |
7303 | + return 0; |
7304 | + if (!inat_is_group(table[opcode]) && vex_p) { |
7305 | + /* If this is not a group, get attribute directly */ |
7306 | + table = inat_avx_tables[vex_m][vex_p]; |
7307 | + if (!table) |
7308 | + return 0; |
7309 | + } |
7310 | + return table[opcode]; |
7311 | +} |
7312 | + |
7313 | diff --git a/tools/objtool/arch/x86/lib/insn.c b/tools/objtool/arch/x86/lib/insn.c |
7314 | new file mode 100644 |
7315 | index 000000000000..1088eb8f3a5f |
7316 | --- /dev/null |
7317 | +++ b/tools/objtool/arch/x86/lib/insn.c |
7318 | @@ -0,0 +1,606 @@ |
7319 | +/* |
7320 | + * x86 instruction analysis |
7321 | + * |
7322 | + * This program is free software; you can redistribute it and/or modify |
7323 | + * it under the terms of the GNU General Public License as published by |
7324 | + * the Free Software Foundation; either version 2 of the License, or |
7325 | + * (at your option) any later version. |
7326 | + * |
7327 | + * This program is distributed in the hope that it will be useful, |
7328 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
7329 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
7330 | + * GNU General Public License for more details. |
7331 | + * |
7332 | + * You should have received a copy of the GNU General Public License |
7333 | + * along with this program; if not, write to the Free Software |
7334 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
7335 | + * |
7336 | + * Copyright (C) IBM Corporation, 2002, 2004, 2009 |
7337 | + */ |
7338 | + |
7339 | +#ifdef __KERNEL__ |
7340 | +#include <linux/string.h> |
7341 | +#else |
7342 | +#include <string.h> |
7343 | +#endif |
7344 | +#include <asm/inat.h> |
7345 | +#include <asm/insn.h> |
7346 | + |
7347 | +/* Verify next sizeof(t) bytes can be on the same instruction */ |
7348 | +#define validate_next(t, insn, n) \ |
7349 | + ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) |
7350 | + |
7351 | +#define __get_next(t, insn) \ |
7352 | + ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) |
7353 | + |
7354 | +#define __peek_nbyte_next(t, insn, n) \ |
7355 | + ({ t r = *(t*)((insn)->next_byte + n); r; }) |
7356 | + |
7357 | +#define get_next(t, insn) \ |
7358 | + ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) |
7359 | + |
7360 | +#define peek_nbyte_next(t, insn, n) \ |
7361 | + ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); }) |
7362 | + |
7363 | +#define peek_next(t, insn) peek_nbyte_next(t, insn, 0) |
7364 | + |
7365 | +/** |
7366 | + * insn_init() - initialize struct insn |
7367 | + * @insn: &struct insn to be initialized |
7368 | + * @kaddr: address (in kernel memory) of instruction (or copy thereof) |
7369 | + * @x86_64: !0 for 64-bit kernel or 64-bit app |
7370 | + */ |
7371 | +void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64) |
7372 | +{ |
7373 | + /* |
7374 | + * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid |
7375 | + * even if the input buffer is long enough to hold them. |
7376 | + */ |
7377 | + if (buf_len > MAX_INSN_SIZE) |
7378 | + buf_len = MAX_INSN_SIZE; |
7379 | + |
7380 | + memset(insn, 0, sizeof(*insn)); |
7381 | + insn->kaddr = kaddr; |
7382 | + insn->end_kaddr = kaddr + buf_len; |
7383 | + insn->next_byte = kaddr; |
7384 | + insn->x86_64 = x86_64 ? 1 : 0; |
7385 | + insn->opnd_bytes = 4; |
7386 | + if (x86_64) |
7387 | + insn->addr_bytes = 8; |
7388 | + else |
7389 | + insn->addr_bytes = 4; |
7390 | +} |
7391 | + |
7392 | +/** |
7393 | + * insn_get_prefixes - scan x86 instruction prefix bytes |
7394 | + * @insn: &struct insn containing instruction |
7395 | + * |
7396 | + * Populates the @insn->prefixes bitmap, and updates @insn->next_byte |
7397 | + * to point to the (first) opcode. No effect if @insn->prefixes.got |
7398 | + * is already set. |
7399 | + */ |
7400 | +void insn_get_prefixes(struct insn *insn) |
7401 | +{ |
7402 | + struct insn_field *prefixes = &insn->prefixes; |
7403 | + insn_attr_t attr; |
7404 | + insn_byte_t b, lb; |
7405 | + int i, nb; |
7406 | + |
7407 | + if (prefixes->got) |
7408 | + return; |
7409 | + |
7410 | + nb = 0; |
7411 | + lb = 0; |
7412 | + b = peek_next(insn_byte_t, insn); |
7413 | + attr = inat_get_opcode_attribute(b); |
7414 | + while (inat_is_legacy_prefix(attr)) { |
7415 | + /* Skip if same prefix */ |
7416 | + for (i = 0; i < nb; i++) |
7417 | + if (prefixes->bytes[i] == b) |
7418 | + goto found; |
7419 | + if (nb == 4) |
7420 | + /* Invalid instruction */ |
7421 | + break; |
7422 | + prefixes->bytes[nb++] = b; |
7423 | + if (inat_is_address_size_prefix(attr)) { |
7424 | + /* address size switches 2/4 or 4/8 */ |
7425 | + if (insn->x86_64) |
7426 | + insn->addr_bytes ^= 12; |
7427 | + else |
7428 | + insn->addr_bytes ^= 6; |
7429 | + } else if (inat_is_operand_size_prefix(attr)) { |
7430 | + /* oprand size switches 2/4 */ |
7431 | + insn->opnd_bytes ^= 6; |
7432 | + } |
7433 | +found: |
7434 | + prefixes->nbytes++; |
7435 | + insn->next_byte++; |
7436 | + lb = b; |
7437 | + b = peek_next(insn_byte_t, insn); |
7438 | + attr = inat_get_opcode_attribute(b); |
7439 | + } |
7440 | + /* Set the last prefix */ |
7441 | + if (lb && lb != insn->prefixes.bytes[3]) { |
7442 | + if (unlikely(insn->prefixes.bytes[3])) { |
7443 | + /* Swap the last prefix */ |
7444 | + b = insn->prefixes.bytes[3]; |
7445 | + for (i = 0; i < nb; i++) |
7446 | + if (prefixes->bytes[i] == lb) |
7447 | + prefixes->bytes[i] = b; |
7448 | + } |
7449 | + insn->prefixes.bytes[3] = lb; |
7450 | + } |
7451 | + |
7452 | + /* Decode REX prefix */ |
7453 | + if (insn->x86_64) { |
7454 | + b = peek_next(insn_byte_t, insn); |
7455 | + attr = inat_get_opcode_attribute(b); |
7456 | + if (inat_is_rex_prefix(attr)) { |
7457 | + insn->rex_prefix.value = b; |
7458 | + insn->rex_prefix.nbytes = 1; |
7459 | + insn->next_byte++; |
7460 | + if (X86_REX_W(b)) |
7461 | + /* REX.W overrides opnd_size */ |
7462 | + insn->opnd_bytes = 8; |
7463 | + } |
7464 | + } |
7465 | + insn->rex_prefix.got = 1; |
7466 | + |
7467 | + /* Decode VEX prefix */ |
7468 | + b = peek_next(insn_byte_t, insn); |
7469 | + attr = inat_get_opcode_attribute(b); |
7470 | + if (inat_is_vex_prefix(attr)) { |
7471 | + insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1); |
7472 | + if (!insn->x86_64) { |
7473 | + /* |
7474 | + * In 32-bits mode, if the [7:6] bits (mod bits of |
7475 | + * ModRM) on the second byte are not 11b, it is |
7476 | + * LDS or LES or BOUND. |
7477 | + */ |
7478 | + if (X86_MODRM_MOD(b2) != 3) |
7479 | + goto vex_end; |
7480 | + } |
7481 | + insn->vex_prefix.bytes[0] = b; |
7482 | + insn->vex_prefix.bytes[1] = b2; |
7483 | + if (inat_is_evex_prefix(attr)) { |
7484 | + b2 = peek_nbyte_next(insn_byte_t, insn, 2); |
7485 | + insn->vex_prefix.bytes[2] = b2; |
7486 | + b2 = peek_nbyte_next(insn_byte_t, insn, 3); |
7487 | + insn->vex_prefix.bytes[3] = b2; |
7488 | + insn->vex_prefix.nbytes = 4; |
7489 | + insn->next_byte += 4; |
7490 | + if (insn->x86_64 && X86_VEX_W(b2)) |
7491 | + /* VEX.W overrides opnd_size */ |
7492 | + insn->opnd_bytes = 8; |
7493 | + } else if (inat_is_vex3_prefix(attr)) { |
7494 | + b2 = peek_nbyte_next(insn_byte_t, insn, 2); |
7495 | + insn->vex_prefix.bytes[2] = b2; |
7496 | + insn->vex_prefix.nbytes = 3; |
7497 | + insn->next_byte += 3; |
7498 | + if (insn->x86_64 && X86_VEX_W(b2)) |
7499 | + /* VEX.W overrides opnd_size */ |
7500 | + insn->opnd_bytes = 8; |
7501 | + } else { |
7502 | + /* |
7503 | + * For VEX2, fake VEX3-like byte#2. |
7504 | + * Makes it easier to decode vex.W, vex.vvvv, |
7505 | + * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0. |
7506 | + */ |
7507 | + insn->vex_prefix.bytes[2] = b2 & 0x7f; |
7508 | + insn->vex_prefix.nbytes = 2; |
7509 | + insn->next_byte += 2; |
7510 | + } |
7511 | + } |
7512 | +vex_end: |
7513 | + insn->vex_prefix.got = 1; |
7514 | + |
7515 | + prefixes->got = 1; |
7516 | + |
7517 | +err_out: |
7518 | + return; |
7519 | +} |
7520 | + |
7521 | +/** |
7522 | + * insn_get_opcode - collect opcode(s) |
7523 | + * @insn: &struct insn containing instruction |
7524 | + * |
7525 | + * Populates @insn->opcode, updates @insn->next_byte to point past the |
7526 | + * opcode byte(s), and set @insn->attr (except for groups). |
7527 | + * If necessary, first collects any preceding (prefix) bytes. |
7528 | + * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got |
7529 | + * is already 1. |
7530 | + */ |
7531 | +void insn_get_opcode(struct insn *insn) |
7532 | +{ |
7533 | + struct insn_field *opcode = &insn->opcode; |
7534 | + insn_byte_t op; |
7535 | + int pfx_id; |
7536 | + if (opcode->got) |
7537 | + return; |
7538 | + if (!insn->prefixes.got) |
7539 | + insn_get_prefixes(insn); |
7540 | + |
7541 | + /* Get first opcode */ |
7542 | + op = get_next(insn_byte_t, insn); |
7543 | + opcode->bytes[0] = op; |
7544 | + opcode->nbytes = 1; |
7545 | + |
7546 | + /* Check if there is VEX prefix or not */ |
7547 | + if (insn_is_avx(insn)) { |
7548 | + insn_byte_t m, p; |
7549 | + m = insn_vex_m_bits(insn); |
7550 | + p = insn_vex_p_bits(insn); |
7551 | + insn->attr = inat_get_avx_attribute(op, m, p); |
7552 | + if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) || |
7553 | + (!inat_accept_vex(insn->attr) && |
7554 | + !inat_is_group(insn->attr))) |
7555 | + insn->attr = 0; /* This instruction is bad */ |
7556 | + goto end; /* VEX has only 1 byte for opcode */ |
7557 | + } |
7558 | + |
7559 | + insn->attr = inat_get_opcode_attribute(op); |
7560 | + while (inat_is_escape(insn->attr)) { |
7561 | + /* Get escaped opcode */ |
7562 | + op = get_next(insn_byte_t, insn); |
7563 | + opcode->bytes[opcode->nbytes++] = op; |
7564 | + pfx_id = insn_last_prefix_id(insn); |
7565 | + insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr); |
7566 | + } |
7567 | + if (inat_must_vex(insn->attr)) |
7568 | + insn->attr = 0; /* This instruction is bad */ |
7569 | +end: |
7570 | + opcode->got = 1; |
7571 | + |
7572 | +err_out: |
7573 | + return; |
7574 | +} |
7575 | + |
7576 | +/** |
7577 | + * insn_get_modrm - collect ModRM byte, if any |
7578 | + * @insn: &struct insn containing instruction |
7579 | + * |
7580 | + * Populates @insn->modrm and updates @insn->next_byte to point past the |
7581 | + * ModRM byte, if any. If necessary, first collects the preceding bytes |
7582 | + * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1. |
7583 | + */ |
7584 | +void insn_get_modrm(struct insn *insn) |
7585 | +{ |
7586 | + struct insn_field *modrm = &insn->modrm; |
7587 | + insn_byte_t pfx_id, mod; |
7588 | + if (modrm->got) |
7589 | + return; |
7590 | + if (!insn->opcode.got) |
7591 | + insn_get_opcode(insn); |
7592 | + |
7593 | + if (inat_has_modrm(insn->attr)) { |
7594 | + mod = get_next(insn_byte_t, insn); |
7595 | + modrm->value = mod; |
7596 | + modrm->nbytes = 1; |
7597 | + if (inat_is_group(insn->attr)) { |
7598 | + pfx_id = insn_last_prefix_id(insn); |
7599 | + insn->attr = inat_get_group_attribute(mod, pfx_id, |
7600 | + insn->attr); |
7601 | + if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) |
7602 | + insn->attr = 0; /* This is bad */ |
7603 | + } |
7604 | + } |
7605 | + |
7606 | + if (insn->x86_64 && inat_is_force64(insn->attr)) |
7607 | + insn->opnd_bytes = 8; |
7608 | + modrm->got = 1; |
7609 | + |
7610 | +err_out: |
7611 | + return; |
7612 | +} |
7613 | + |
7614 | + |
7615 | +/** |
7616 | + * insn_rip_relative() - Does instruction use RIP-relative addressing mode? |
7617 | + * @insn: &struct insn containing instruction |
7618 | + * |
7619 | + * If necessary, first collects the instruction up to and including the |
7620 | + * ModRM byte. No effect if @insn->x86_64 is 0. |
7621 | + */ |
7622 | +int insn_rip_relative(struct insn *insn) |
7623 | +{ |
7624 | + struct insn_field *modrm = &insn->modrm; |
7625 | + |
7626 | + if (!insn->x86_64) |
7627 | + return 0; |
7628 | + if (!modrm->got) |
7629 | + insn_get_modrm(insn); |
7630 | + /* |
7631 | + * For rip-relative instructions, the mod field (top 2 bits) |
7632 | + * is zero and the r/m field (bottom 3 bits) is 0x5. |
7633 | + */ |
7634 | + return (modrm->nbytes && (modrm->value & 0xc7) == 0x5); |
7635 | +} |
7636 | + |
7637 | +/** |
7638 | + * insn_get_sib() - Get the SIB byte of instruction |
7639 | + * @insn: &struct insn containing instruction |
7640 | + * |
7641 | + * If necessary, first collects the instruction up to and including the |
7642 | + * ModRM byte. |
7643 | + */ |
7644 | +void insn_get_sib(struct insn *insn) |
7645 | +{ |
7646 | + insn_byte_t modrm; |
7647 | + |
7648 | + if (insn->sib.got) |
7649 | + return; |
7650 | + if (!insn->modrm.got) |
7651 | + insn_get_modrm(insn); |
7652 | + if (insn->modrm.nbytes) { |
7653 | + modrm = (insn_byte_t)insn->modrm.value; |
7654 | + if (insn->addr_bytes != 2 && |
7655 | + X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) { |
7656 | + insn->sib.value = get_next(insn_byte_t, insn); |
7657 | + insn->sib.nbytes = 1; |
7658 | + } |
7659 | + } |
7660 | + insn->sib.got = 1; |
7661 | + |
7662 | +err_out: |
7663 | + return; |
7664 | +} |
7665 | + |
7666 | + |
7667 | +/** |
7668 | + * insn_get_displacement() - Get the displacement of instruction |
7669 | + * @insn: &struct insn containing instruction |
7670 | + * |
7671 | + * If necessary, first collects the instruction up to and including the |
7672 | + * SIB byte. |
7673 | + * Displacement value is sign-expanded. |
7674 | + */ |
7675 | +void insn_get_displacement(struct insn *insn) |
7676 | +{ |
7677 | + insn_byte_t mod, rm, base; |
7678 | + |
7679 | + if (insn->displacement.got) |
7680 | + return; |
7681 | + if (!insn->sib.got) |
7682 | + insn_get_sib(insn); |
7683 | + if (insn->modrm.nbytes) { |
7684 | + /* |
7685 | + * Interpreting the modrm byte: |
7686 | + * mod = 00 - no displacement fields (exceptions below) |
7687 | + * mod = 01 - 1-byte displacement field |
7688 | + * mod = 10 - displacement field is 4 bytes, or 2 bytes if |
7689 | + * address size = 2 (0x67 prefix in 32-bit mode) |
7690 | + * mod = 11 - no memory operand |
7691 | + * |
7692 | + * If address size = 2... |
7693 | + * mod = 00, r/m = 110 - displacement field is 2 bytes |
7694 | + * |
7695 | + * If address size != 2... |
7696 | + * mod != 11, r/m = 100 - SIB byte exists |
7697 | + * mod = 00, SIB base = 101 - displacement field is 4 bytes |
7698 | + * mod = 00, r/m = 101 - rip-relative addressing, displacement |
7699 | + * field is 4 bytes |
7700 | + */ |
7701 | + mod = X86_MODRM_MOD(insn->modrm.value); |
7702 | + rm = X86_MODRM_RM(insn->modrm.value); |
7703 | + base = X86_SIB_BASE(insn->sib.value); |
7704 | + if (mod == 3) |
7705 | + goto out; |
7706 | + if (mod == 1) { |
7707 | + insn->displacement.value = get_next(signed char, insn); |
7708 | + insn->displacement.nbytes = 1; |
7709 | + } else if (insn->addr_bytes == 2) { |
7710 | + if ((mod == 0 && rm == 6) || mod == 2) { |
7711 | + insn->displacement.value = |
7712 | + get_next(short, insn); |
7713 | + insn->displacement.nbytes = 2; |
7714 | + } |
7715 | + } else { |
7716 | + if ((mod == 0 && rm == 5) || mod == 2 || |
7717 | + (mod == 0 && base == 5)) { |
7718 | + insn->displacement.value = get_next(int, insn); |
7719 | + insn->displacement.nbytes = 4; |
7720 | + } |
7721 | + } |
7722 | + } |
7723 | +out: |
7724 | + insn->displacement.got = 1; |
7725 | + |
7726 | +err_out: |
7727 | + return; |
7728 | +} |
7729 | + |
7730 | +/* Decode moffset16/32/64. Return 0 if failed */ |
7731 | +static int __get_moffset(struct insn *insn) |
7732 | +{ |
7733 | + switch (insn->addr_bytes) { |
7734 | + case 2: |
7735 | + insn->moffset1.value = get_next(short, insn); |
7736 | + insn->moffset1.nbytes = 2; |
7737 | + break; |
7738 | + case 4: |
7739 | + insn->moffset1.value = get_next(int, insn); |
7740 | + insn->moffset1.nbytes = 4; |
7741 | + break; |
7742 | + case 8: |
7743 | + insn->moffset1.value = get_next(int, insn); |
7744 | + insn->moffset1.nbytes = 4; |
7745 | + insn->moffset2.value = get_next(int, insn); |
7746 | + insn->moffset2.nbytes = 4; |
7747 | + break; |
7748 | + default: /* opnd_bytes must be modified manually */ |
7749 | + goto err_out; |
7750 | + } |
7751 | + insn->moffset1.got = insn->moffset2.got = 1; |
7752 | + |
7753 | + return 1; |
7754 | + |
7755 | +err_out: |
7756 | + return 0; |
7757 | +} |
7758 | + |
7759 | +/* Decode imm v32(Iz). Return 0 if failed */ |
7760 | +static int __get_immv32(struct insn *insn) |
7761 | +{ |
7762 | + switch (insn->opnd_bytes) { |
7763 | + case 2: |
7764 | + insn->immediate.value = get_next(short, insn); |
7765 | + insn->immediate.nbytes = 2; |
7766 | + break; |
7767 | + case 4: |
7768 | + case 8: |
7769 | + insn->immediate.value = get_next(int, insn); |
7770 | + insn->immediate.nbytes = 4; |
7771 | + break; |
7772 | + default: /* opnd_bytes must be modified manually */ |
7773 | + goto err_out; |
7774 | + } |
7775 | + |
7776 | + return 1; |
7777 | + |
7778 | +err_out: |
7779 | + return 0; |
7780 | +} |
7781 | + |
7782 | +/* Decode imm v64(Iv/Ov), Return 0 if failed */ |
7783 | +static int __get_immv(struct insn *insn) |
7784 | +{ |
7785 | + switch (insn->opnd_bytes) { |
7786 | + case 2: |
7787 | + insn->immediate1.value = get_next(short, insn); |
7788 | + insn->immediate1.nbytes = 2; |
7789 | + break; |
7790 | + case 4: |
7791 | + insn->immediate1.value = get_next(int, insn); |
7792 | + insn->immediate1.nbytes = 4; |
7793 | + break; |
7794 | + case 8: |
7795 | + insn->immediate1.value = get_next(int, insn); |
7796 | + insn->immediate1.nbytes = 4; |
7797 | + insn->immediate2.value = get_next(int, insn); |
7798 | + insn->immediate2.nbytes = 4; |
7799 | + break; |
7800 | + default: /* opnd_bytes must be modified manually */ |
7801 | + goto err_out; |
7802 | + } |
7803 | + insn->immediate1.got = insn->immediate2.got = 1; |
7804 | + |
7805 | + return 1; |
7806 | +err_out: |
7807 | + return 0; |
7808 | +} |
7809 | + |
7810 | +/* Decode ptr16:16/32(Ap) */ |
7811 | +static int __get_immptr(struct insn *insn) |
7812 | +{ |
7813 | + switch (insn->opnd_bytes) { |
7814 | + case 2: |
7815 | + insn->immediate1.value = get_next(short, insn); |
7816 | + insn->immediate1.nbytes = 2; |
7817 | + break; |
7818 | + case 4: |
7819 | + insn->immediate1.value = get_next(int, insn); |
7820 | + insn->immediate1.nbytes = 4; |
7821 | + break; |
7822 | + case 8: |
7823 | + /* ptr16:64 is not exist (no segment) */ |
7824 | + return 0; |
7825 | + default: /* opnd_bytes must be modified manually */ |
7826 | + goto err_out; |
7827 | + } |
7828 | + insn->immediate2.value = get_next(unsigned short, insn); |
7829 | + insn->immediate2.nbytes = 2; |
7830 | + insn->immediate1.got = insn->immediate2.got = 1; |
7831 | + |
7832 | + return 1; |
7833 | +err_out: |
7834 | + return 0; |
7835 | +} |
7836 | + |
7837 | +/** |
7838 | + * insn_get_immediate() - Get the immediates of instruction |
7839 | + * @insn: &struct insn containing instruction |
7840 | + * |
7841 | + * If necessary, first collects the instruction up to and including the |
7842 | + * displacement bytes. |
7843 | + * Basically, most of immediates are sign-expanded. Unsigned-value can be |
7844 | + * get by bit masking with ((1 << (nbytes * 8)) - 1) |
7845 | + */ |
7846 | +void insn_get_immediate(struct insn *insn) |
7847 | +{ |
7848 | + if (insn->immediate.got) |
7849 | + return; |
7850 | + if (!insn->displacement.got) |
7851 | + insn_get_displacement(insn); |
7852 | + |
7853 | + if (inat_has_moffset(insn->attr)) { |
7854 | + if (!__get_moffset(insn)) |
7855 | + goto err_out; |
7856 | + goto done; |
7857 | + } |
7858 | + |
7859 | + if (!inat_has_immediate(insn->attr)) |
7860 | + /* no immediates */ |
7861 | + goto done; |
7862 | + |
7863 | + switch (inat_immediate_size(insn->attr)) { |
7864 | + case INAT_IMM_BYTE: |
7865 | + insn->immediate.value = get_next(signed char, insn); |
7866 | + insn->immediate.nbytes = 1; |
7867 | + break; |
7868 | + case INAT_IMM_WORD: |
7869 | + insn->immediate.value = get_next(short, insn); |
7870 | + insn->immediate.nbytes = 2; |
7871 | + break; |
7872 | + case INAT_IMM_DWORD: |
7873 | + insn->immediate.value = get_next(int, insn); |
7874 | + insn->immediate.nbytes = 4; |
7875 | + break; |
7876 | + case INAT_IMM_QWORD: |
7877 | + insn->immediate1.value = get_next(int, insn); |
7878 | + insn->immediate1.nbytes = 4; |
7879 | + insn->immediate2.value = get_next(int, insn); |
7880 | + insn->immediate2.nbytes = 4; |
7881 | + break; |
7882 | + case INAT_IMM_PTR: |
7883 | + if (!__get_immptr(insn)) |
7884 | + goto err_out; |
7885 | + break; |
7886 | + case INAT_IMM_VWORD32: |
7887 | + if (!__get_immv32(insn)) |
7888 | + goto err_out; |
7889 | + break; |
7890 | + case INAT_IMM_VWORD: |
7891 | + if (!__get_immv(insn)) |
7892 | + goto err_out; |
7893 | + break; |
7894 | + default: |
7895 | + /* Here, insn must have an immediate, but failed */ |
7896 | + goto err_out; |
7897 | + } |
7898 | + if (inat_has_second_immediate(insn->attr)) { |
7899 | + insn->immediate2.value = get_next(signed char, insn); |
7900 | + insn->immediate2.nbytes = 1; |
7901 | + } |
7902 | +done: |
7903 | + insn->immediate.got = 1; |
7904 | + |
7905 | +err_out: |
7906 | + return; |
7907 | +} |
7908 | + |
7909 | +/** |
7910 | + * insn_get_length() - Get the length of instruction |
7911 | + * @insn: &struct insn containing instruction |
7912 | + * |
7913 | + * If necessary, first collects the instruction up to and including the |
7914 | + * immediates bytes. |
7915 | + */ |
7916 | +void insn_get_length(struct insn *insn) |
7917 | +{ |
7918 | + if (insn->length) |
7919 | + return; |
7920 | + if (!insn->immediate.got) |
7921 | + insn_get_immediate(insn); |
7922 | + insn->length = (unsigned char)((unsigned long)insn->next_byte |
7923 | + - (unsigned long)insn->kaddr); |
7924 | +} |
7925 | diff --git a/tools/objtool/arch/x86/lib/x86-opcode-map.txt b/tools/objtool/arch/x86/lib/x86-opcode-map.txt |
7926 | new file mode 100644 |
7927 | index 000000000000..e0b85930dd77 |
7928 | --- /dev/null |
7929 | +++ b/tools/objtool/arch/x86/lib/x86-opcode-map.txt |
7930 | @@ -0,0 +1,1072 @@ |
7931 | +# x86 Opcode Maps |
7932 | +# |
7933 | +# This is (mostly) based on following documentations. |
7934 | +# - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C |
7935 | +# (#326018-047US, June 2013) |
7936 | +# |
7937 | +#<Opcode maps> |
7938 | +# Table: table-name |
7939 | +# Referrer: escaped-name |
7940 | +# AVXcode: avx-code |
7941 | +# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] |
7942 | +# (or) |
7943 | +# opcode: escape # escaped-name |
7944 | +# EndTable |
7945 | +# |
7946 | +# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix |
7947 | +# mnemonics that begin with lowercase 'k' accept a VEX prefix |
7948 | +# |
7949 | +#<group maps> |
7950 | +# GrpTable: GrpXXX |
7951 | +# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] |
7952 | +# EndTable |
7953 | +# |
7954 | +# AVX Superscripts |
7955 | +# (ev): this opcode requires EVEX prefix. |
7956 | +# (evo): this opcode is changed by EVEX prefix (EVEX opcode) |
7957 | +# (v): this opcode requires VEX prefix. |
7958 | +# (v1): this opcode only supports 128bit VEX. |
7959 | +# |
7960 | +# Last Prefix Superscripts |
7961 | +# - (66): the last prefix is 0x66 |
7962 | +# - (F3): the last prefix is 0xF3 |
7963 | +# - (F2): the last prefix is 0xF2 |
7964 | +# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) |
7965 | +# - (66&F2): Both 0x66 and 0xF2 prefixes are specified. |
7966 | + |
7967 | +Table: one byte opcode |
7968 | +Referrer: |
7969 | +AVXcode: |
7970 | +# 0x00 - 0x0f |
7971 | +00: ADD Eb,Gb |
7972 | +01: ADD Ev,Gv |
7973 | +02: ADD Gb,Eb |
7974 | +03: ADD Gv,Ev |
7975 | +04: ADD AL,Ib |
7976 | +05: ADD rAX,Iz |
7977 | +06: PUSH ES (i64) |
7978 | +07: POP ES (i64) |
7979 | +08: OR Eb,Gb |
7980 | +09: OR Ev,Gv |
7981 | +0a: OR Gb,Eb |
7982 | +0b: OR Gv,Ev |
7983 | +0c: OR AL,Ib |
7984 | +0d: OR rAX,Iz |
7985 | +0e: PUSH CS (i64) |
7986 | +0f: escape # 2-byte escape |
7987 | +# 0x10 - 0x1f |
7988 | +10: ADC Eb,Gb |
7989 | +11: ADC Ev,Gv |
7990 | +12: ADC Gb,Eb |
7991 | +13: ADC Gv,Ev |
7992 | +14: ADC AL,Ib |
7993 | +15: ADC rAX,Iz |
7994 | +16: PUSH SS (i64) |
7995 | +17: POP SS (i64) |
7996 | +18: SBB Eb,Gb |
7997 | +19: SBB Ev,Gv |
7998 | +1a: SBB Gb,Eb |
7999 | +1b: SBB Gv,Ev |
8000 | +1c: SBB AL,Ib |
8001 | +1d: SBB rAX,Iz |
8002 | +1e: PUSH DS (i64) |
8003 | +1f: POP DS (i64) |
8004 | +# 0x20 - 0x2f |
8005 | +20: AND Eb,Gb |
8006 | +21: AND Ev,Gv |
8007 | +22: AND Gb,Eb |
8008 | +23: AND Gv,Ev |
8009 | +24: AND AL,Ib |
8010 | +25: AND rAx,Iz |
8011 | +26: SEG=ES (Prefix) |
8012 | +27: DAA (i64) |
8013 | +28: SUB Eb,Gb |
8014 | +29: SUB Ev,Gv |
8015 | +2a: SUB Gb,Eb |
8016 | +2b: SUB Gv,Ev |
8017 | +2c: SUB AL,Ib |
8018 | +2d: SUB rAX,Iz |
8019 | +2e: SEG=CS (Prefix) |
8020 | +2f: DAS (i64) |
8021 | +# 0x30 - 0x3f |
8022 | +30: XOR Eb,Gb |
8023 | +31: XOR Ev,Gv |
8024 | +32: XOR Gb,Eb |
8025 | +33: XOR Gv,Ev |
8026 | +34: XOR AL,Ib |
8027 | +35: XOR rAX,Iz |
8028 | +36: SEG=SS (Prefix) |
8029 | +37: AAA (i64) |
8030 | +38: CMP Eb,Gb |
8031 | +39: CMP Ev,Gv |
8032 | +3a: CMP Gb,Eb |
8033 | +3b: CMP Gv,Ev |
8034 | +3c: CMP AL,Ib |
8035 | +3d: CMP rAX,Iz |
8036 | +3e: SEG=DS (Prefix) |
8037 | +3f: AAS (i64) |
8038 | +# 0x40 - 0x4f |
8039 | +40: INC eAX (i64) | REX (o64) |
8040 | +41: INC eCX (i64) | REX.B (o64) |
8041 | +42: INC eDX (i64) | REX.X (o64) |
8042 | +43: INC eBX (i64) | REX.XB (o64) |
8043 | +44: INC eSP (i64) | REX.R (o64) |
8044 | +45: INC eBP (i64) | REX.RB (o64) |
8045 | +46: INC eSI (i64) | REX.RX (o64) |
8046 | +47: INC eDI (i64) | REX.RXB (o64) |
8047 | +48: DEC eAX (i64) | REX.W (o64) |
8048 | +49: DEC eCX (i64) | REX.WB (o64) |
8049 | +4a: DEC eDX (i64) | REX.WX (o64) |
8050 | +4b: DEC eBX (i64) | REX.WXB (o64) |
8051 | +4c: DEC eSP (i64) | REX.WR (o64) |
8052 | +4d: DEC eBP (i64) | REX.WRB (o64) |
8053 | +4e: DEC eSI (i64) | REX.WRX (o64) |
8054 | +4f: DEC eDI (i64) | REX.WRXB (o64) |
8055 | +# 0x50 - 0x5f |
8056 | +50: PUSH rAX/r8 (d64) |
8057 | +51: PUSH rCX/r9 (d64) |
8058 | +52: PUSH rDX/r10 (d64) |
8059 | +53: PUSH rBX/r11 (d64) |
8060 | +54: PUSH rSP/r12 (d64) |
8061 | +55: PUSH rBP/r13 (d64) |
8062 | +56: PUSH rSI/r14 (d64) |
8063 | +57: PUSH rDI/r15 (d64) |
8064 | +58: POP rAX/r8 (d64) |
8065 | +59: POP rCX/r9 (d64) |
8066 | +5a: POP rDX/r10 (d64) |
8067 | +5b: POP rBX/r11 (d64) |
8068 | +5c: POP rSP/r12 (d64) |
8069 | +5d: POP rBP/r13 (d64) |
8070 | +5e: POP rSI/r14 (d64) |
8071 | +5f: POP rDI/r15 (d64) |
8072 | +# 0x60 - 0x6f |
8073 | +60: PUSHA/PUSHAD (i64) |
8074 | +61: POPA/POPAD (i64) |
8075 | +62: BOUND Gv,Ma (i64) | EVEX (Prefix) |
8076 | +63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64) |
8077 | +64: SEG=FS (Prefix) |
8078 | +65: SEG=GS (Prefix) |
8079 | +66: Operand-Size (Prefix) |
8080 | +67: Address-Size (Prefix) |
8081 | +68: PUSH Iz (d64) |
8082 | +69: IMUL Gv,Ev,Iz |
8083 | +6a: PUSH Ib (d64) |
8084 | +6b: IMUL Gv,Ev,Ib |
8085 | +6c: INS/INSB Yb,DX |
8086 | +6d: INS/INSW/INSD Yz,DX |
8087 | +6e: OUTS/OUTSB DX,Xb |
8088 | +6f: OUTS/OUTSW/OUTSD DX,Xz |
8089 | +# 0x70 - 0x7f |
8090 | +70: JO Jb |
8091 | +71: JNO Jb |
8092 | +72: JB/JNAE/JC Jb |
8093 | +73: JNB/JAE/JNC Jb |
8094 | +74: JZ/JE Jb |
8095 | +75: JNZ/JNE Jb |
8096 | +76: JBE/JNA Jb |
8097 | +77: JNBE/JA Jb |
8098 | +78: JS Jb |
8099 | +79: JNS Jb |
8100 | +7a: JP/JPE Jb |
8101 | +7b: JNP/JPO Jb |
8102 | +7c: JL/JNGE Jb |
8103 | +7d: JNL/JGE Jb |
8104 | +7e: JLE/JNG Jb |
8105 | +7f: JNLE/JG Jb |
8106 | +# 0x80 - 0x8f |
8107 | +80: Grp1 Eb,Ib (1A) |
8108 | +81: Grp1 Ev,Iz (1A) |
8109 | +82: Grp1 Eb,Ib (1A),(i64) |
8110 | +83: Grp1 Ev,Ib (1A) |
8111 | +84: TEST Eb,Gb |
8112 | +85: TEST Ev,Gv |
8113 | +86: XCHG Eb,Gb |
8114 | +87: XCHG Ev,Gv |
8115 | +88: MOV Eb,Gb |
8116 | +89: MOV Ev,Gv |
8117 | +8a: MOV Gb,Eb |
8118 | +8b: MOV Gv,Ev |
8119 | +8c: MOV Ev,Sw |
8120 | +8d: LEA Gv,M |
8121 | +8e: MOV Sw,Ew |
8122 | +8f: Grp1A (1A) | POP Ev (d64) |
8123 | +# 0x90 - 0x9f |
8124 | +90: NOP | PAUSE (F3) | XCHG r8,rAX |
8125 | +91: XCHG rCX/r9,rAX |
8126 | +92: XCHG rDX/r10,rAX |
8127 | +93: XCHG rBX/r11,rAX |
8128 | +94: XCHG rSP/r12,rAX |
8129 | +95: XCHG rBP/r13,rAX |
8130 | +96: XCHG rSI/r14,rAX |
8131 | +97: XCHG rDI/r15,rAX |
8132 | +98: CBW/CWDE/CDQE |
8133 | +99: CWD/CDQ/CQO |
8134 | +9a: CALLF Ap (i64) |
8135 | +9b: FWAIT/WAIT |
8136 | +9c: PUSHF/D/Q Fv (d64) |
8137 | +9d: POPF/D/Q Fv (d64) |
8138 | +9e: SAHF |
8139 | +9f: LAHF |
8140 | +# 0xa0 - 0xaf |
8141 | +a0: MOV AL,Ob |
8142 | +a1: MOV rAX,Ov |
8143 | +a2: MOV Ob,AL |
8144 | +a3: MOV Ov,rAX |
8145 | +a4: MOVS/B Yb,Xb |
8146 | +a5: MOVS/W/D/Q Yv,Xv |
8147 | +a6: CMPS/B Xb,Yb |
8148 | +a7: CMPS/W/D Xv,Yv |
8149 | +a8: TEST AL,Ib |
8150 | +a9: TEST rAX,Iz |
8151 | +aa: STOS/B Yb,AL |
8152 | +ab: STOS/W/D/Q Yv,rAX |
8153 | +ac: LODS/B AL,Xb |
8154 | +ad: LODS/W/D/Q rAX,Xv |
8155 | +ae: SCAS/B AL,Yb |
8156 | +# Note: The May 2011 Intel manual shows Xv for the second parameter of the |
8157 | +# next instruction but Yv is correct |
8158 | +af: SCAS/W/D/Q rAX,Yv |
8159 | +# 0xb0 - 0xbf |
8160 | +b0: MOV AL/R8L,Ib |
8161 | +b1: MOV CL/R9L,Ib |
8162 | +b2: MOV DL/R10L,Ib |
8163 | +b3: MOV BL/R11L,Ib |
8164 | +b4: MOV AH/R12L,Ib |
8165 | +b5: MOV CH/R13L,Ib |
8166 | +b6: MOV DH/R14L,Ib |
8167 | +b7: MOV BH/R15L,Ib |
8168 | +b8: MOV rAX/r8,Iv |
8169 | +b9: MOV rCX/r9,Iv |
8170 | +ba: MOV rDX/r10,Iv |
8171 | +bb: MOV rBX/r11,Iv |
8172 | +bc: MOV rSP/r12,Iv |
8173 | +bd: MOV rBP/r13,Iv |
8174 | +be: MOV rSI/r14,Iv |
8175 | +bf: MOV rDI/r15,Iv |
8176 | +# 0xc0 - 0xcf |
8177 | +c0: Grp2 Eb,Ib (1A) |
8178 | +c1: Grp2 Ev,Ib (1A) |
8179 | +c2: RETN Iw (f64) |
8180 | +c3: RETN |
8181 | +c4: LES Gz,Mp (i64) | VEX+2byte (Prefix) |
8182 | +c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix) |
8183 | +c6: Grp11A Eb,Ib (1A) |
8184 | +c7: Grp11B Ev,Iz (1A) |
8185 | +c8: ENTER Iw,Ib |
8186 | +c9: LEAVE (d64) |
8187 | +ca: RETF Iw |
8188 | +cb: RETF |
8189 | +cc: INT3 |
8190 | +cd: INT Ib |
8191 | +ce: INTO (i64) |
8192 | +cf: IRET/D/Q |
8193 | +# 0xd0 - 0xdf |
8194 | +d0: Grp2 Eb,1 (1A) |
8195 | +d1: Grp2 Ev,1 (1A) |
8196 | +d2: Grp2 Eb,CL (1A) |
8197 | +d3: Grp2 Ev,CL (1A) |
8198 | +d4: AAM Ib (i64) |
8199 | +d5: AAD Ib (i64) |
8200 | +d6: |
8201 | +d7: XLAT/XLATB |
8202 | +d8: ESC |
8203 | +d9: ESC |
8204 | +da: ESC |
8205 | +db: ESC |
8206 | +dc: ESC |
8207 | +dd: ESC |
8208 | +de: ESC |
8209 | +df: ESC |
8210 | +# 0xe0 - 0xef |
8211 | +# Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix |
8212 | +# in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation |
8213 | +# to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD. |
8214 | +e0: LOOPNE/LOOPNZ Jb (f64) |
8215 | +e1: LOOPE/LOOPZ Jb (f64) |
8216 | +e2: LOOP Jb (f64) |
8217 | +e3: JrCXZ Jb (f64) |
8218 | +e4: IN AL,Ib |
8219 | +e5: IN eAX,Ib |
8220 | +e6: OUT Ib,AL |
8221 | +e7: OUT Ib,eAX |
8222 | +# With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset |
8223 | +# in "near" jumps and calls is 16-bit. For CALL, |
8224 | +# push of return address is 16-bit wide, RSP is decremented by 2 |
8225 | +# but is not truncated to 16 bits, unlike RIP. |
8226 | +e8: CALL Jz (f64) |
8227 | +e9: JMP-near Jz (f64) |
8228 | +ea: JMP-far Ap (i64) |
8229 | +eb: JMP-short Jb (f64) |
8230 | +ec: IN AL,DX |
8231 | +ed: IN eAX,DX |
8232 | +ee: OUT DX,AL |
8233 | +ef: OUT DX,eAX |
8234 | +# 0xf0 - 0xff |
8235 | +f0: LOCK (Prefix) |
8236 | +f1: |
8237 | +f2: REPNE (Prefix) | XACQUIRE (Prefix) |
8238 | +f3: REP/REPE (Prefix) | XRELEASE (Prefix) |
8239 | +f4: HLT |
8240 | +f5: CMC |
8241 | +f6: Grp3_1 Eb (1A) |
8242 | +f7: Grp3_2 Ev (1A) |
8243 | +f8: CLC |
8244 | +f9: STC |
8245 | +fa: CLI |
8246 | +fb: STI |
8247 | +fc: CLD |
8248 | +fd: STD |
8249 | +fe: Grp4 (1A) |
8250 | +ff: Grp5 (1A) |
8251 | +EndTable |
8252 | + |
8253 | +Table: 2-byte opcode (0x0f) |
8254 | +Referrer: 2-byte escape |
8255 | +AVXcode: 1 |
8256 | +# 0x0f 0x00-0x0f |
8257 | +00: Grp6 (1A) |
8258 | +01: Grp7 (1A) |
8259 | +02: LAR Gv,Ew |
8260 | +03: LSL Gv,Ew |
8261 | +04: |
8262 | +05: SYSCALL (o64) |
8263 | +06: CLTS |
8264 | +07: SYSRET (o64) |
8265 | +08: INVD |
8266 | +09: WBINVD |
8267 | +0a: |
8268 | +0b: UD2 (1B) |
8269 | +0c: |
8270 | +# AMD's prefetch group. Intel supports prefetchw(/1) only. |
8271 | +0d: GrpP |
8272 | +0e: FEMMS |
8273 | +# 3DNow! uses the last imm byte as opcode extension. |
8274 | +0f: 3DNow! Pq,Qq,Ib |
8275 | +# 0x0f 0x10-0x1f |
8276 | +# NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands |
8277 | +# but it actually has operands. And also, vmovss and vmovsd only accept 128bit. |
8278 | +# MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form. |
8279 | +# Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming |
8280 | +# Reference A.1 |
8281 | +10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1) |
8282 | +11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1) |
8283 | +12: vmovlps Vq,Hq,Mq (v1) | vmovhlps Vq,Hq,Uq (v1) | vmovlpd Vq,Hq,Mq (66),(v1) | vmovsldup Vx,Wx (F3) | vmovddup Vx,Wx (F2) |
8284 | +13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1) |
8285 | +14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66) |
8286 | +15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66) |
8287 | +16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3) |
8288 | +17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1) |
8289 | +18: Grp16 (1A) |
8290 | +19: |
8291 | +# Intel SDM opcode map does not list MPX instructions. For now using Gv for |
8292 | +# bnd registers and Ev for everything else is OK because the instruction |
8293 | +# decoder does not use the information except as an indication that there is |
8294 | +# a ModR/M byte. |
8295 | +1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev |
8296 | +1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv |
8297 | +1c: |
8298 | +1d: |
8299 | +1e: |
8300 | +1f: NOP Ev |
8301 | +# 0x0f 0x20-0x2f |
8302 | +20: MOV Rd,Cd |
8303 | +21: MOV Rd,Dd |
8304 | +22: MOV Cd,Rd |
8305 | +23: MOV Dd,Rd |
8306 | +24: |
8307 | +25: |
8308 | +26: |
8309 | +27: |
8310 | +28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66) |
8311 | +29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66) |
8312 | +2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1) |
8313 | +2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66) |
8314 | +2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1) |
8315 | +2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1) |
8316 | +2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1) |
8317 | +2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1) |
8318 | +# 0x0f 0x30-0x3f |
8319 | +30: WRMSR |
8320 | +31: RDTSC |
8321 | +32: RDMSR |
8322 | +33: RDPMC |
8323 | +34: SYSENTER |
8324 | +35: SYSEXIT |
8325 | +36: |
8326 | +37: GETSEC |
8327 | +38: escape # 3-byte escape 1 |
8328 | +39: |
8329 | +3a: escape # 3-byte escape 2 |
8330 | +3b: |
8331 | +3c: |
8332 | +3d: |
8333 | +3e: |
8334 | +3f: |
8335 | +# 0x0f 0x40-0x4f |
8336 | +40: CMOVO Gv,Ev |
8337 | +41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66) |
8338 | +42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66) |
8339 | +43: CMOVAE/NB/NC Gv,Ev |
8340 | +44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66) |
8341 | +45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66) |
8342 | +46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66) |
8343 | +47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66) |
8344 | +48: CMOVS Gv,Ev |
8345 | +49: CMOVNS Gv,Ev |
8346 | +4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66) |
8347 | +4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk |
8348 | +4c: CMOVL/NGE Gv,Ev |
8349 | +4d: CMOVNL/GE Gv,Ev |
8350 | +4e: CMOVLE/NG Gv,Ev |
8351 | +4f: CMOVNLE/G Gv,Ev |
8352 | +# 0x0f 0x50-0x5f |
8353 | +50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66) |
8354 | +51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1) |
8355 | +52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1) |
8356 | +53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1) |
8357 | +54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66) |
8358 | +55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66) |
8359 | +56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66) |
8360 | +57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66) |
8361 | +58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1) |
8362 | +59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1) |
8363 | +5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1) |
8364 | +5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3) |
8365 | +5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1) |
8366 | +5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1) |
8367 | +5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1) |
8368 | +5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1) |
8369 | +# 0x0f 0x60-0x6f |
8370 | +60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1) |
8371 | +61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1) |
8372 | +62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1) |
8373 | +63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1) |
8374 | +64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1) |
8375 | +65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1) |
8376 | +66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1) |
8377 | +67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1) |
8378 | +68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1) |
8379 | +69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1) |
8380 | +6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1) |
8381 | +6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1) |
8382 | +6c: vpunpcklqdq Vx,Hx,Wx (66),(v1) |
8383 | +6d: vpunpckhqdq Vx,Hx,Wx (66),(v1) |
8384 | +6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1) |
8385 | +6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev) |
8386 | +# 0x0f 0x70-0x7f |
8387 | +70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1) |
8388 | +71: Grp12 (1A) |
8389 | +72: Grp13 (1A) |
8390 | +73: Grp14 (1A) |
8391 | +74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1) |
8392 | +75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1) |
8393 | +76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1) |
8394 | +# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX. |
8395 | +77: emms | vzeroupper | vzeroall |
8396 | +78: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev) |
8397 | +79: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev) |
8398 | +7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev) |
8399 | +7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev) |
8400 | +7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2) |
8401 | +7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2) |
8402 | +7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1) |
8403 | +7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev) |
8404 | +# 0x0f 0x80-0x8f |
8405 | +# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). |
8406 | +80: JO Jz (f64) |
8407 | +81: JNO Jz (f64) |
8408 | +82: JB/JC/JNAE Jz (f64) |
8409 | +83: JAE/JNB/JNC Jz (f64) |
8410 | +84: JE/JZ Jz (f64) |
8411 | +85: JNE/JNZ Jz (f64) |
8412 | +86: JBE/JNA Jz (f64) |
8413 | +87: JA/JNBE Jz (f64) |
8414 | +88: JS Jz (f64) |
8415 | +89: JNS Jz (f64) |
8416 | +8a: JP/JPE Jz (f64) |
8417 | +8b: JNP/JPO Jz (f64) |
8418 | +8c: JL/JNGE Jz (f64) |
8419 | +8d: JNL/JGE Jz (f64) |
8420 | +8e: JLE/JNG Jz (f64) |
8421 | +8f: JNLE/JG Jz (f64) |
8422 | +# 0x0f 0x90-0x9f |
8423 | +90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66) |
8424 | +91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66) |
8425 | +92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2) |
8426 | +93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2) |
8427 | +94: SETE/Z Eb |
8428 | +95: SETNE/NZ Eb |
8429 | +96: SETBE/NA Eb |
8430 | +97: SETA/NBE Eb |
8431 | +98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66) |
8432 | +99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66) |
8433 | +9a: SETP/PE Eb |
8434 | +9b: SETNP/PO Eb |
8435 | +9c: SETL/NGE Eb |
8436 | +9d: SETNL/GE Eb |
8437 | +9e: SETLE/NG Eb |
8438 | +9f: SETNLE/G Eb |
8439 | +# 0x0f 0xa0-0xaf |
8440 | +a0: PUSH FS (d64) |
8441 | +a1: POP FS (d64) |
8442 | +a2: CPUID |
8443 | +a3: BT Ev,Gv |
8444 | +a4: SHLD Ev,Gv,Ib |
8445 | +a5: SHLD Ev,Gv,CL |
8446 | +a6: GrpPDLK |
8447 | +a7: GrpRNG |
8448 | +a8: PUSH GS (d64) |
8449 | +a9: POP GS (d64) |
8450 | +aa: RSM |
8451 | +ab: BTS Ev,Gv |
8452 | +ac: SHRD Ev,Gv,Ib |
8453 | +ad: SHRD Ev,Gv,CL |
8454 | +ae: Grp15 (1A),(1C) |
8455 | +af: IMUL Gv,Ev |
8456 | +# 0x0f 0xb0-0xbf |
8457 | +b0: CMPXCHG Eb,Gb |
8458 | +b1: CMPXCHG Ev,Gv |
8459 | +b2: LSS Gv,Mp |
8460 | +b3: BTR Ev,Gv |
8461 | +b4: LFS Gv,Mp |
8462 | +b5: LGS Gv,Mp |
8463 | +b6: MOVZX Gv,Eb |
8464 | +b7: MOVZX Gv,Ew |
8465 | +b8: JMPE (!F3) | POPCNT Gv,Ev (F3) |
8466 | +b9: Grp10 (1A) |
8467 | +ba: Grp8 Ev,Ib (1A) |
8468 | +bb: BTC Ev,Gv |
8469 | +bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3) |
8470 | +bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3) |
8471 | +be: MOVSX Gv,Eb |
8472 | +bf: MOVSX Gv,Ew |
8473 | +# 0x0f 0xc0-0xcf |
8474 | +c0: XADD Eb,Gb |
8475 | +c1: XADD Ev,Gv |
8476 | +c2: vcmpps Vps,Hps,Wps,Ib | vcmppd Vpd,Hpd,Wpd,Ib (66) | vcmpss Vss,Hss,Wss,Ib (F3),(v1) | vcmpsd Vsd,Hsd,Wsd,Ib (F2),(v1) |
8477 | +c3: movnti My,Gy |
8478 | +c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1) |
8479 | +c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1) |
8480 | +c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66) |
8481 | +c7: Grp9 (1A) |
8482 | +c8: BSWAP RAX/EAX/R8/R8D |
8483 | +c9: BSWAP RCX/ECX/R9/R9D |
8484 | +ca: BSWAP RDX/EDX/R10/R10D |
8485 | +cb: BSWAP RBX/EBX/R11/R11D |
8486 | +cc: BSWAP RSP/ESP/R12/R12D |
8487 | +cd: BSWAP RBP/EBP/R13/R13D |
8488 | +ce: BSWAP RSI/ESI/R14/R14D |
8489 | +cf: BSWAP RDI/EDI/R15/R15D |
8490 | +# 0x0f 0xd0-0xdf |
8491 | +d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2) |
8492 | +d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1) |
8493 | +d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1) |
8494 | +d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1) |
8495 | +d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1) |
8496 | +d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1) |
8497 | +d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2) |
8498 | +d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1) |
8499 | +d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1) |
8500 | +d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1) |
8501 | +da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1) |
8502 | +db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo) |
8503 | +dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1) |
8504 | +dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1) |
8505 | +de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1) |
8506 | +df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo) |
8507 | +# 0x0f 0xe0-0xef |
8508 | +e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1) |
8509 | +e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1) |
8510 | +e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1) |
8511 | +e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1) |
8512 | +e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1) |
8513 | +e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1) |
8514 | +e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2) |
8515 | +e7: movntq Mq,Pq | vmovntdq Mx,Vx (66) |
8516 | +e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1) |
8517 | +e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1) |
8518 | +ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1) |
8519 | +eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo) |
8520 | +ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1) |
8521 | +ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1) |
8522 | +ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1) |
8523 | +ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo) |
8524 | +# 0x0f 0xf0-0xff |
8525 | +f0: vlddqu Vx,Mx (F2) |
8526 | +f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1) |
8527 | +f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1) |
8528 | +f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1) |
8529 | +f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1) |
8530 | +f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1) |
8531 | +f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1) |
8532 | +f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1) |
8533 | +f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1) |
8534 | +f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1) |
8535 | +fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1) |
8536 | +fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) |
8537 | +fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) |
8538 | +fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) |
8539 | +fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) |
8540 | +ff: UD0 |
8541 | +EndTable |
8542 | + |
8543 | +Table: 3-byte opcode 1 (0x0f 0x38) |
8544 | +Referrer: 3-byte escape 1 |
8545 | +AVXcode: 2 |
8546 | +# 0x0f 0x38 0x00-0x0f |
8547 | +00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1) |
8548 | +01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1) |
8549 | +02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1) |
8550 | +03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1) |
8551 | +04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1) |
8552 | +05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1) |
8553 | +06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1) |
8554 | +07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1) |
8555 | +08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1) |
8556 | +09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1) |
8557 | +0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1) |
8558 | +0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1) |
8559 | +0c: vpermilps Vx,Hx,Wx (66),(v) |
8560 | +0d: vpermilpd Vx,Hx,Wx (66),(v) |
8561 | +0e: vtestps Vx,Wx (66),(v) |
8562 | +0f: vtestpd Vx,Wx (66),(v) |
8563 | +# 0x0f 0x38 0x10-0x1f |
8564 | +10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev) |
8565 | +11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev) |
8566 | +12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev) |
8567 | +13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev) |
8568 | +14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo) |
8569 | +15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo) |
8570 | +16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo) |
8571 | +17: vptest Vx,Wx (66) |
8572 | +18: vbroadcastss Vx,Wd (66),(v) |
8573 | +19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo) |
8574 | +1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo) |
8575 | +1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev) |
8576 | +1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1) |
8577 | +1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1) |
8578 | +1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1) |
8579 | +1f: vpabsq Vx,Wx (66),(ev) |
8580 | +# 0x0f 0x38 0x20-0x2f |
8581 | +20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev) |
8582 | +21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev) |
8583 | +22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev) |
8584 | +23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev) |
8585 | +24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev) |
8586 | +25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev) |
8587 | +26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev) |
8588 | +27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev) |
8589 | +28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev) |
8590 | +29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev) |
8591 | +2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev) |
8592 | +2b: vpackusdw Vx,Hx,Wx (66),(v1) |
8593 | +2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo) |
8594 | +2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo) |
8595 | +2e: vmaskmovps Mx,Hx,Vx (66),(v) |
8596 | +2f: vmaskmovpd Mx,Hx,Vx (66),(v) |
8597 | +# 0x0f 0x38 0x30-0x3f |
8598 | +30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev) |
8599 | +31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev) |
8600 | +32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev) |
8601 | +33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev) |
8602 | +34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev) |
8603 | +35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev) |
8604 | +36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo) |
8605 | +37: vpcmpgtq Vx,Hx,Wx (66),(v1) |
8606 | +38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev) |
8607 | +39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev) |
8608 | +3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev) |
8609 | +3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo) |
8610 | +3c: vpmaxsb Vx,Hx,Wx (66),(v1) |
8611 | +3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo) |
8612 | +3e: vpmaxuw Vx,Hx,Wx (66),(v1) |
8613 | +3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo) |
8614 | +# 0x0f 0x38 0x40-0x8f |
8615 | +40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo) |
8616 | +41: vphminposuw Vdq,Wdq (66),(v1) |
8617 | +42: vgetexpps/d Vx,Wx (66),(ev) |
8618 | +43: vgetexpss/d Vx,Hx,Wx (66),(ev) |
8619 | +44: vplzcntd/q Vx,Wx (66),(ev) |
8620 | +45: vpsrlvd/q Vx,Hx,Wx (66),(v) |
8621 | +46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo) |
8622 | +47: vpsllvd/q Vx,Hx,Wx (66),(v) |
8623 | +# Skip 0x48-0x4b |
8624 | +4c: vrcp14ps/d Vpd,Wpd (66),(ev) |
8625 | +4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) |
8626 | +4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) |
8627 | +4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) |
8628 | +# Skip 0x50-0x57 |
8629 | +58: vpbroadcastd Vx,Wx (66),(v) |
8630 | +59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo) |
8631 | +5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo) |
8632 | +5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev) |
8633 | +# Skip 0x5c-0x63 |
8634 | +64: vpblendmd/q Vx,Hx,Wx (66),(ev) |
8635 | +65: vblendmps/d Vx,Hx,Wx (66),(ev) |
8636 | +66: vpblendmb/w Vx,Hx,Wx (66),(ev) |
8637 | +# Skip 0x67-0x74 |
8638 | +75: vpermi2b/w Vx,Hx,Wx (66),(ev) |
8639 | +76: vpermi2d/q Vx,Hx,Wx (66),(ev) |
8640 | +77: vpermi2ps/d Vx,Hx,Wx (66),(ev) |
8641 | +78: vpbroadcastb Vx,Wx (66),(v) |
8642 | +79: vpbroadcastw Vx,Wx (66),(v) |
8643 | +7a: vpbroadcastb Vx,Rv (66),(ev) |
8644 | +7b: vpbroadcastw Vx,Rv (66),(ev) |
8645 | +7c: vpbroadcastd/q Vx,Rv (66),(ev) |
8646 | +7d: vpermt2b/w Vx,Hx,Wx (66),(ev) |
8647 | +7e: vpermt2d/q Vx,Hx,Wx (66),(ev) |
8648 | +7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) |
8649 | +80: INVEPT Gy,Mdq (66) |
8650 | +81: INVVPID Gy,Mdq (66) |
8651 | +82: INVPCID Gy,Mdq (66) |
8652 | +83: vpmultishiftqb Vx,Hx,Wx (66),(ev) |
8653 | +88: vexpandps/d Vpd,Wpd (66),(ev) |
8654 | +89: vpexpandd/q Vx,Wx (66),(ev) |
8655 | +8a: vcompressps/d Wx,Vx (66),(ev) |
8656 | +8b: vpcompressd/q Wx,Vx (66),(ev) |
8657 | +8c: vpmaskmovd/q Vx,Hx,Mx (66),(v) |
8658 | +8d: vpermb/w Vx,Hx,Wx (66),(ev) |
8659 | +8e: vpmaskmovd/q Mx,Vx,Hx (66),(v) |
8660 | +# 0x0f 0x38 0x90-0xbf (FMA) |
8661 | +90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo) |
8662 | +91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo) |
8663 | +92: vgatherdps/d Vx,Hx,Wx (66),(v) |
8664 | +93: vgatherqps/d Vx,Hx,Wx (66),(v) |
8665 | +94: |
8666 | +95: |
8667 | +96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v) |
8668 | +97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v) |
8669 | +98: vfmadd132ps/d Vx,Hx,Wx (66),(v) |
8670 | +99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1) |
8671 | +9a: vfmsub132ps/d Vx,Hx,Wx (66),(v) |
8672 | +9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1) |
8673 | +9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v) |
8674 | +9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) |
8675 | +9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) |
8676 | +9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1) |
8677 | +a0: vpscatterdd/q Wx,Vx (66),(ev) |
8678 | +a1: vpscatterqd/q Wx,Vx (66),(ev) |
8679 | +a2: vscatterdps/d Wx,Vx (66),(ev) |
8680 | +a3: vscatterqps/d Wx,Vx (66),(ev) |
8681 | +a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) |
8682 | +a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) |
8683 | +a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) |
8684 | +a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1) |
8685 | +aa: vfmsub213ps/d Vx,Hx,Wx (66),(v) |
8686 | +ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1) |
8687 | +ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v) |
8688 | +ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) |
8689 | +ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) |
8690 | +af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) |
8691 | +b4: vpmadd52luq Vx,Hx,Wx (66),(ev) |
8692 | +b5: vpmadd52huq Vx,Hx,Wx (66),(ev) |
8693 | +b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) |
8694 | +b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) |
8695 | +b8: vfmadd231ps/d Vx,Hx,Wx (66),(v) |
8696 | +b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1) |
8697 | +ba: vfmsub231ps/d Vx,Hx,Wx (66),(v) |
8698 | +bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1) |
8699 | +bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v) |
8700 | +bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1) |
8701 | +be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) |
8702 | +bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) |
8703 | +# 0x0f 0x38 0xc0-0xff |
8704 | +c4: vpconflictd/q Vx,Wx (66),(ev) |
8705 | +c6: Grp18 (1A) |
8706 | +c7: Grp19 (1A) |
8707 | +c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev) |
8708 | +c9: sha1msg1 Vdq,Wdq |
8709 | +ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev) |
8710 | +cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) |
8711 | +cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) |
8712 | +cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) |
8713 | +db: VAESIMC Vdq,Wdq (66),(v1) |
8714 | +dc: VAESENC Vdq,Hdq,Wdq (66),(v1) |
8715 | +dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) |
8716 | +de: VAESDEC Vdq,Hdq,Wdq (66),(v1) |
8717 | +df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1) |
8718 | +f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) |
8719 | +f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) |
8720 | +f2: ANDN Gy,By,Ey (v) |
8721 | +f3: Grp17 (1A) |
8722 | +f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) |
8723 | +f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) |
8724 | +f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) |
8725 | +EndTable |
8726 | + |
8727 | +Table: 3-byte opcode 2 (0x0f 0x3a) |
8728 | +Referrer: 3-byte escape 2 |
8729 | +AVXcode: 3 |
8730 | +# 0x0f 0x3a 0x00-0xff |
8731 | +00: vpermq Vqq,Wqq,Ib (66),(v) |
8732 | +01: vpermpd Vqq,Wqq,Ib (66),(v) |
8733 | +02: vpblendd Vx,Hx,Wx,Ib (66),(v) |
8734 | +03: valignd/q Vx,Hx,Wx,Ib (66),(ev) |
8735 | +04: vpermilps Vx,Wx,Ib (66),(v) |
8736 | +05: vpermilpd Vx,Wx,Ib (66),(v) |
8737 | +06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v) |
8738 | +07: |
8739 | +08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo) |
8740 | +09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo) |
8741 | +0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo) |
8742 | +0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo) |
8743 | +0c: vblendps Vx,Hx,Wx,Ib (66) |
8744 | +0d: vblendpd Vx,Hx,Wx,Ib (66) |
8745 | +0e: vpblendw Vx,Hx,Wx,Ib (66),(v1) |
8746 | +0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1) |
8747 | +14: vpextrb Rd/Mb,Vdq,Ib (66),(v1) |
8748 | +15: vpextrw Rd/Mw,Vdq,Ib (66),(v1) |
8749 | +16: vpextrd/q Ey,Vdq,Ib (66),(v1) |
8750 | +17: vextractps Ed,Vdq,Ib (66),(v1) |
8751 | +18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) |
8752 | +19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo) |
8753 | +1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) |
8754 | +1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev) |
8755 | +1d: vcvtps2ph Wx,Vx,Ib (66),(v) |
8756 | +1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev) |
8757 | +1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev) |
8758 | +20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1) |
8759 | +21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1) |
8760 | +22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1) |
8761 | +23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) |
8762 | +25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev) |
8763 | +26: vgetmantps/d Vx,Wx,Ib (66),(ev) |
8764 | +27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev) |
8765 | +30: kshiftrb/w Vk,Uk,Ib (66),(v) |
8766 | +31: kshiftrd/q Vk,Uk,Ib (66),(v) |
8767 | +32: kshiftlb/w Vk,Uk,Ib (66),(v) |
8768 | +33: kshiftld/q Vk,Uk,Ib (66),(v) |
8769 | +38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) |
8770 | +39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo) |
8771 | +3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) |
8772 | +3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev) |
8773 | +3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev) |
8774 | +3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev) |
8775 | +40: vdpps Vx,Hx,Wx,Ib (66) |
8776 | +41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) |
8777 | +42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo) |
8778 | +43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) |
8779 | +44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) |
8780 | +46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) |
8781 | +4a: vblendvps Vx,Hx,Wx,Lx (66),(v) |
8782 | +4b: vblendvpd Vx,Hx,Wx,Lx (66),(v) |
8783 | +4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1) |
8784 | +50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev) |
8785 | +51: vrangess/d Vx,Hx,Wx,Ib (66),(ev) |
8786 | +54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev) |
8787 | +55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev) |
8788 | +56: vreduceps/d Vx,Wx,Ib (66),(ev) |
8789 | +57: vreducess/d Vx,Hx,Wx,Ib (66),(ev) |
8790 | +60: vpcmpestrm Vdq,Wdq,Ib (66),(v1) |
8791 | +61: vpcmpestri Vdq,Wdq,Ib (66),(v1) |
8792 | +62: vpcmpistrm Vdq,Wdq,Ib (66),(v1) |
8793 | +63: vpcmpistri Vdq,Wdq,Ib (66),(v1) |
8794 | +66: vfpclassps/d Vk,Wx,Ib (66),(ev) |
8795 | +67: vfpclassss/d Vk,Wx,Ib (66),(ev) |
8796 | +cc: sha1rnds4 Vdq,Wdq,Ib |
8797 | +df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) |
8798 | +f0: RORX Gy,Ey,Ib (F2),(v) |
8799 | +EndTable |
8800 | + |
8801 | +GrpTable: Grp1 |
8802 | +0: ADD |
8803 | +1: OR |
8804 | +2: ADC |
8805 | +3: SBB |
8806 | +4: AND |
8807 | +5: SUB |
8808 | +6: XOR |
8809 | +7: CMP |
8810 | +EndTable |
8811 | + |
8812 | +GrpTable: Grp1A |
8813 | +0: POP |
8814 | +EndTable |
8815 | + |
8816 | +GrpTable: Grp2 |
8817 | +0: ROL |
8818 | +1: ROR |
8819 | +2: RCL |
8820 | +3: RCR |
8821 | +4: SHL/SAL |
8822 | +5: SHR |
8823 | +6: |
8824 | +7: SAR |
8825 | +EndTable |
8826 | + |
8827 | +GrpTable: Grp3_1 |
8828 | +0: TEST Eb,Ib |
8829 | +1: TEST Eb,Ib |
8830 | +2: NOT Eb |
8831 | +3: NEG Eb |
8832 | +4: MUL AL,Eb |
8833 | +5: IMUL AL,Eb |
8834 | +6: DIV AL,Eb |
8835 | +7: IDIV AL,Eb |
8836 | +EndTable |
8837 | + |
8838 | +GrpTable: Grp3_2 |
8839 | +0: TEST Ev,Iz |
8840 | +1: |
8841 | +2: NOT Ev |
8842 | +3: NEG Ev |
8843 | +4: MUL rAX,Ev |
8844 | +5: IMUL rAX,Ev |
8845 | +6: DIV rAX,Ev |
8846 | +7: IDIV rAX,Ev |
8847 | +EndTable |
8848 | + |
8849 | +GrpTable: Grp4 |
8850 | +0: INC Eb |
8851 | +1: DEC Eb |
8852 | +EndTable |
8853 | + |
8854 | +GrpTable: Grp5 |
8855 | +0: INC Ev |
8856 | +1: DEC Ev |
8857 | +# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). |
8858 | +2: CALLN Ev (f64) |
8859 | +3: CALLF Ep |
8860 | +4: JMPN Ev (f64) |
8861 | +5: JMPF Mp |
8862 | +6: PUSH Ev (d64) |
8863 | +7: |
8864 | +EndTable |
8865 | + |
8866 | +GrpTable: Grp6 |
8867 | +0: SLDT Rv/Mw |
8868 | +1: STR Rv/Mw |
8869 | +2: LLDT Ew |
8870 | +3: LTR Ew |
8871 | +4: VERR Ew |
8872 | +5: VERW Ew |
8873 | +EndTable |
8874 | + |
8875 | +GrpTable: Grp7 |
8876 | +0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) |
8877 | +1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) |
8878 | +2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) |
8879 | +3: LIDT Ms |
8880 | +4: SMSW Mw/Rv |
8881 | +5: rdpkru (110),(11B) | wrpkru (111),(11B) |
8882 | +6: LMSW Ew |
8883 | +7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B) |
8884 | +EndTable |
8885 | + |
8886 | +GrpTable: Grp8 |
8887 | +4: BT |
8888 | +5: BTS |
8889 | +6: BTR |
8890 | +7: BTC |
8891 | +EndTable |
8892 | + |
8893 | +GrpTable: Grp9 |
8894 | +1: CMPXCHG8B/16B Mq/Mdq |
8895 | +3: xrstors |
8896 | +4: xsavec |
8897 | +5: xsaves |
8898 | +6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) |
8899 | +7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B) |
8900 | +EndTable |
8901 | + |
8902 | +GrpTable: Grp10 |
8903 | +# all are UD1 |
8904 | +0: UD1 |
8905 | +1: UD1 |
8906 | +2: UD1 |
8907 | +3: UD1 |
8908 | +4: UD1 |
8909 | +5: UD1 |
8910 | +6: UD1 |
8911 | +7: UD1 |
8912 | +EndTable |
8913 | + |
8914 | +# Grp11A and Grp11B are expressed as Grp11 in Intel SDM |
8915 | +GrpTable: Grp11A |
8916 | +0: MOV Eb,Ib |
8917 | +7: XABORT Ib (000),(11B) |
8918 | +EndTable |
8919 | + |
8920 | +GrpTable: Grp11B |
8921 | +0: MOV Eb,Iz |
8922 | +7: XBEGIN Jz (000),(11B) |
8923 | +EndTable |
8924 | + |
8925 | +GrpTable: Grp12 |
8926 | +2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1) |
8927 | +4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1) |
8928 | +6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1) |
8929 | +EndTable |
8930 | + |
8931 | +GrpTable: Grp13 |
8932 | +0: vprord/q Hx,Wx,Ib (66),(ev) |
8933 | +1: vprold/q Hx,Wx,Ib (66),(ev) |
8934 | +2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1) |
8935 | +4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo) |
8936 | +6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1) |
8937 | +EndTable |
8938 | + |
8939 | +GrpTable: Grp14 |
8940 | +2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1) |
8941 | +3: vpsrldq Hx,Ux,Ib (66),(11B),(v1) |
8942 | +6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1) |
8943 | +7: vpslldq Hx,Ux,Ib (66),(11B),(v1) |
8944 | +EndTable |
8945 | + |
8946 | +GrpTable: Grp15 |
8947 | +0: fxsave | RDFSBASE Ry (F3),(11B) |
8948 | +1: fxstor | RDGSBASE Ry (F3),(11B) |
8949 | +2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B) |
8950 | +3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) |
8951 | +4: XSAVE | ptwrite Ey (F3),(11B) |
8952 | +5: XRSTOR | lfence (11B) |
8953 | +6: XSAVEOPT | clwb (66) | mfence (11B) |
8954 | +7: clflush | clflushopt (66) | sfence (11B) |
8955 | +EndTable |
8956 | + |
8957 | +GrpTable: Grp16 |
8958 | +0: prefetch NTA |
8959 | +1: prefetch T0 |
8960 | +2: prefetch T1 |
8961 | +3: prefetch T2 |
8962 | +EndTable |
8963 | + |
8964 | +GrpTable: Grp17 |
8965 | +1: BLSR By,Ey (v) |
8966 | +2: BLSMSK By,Ey (v) |
8967 | +3: BLSI By,Ey (v) |
8968 | +EndTable |
8969 | + |
8970 | +GrpTable: Grp18 |
8971 | +1: vgatherpf0dps/d Wx (66),(ev) |
8972 | +2: vgatherpf1dps/d Wx (66),(ev) |
8973 | +5: vscatterpf0dps/d Wx (66),(ev) |
8974 | +6: vscatterpf1dps/d Wx (66),(ev) |
8975 | +EndTable |
8976 | + |
8977 | +GrpTable: Grp19 |
8978 | +1: vgatherpf0qps/d Wx (66),(ev) |
8979 | +2: vgatherpf1qps/d Wx (66),(ev) |
8980 | +5: vscatterpf0qps/d Wx (66),(ev) |
8981 | +6: vscatterpf1qps/d Wx (66),(ev) |
8982 | +EndTable |
8983 | + |
8984 | +# AMD's Prefetch Group |
8985 | +GrpTable: GrpP |
8986 | +0: PREFETCH |
8987 | +1: PREFETCHW |
8988 | +EndTable |
8989 | + |
8990 | +GrpTable: GrpPDLK |
8991 | +0: MONTMUL |
8992 | +1: XSHA1 |
8993 | +2: XSHA2 |
8994 | +EndTable |
8995 | + |
8996 | +GrpTable: GrpRNG |
8997 | +0: xstore-rng |
8998 | +1: xcrypt-ecb |
8999 | +2: xcrypt-cbc |
9000 | +4: xcrypt-cfb |
9001 | +5: xcrypt-ofb |
9002 | +EndTable |
9003 | diff --git a/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk |
9004 | new file mode 100644 |
9005 | index 000000000000..b02a36b2c14f |
9006 | --- /dev/null |
9007 | +++ b/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk |
9008 | @@ -0,0 +1,393 @@ |
9009 | +#!/bin/awk -f |
9010 | +# SPDX-License-Identifier: GPL-2.0 |
9011 | +# gen-insn-attr-x86.awk: Instruction attribute table generator |
9012 | +# Written by Masami Hiramatsu <mhiramat@redhat.com> |
9013 | +# |
9014 | +# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c |
9015 | + |
9016 | +# Awk implementation sanity check |
9017 | +function check_awk_implement() { |
9018 | + if (sprintf("%x", 0) != "0") |
9019 | + return "Your awk has a printf-format problem." |
9020 | + return "" |
9021 | +} |
9022 | + |
9023 | +# Clear working vars |
9024 | +function clear_vars() { |
9025 | + delete table |
9026 | + delete lptable2 |
9027 | + delete lptable1 |
9028 | + delete lptable3 |
9029 | + eid = -1 # escape id |
9030 | + gid = -1 # group id |
9031 | + aid = -1 # AVX id |
9032 | + tname = "" |
9033 | +} |
9034 | + |
9035 | +BEGIN { |
9036 | + # Implementation error checking |
9037 | + awkchecked = check_awk_implement() |
9038 | + if (awkchecked != "") { |
9039 | + print "Error: " awkchecked > "/dev/stderr" |
9040 | + print "Please try to use gawk." > "/dev/stderr" |
9041 | + exit 1 |
9042 | + } |
9043 | + |
9044 | + # Setup generating tables |
9045 | + print "/* x86 opcode map generated from x86-opcode-map.txt */" |
9046 | + print "/* Do not change this code. */\n" |
9047 | + ggid = 1 |
9048 | + geid = 1 |
9049 | + gaid = 0 |
9050 | + delete etable |
9051 | + delete gtable |
9052 | + delete atable |
9053 | + |
9054 | + opnd_expr = "^[A-Za-z/]" |
9055 | + ext_expr = "^\\(" |
9056 | + sep_expr = "^\\|$" |
9057 | + group_expr = "^Grp[0-9A-Za-z]+" |
9058 | + |
9059 | + imm_expr = "^[IJAOL][a-z]" |
9060 | + imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" |
9061 | + imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" |
9062 | + imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)" |
9063 | + imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)" |
9064 | + imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)" |
9065 | + imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)" |
9066 | + imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" |
9067 | + imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" |
9068 | + imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)" |
9069 | + imm_flag["Ob"] = "INAT_MOFFSET" |
9070 | + imm_flag["Ov"] = "INAT_MOFFSET" |
9071 | + imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" |
9072 | + |
9073 | + modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" |
9074 | + force64_expr = "\\([df]64\\)" |
9075 | + rex_expr = "^REX(\\.[XRWB]+)*" |
9076 | + fpu_expr = "^ESC" # TODO |
9077 | + |
9078 | + lprefix1_expr = "\\((66|!F3)\\)" |
9079 | + lprefix2_expr = "\\(F3\\)" |
9080 | + lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)" |
9081 | + lprefix_expr = "\\((66|F2|F3)\\)" |
9082 | + max_lprefix = 4 |
9083 | + |
9084 | + # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript |
9085 | + # accepts VEX prefix |
9086 | + vexok_opcode_expr = "^[vk].*" |
9087 | + vexok_expr = "\\(v1\\)" |
9088 | + # All opcodes with (v) superscript supports *only* VEX prefix |
9089 | + vexonly_expr = "\\(v\\)" |
9090 | + # All opcodes with (ev) superscript supports *only* EVEX prefix |
9091 | + evexonly_expr = "\\(ev\\)" |
9092 | + |
9093 | + prefix_expr = "\\(Prefix\\)" |
9094 | + prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" |
9095 | + prefix_num["REPNE"] = "INAT_PFX_REPNE" |
9096 | + prefix_num["REP/REPE"] = "INAT_PFX_REPE" |
9097 | + prefix_num["XACQUIRE"] = "INAT_PFX_REPNE" |
9098 | + prefix_num["XRELEASE"] = "INAT_PFX_REPE" |
9099 | + prefix_num["LOCK"] = "INAT_PFX_LOCK" |
9100 | + prefix_num["SEG=CS"] = "INAT_PFX_CS" |
9101 | + prefix_num["SEG=DS"] = "INAT_PFX_DS" |
9102 | + prefix_num["SEG=ES"] = "INAT_PFX_ES" |
9103 | + prefix_num["SEG=FS"] = "INAT_PFX_FS" |
9104 | + prefix_num["SEG=GS"] = "INAT_PFX_GS" |
9105 | + prefix_num["SEG=SS"] = "INAT_PFX_SS" |
9106 | + prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" |
9107 | + prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" |
9108 | + prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" |
9109 | + prefix_num["EVEX"] = "INAT_PFX_EVEX" |
9110 | + |
9111 | + clear_vars() |
9112 | +} |
9113 | + |
9114 | +function semantic_error(msg) { |
9115 | + print "Semantic error at " NR ": " msg > "/dev/stderr" |
9116 | + exit 1 |
9117 | +} |
9118 | + |
9119 | +function debug(msg) { |
9120 | + print "DEBUG: " msg |
9121 | +} |
9122 | + |
9123 | +function array_size(arr, i,c) { |
9124 | + c = 0 |
9125 | + for (i in arr) |
9126 | + c++ |
9127 | + return c |
9128 | +} |
9129 | + |
9130 | +/^Table:/ { |
9131 | + print "/* " $0 " */" |
9132 | + if (tname != "") |
9133 | + semantic_error("Hit Table: before EndTable:."); |
9134 | +} |
9135 | + |
9136 | +/^Referrer:/ { |
9137 | + if (NF != 1) { |
9138 | + # escape opcode table |
9139 | + ref = "" |
9140 | + for (i = 2; i <= NF; i++) |
9141 | + ref = ref $i |
9142 | + eid = escape[ref] |
9143 | + tname = sprintf("inat_escape_table_%d", eid) |
9144 | + } |
9145 | +} |
9146 | + |
9147 | +/^AVXcode:/ { |
9148 | + if (NF != 1) { |
9149 | + # AVX/escape opcode table |
9150 | + aid = $2 |
9151 | + if (gaid <= aid) |
9152 | + gaid = aid + 1 |
9153 | + if (tname == "") # AVX only opcode table |
9154 | + tname = sprintf("inat_avx_table_%d", $2) |
9155 | + } |
9156 | + if (aid == -1 && eid == -1) # primary opcode table |
9157 | + tname = "inat_primary_table" |
9158 | +} |
9159 | + |
9160 | +/^GrpTable:/ { |
9161 | + print "/* " $0 " */" |
9162 | + if (!($2 in group)) |
9163 | + semantic_error("No group: " $2 ) |
9164 | + gid = group[$2] |
9165 | + tname = "inat_group_table_" gid |
9166 | +} |
9167 | + |
9168 | +function print_table(tbl,name,fmt,n) |
9169 | +{ |
9170 | + print "const insn_attr_t " name " = {" |
9171 | + for (i = 0; i < n; i++) { |
9172 | + id = sprintf(fmt, i) |
9173 | + if (tbl[id]) |
9174 | + print " [" id "] = " tbl[id] "," |
9175 | + } |
9176 | + print "};" |
9177 | +} |
9178 | + |
9179 | +/^EndTable/ { |
9180 | + if (gid != -1) { |
9181 | + # print group tables |
9182 | + if (array_size(table) != 0) { |
9183 | + print_table(table, tname "[INAT_GROUP_TABLE_SIZE]", |
9184 | + "0x%x", 8) |
9185 | + gtable[gid,0] = tname |
9186 | + } |
9187 | + if (array_size(lptable1) != 0) { |
9188 | + print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]", |
9189 | + "0x%x", 8) |
9190 | + gtable[gid,1] = tname "_1" |
9191 | + } |
9192 | + if (array_size(lptable2) != 0) { |
9193 | + print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]", |
9194 | + "0x%x", 8) |
9195 | + gtable[gid,2] = tname "_2" |
9196 | + } |
9197 | + if (array_size(lptable3) != 0) { |
9198 | + print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]", |
9199 | + "0x%x", 8) |
9200 | + gtable[gid,3] = tname "_3" |
9201 | + } |
9202 | + } else { |
9203 | + # print primary/escaped tables |
9204 | + if (array_size(table) != 0) { |
9205 | + print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]", |
9206 | + "0x%02x", 256) |
9207 | + etable[eid,0] = tname |
9208 | + if (aid >= 0) |
9209 | + atable[aid,0] = tname |
9210 | + } |
9211 | + if (array_size(lptable1) != 0) { |
9212 | + print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]", |
9213 | + "0x%02x", 256) |
9214 | + etable[eid,1] = tname "_1" |
9215 | + if (aid >= 0) |
9216 | + atable[aid,1] = tname "_1" |
9217 | + } |
9218 | + if (array_size(lptable2) != 0) { |
9219 | + print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]", |
9220 | + "0x%02x", 256) |
9221 | + etable[eid,2] = tname "_2" |
9222 | + if (aid >= 0) |
9223 | + atable[aid,2] = tname "_2" |
9224 | + } |
9225 | + if (array_size(lptable3) != 0) { |
9226 | + print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]", |
9227 | + "0x%02x", 256) |
9228 | + etable[eid,3] = tname "_3" |
9229 | + if (aid >= 0) |
9230 | + atable[aid,3] = tname "_3" |
9231 | + } |
9232 | + } |
9233 | + print "" |
9234 | + clear_vars() |
9235 | +} |
9236 | + |
9237 | +function add_flags(old,new) { |
9238 | + if (old && new) |
9239 | + return old " | " new |
9240 | + else if (old) |
9241 | + return old |
9242 | + else |
9243 | + return new |
9244 | +} |
9245 | + |
9246 | +# convert operands to flags. |
9247 | +function convert_operands(count,opnd, i,j,imm,mod) |
9248 | +{ |
9249 | + imm = null |
9250 | + mod = null |
9251 | + for (j = 1; j <= count; j++) { |
9252 | + i = opnd[j] |
9253 | + if (match(i, imm_expr) == 1) { |
9254 | + if (!imm_flag[i]) |
9255 | + semantic_error("Unknown imm opnd: " i) |
9256 | + if (imm) { |
9257 | + if (i != "Ib") |
9258 | + semantic_error("Second IMM error") |
9259 | + imm = add_flags(imm, "INAT_SCNDIMM") |
9260 | + } else |
9261 | + imm = imm_flag[i] |
9262 | + } else if (match(i, modrm_expr)) |
9263 | + mod = "INAT_MODRM" |
9264 | + } |
9265 | + return add_flags(imm, mod) |
9266 | +} |
9267 | + |
9268 | +/^[0-9a-f]+\:/ { |
9269 | + if (NR == 1) |
9270 | + next |
9271 | + # get index |
9272 | + idx = "0x" substr($1, 1, index($1,":") - 1) |
9273 | + if (idx in table) |
9274 | + semantic_error("Redefine " idx " in " tname) |
9275 | + |
9276 | + # check if escaped opcode |
9277 | + if ("escape" == $2) { |
9278 | + if ($3 != "#") |
9279 | + semantic_error("No escaped name") |
9280 | + ref = "" |
9281 | + for (i = 4; i <= NF; i++) |
9282 | + ref = ref $i |
9283 | + if (ref in escape) |
9284 | + semantic_error("Redefine escape (" ref ")") |
9285 | + escape[ref] = geid |
9286 | + geid++ |
9287 | + table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")" |
9288 | + next |
9289 | + } |
9290 | + |
9291 | + variant = null |
9292 | + # converts |
9293 | + i = 2 |
9294 | + while (i <= NF) { |
9295 | + opcode = $(i++) |
9296 | + delete opnds |
9297 | + ext = null |
9298 | + flags = null |
9299 | + opnd = null |
9300 | + # parse one opcode |
9301 | + if (match($i, opnd_expr)) { |
9302 | + opnd = $i |
9303 | + count = split($(i++), opnds, ",") |
9304 | + flags = convert_operands(count, opnds) |
9305 | + } |
9306 | + if (match($i, ext_expr)) |
9307 | + ext = $(i++) |
9308 | + if (match($i, sep_expr)) |
9309 | + i++ |
9310 | + else if (i < NF) |
9311 | + semantic_error($i " is not a separator") |
9312 | + |
9313 | + # check if group opcode |
9314 | + if (match(opcode, group_expr)) { |
9315 | + if (!(opcode in group)) { |
9316 | + group[opcode] = ggid |
9317 | + ggid++ |
9318 | + } |
9319 | + flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")") |
9320 | + } |
9321 | + # check force(or default) 64bit |
9322 | + if (match(ext, force64_expr)) |
9323 | + flags = add_flags(flags, "INAT_FORCE64") |
9324 | + |
9325 | + # check REX prefix |
9326 | + if (match(opcode, rex_expr)) |
9327 | + flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)") |
9328 | + |
9329 | + # check coprocessor escape : TODO |
9330 | + if (match(opcode, fpu_expr)) |
9331 | + flags = add_flags(flags, "INAT_MODRM") |
9332 | + |
9333 | + # check VEX codes |
9334 | + if (match(ext, evexonly_expr)) |
9335 | + flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") |
9336 | + else if (match(ext, vexonly_expr)) |
9337 | + flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") |
9338 | + else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) |
9339 | + flags = add_flags(flags, "INAT_VEXOK") |
9340 | + |
9341 | + # check prefixes |
9342 | + if (match(ext, prefix_expr)) { |
9343 | + if (!prefix_num[opcode]) |
9344 | + semantic_error("Unknown prefix: " opcode) |
9345 | + flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")") |
9346 | + } |
9347 | + if (length(flags) == 0) |
9348 | + continue |
9349 | + # check if last prefix |
9350 | + if (match(ext, lprefix1_expr)) { |
9351 | + lptable1[idx] = add_flags(lptable1[idx],flags) |
9352 | + variant = "INAT_VARIANT" |
9353 | + } |
9354 | + if (match(ext, lprefix2_expr)) { |
9355 | + lptable2[idx] = add_flags(lptable2[idx],flags) |
9356 | + variant = "INAT_VARIANT" |
9357 | + } |
9358 | + if (match(ext, lprefix3_expr)) { |
9359 | + lptable3[idx] = add_flags(lptable3[idx],flags) |
9360 | + variant = "INAT_VARIANT" |
9361 | + } |
9362 | + if (!match(ext, lprefix_expr)){ |
9363 | + table[idx] = add_flags(table[idx],flags) |
9364 | + } |
9365 | + } |
9366 | + if (variant) |
9367 | + table[idx] = add_flags(table[idx],variant) |
9368 | +} |
9369 | + |
9370 | +END { |
9371 | + if (awkchecked != "") |
9372 | + exit 1 |
9373 | + # print escape opcode map's array |
9374 | + print "/* Escape opcode map array */" |
9375 | + print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \ |
9376 | + "[INAT_LSTPFX_MAX + 1] = {" |
9377 | + for (i = 0; i < geid; i++) |
9378 | + for (j = 0; j < max_lprefix; j++) |
9379 | + if (etable[i,j]) |
9380 | + print " ["i"]["j"] = "etable[i,j]"," |
9381 | + print "};\n" |
9382 | + # print group opcode map's array |
9383 | + print "/* Group opcode map array */" |
9384 | + print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\ |
9385 | + "[INAT_LSTPFX_MAX + 1] = {" |
9386 | + for (i = 0; i < ggid; i++) |
9387 | + for (j = 0; j < max_lprefix; j++) |
9388 | + if (gtable[i,j]) |
9389 | + print " ["i"]["j"] = "gtable[i,j]"," |
9390 | + print "};\n" |
9391 | + # print AVX opcode map's array |
9392 | + print "/* AVX opcode map array */" |
9393 | + print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\ |
9394 | + "[INAT_LSTPFX_MAX + 1] = {" |
9395 | + for (i = 0; i < gaid; i++) |
9396 | + for (j = 0; j < max_lprefix; j++) |
9397 | + if (atable[i,j]) |
9398 | + print " ["i"]["j"] = "atable[i,j]"," |
9399 | + print "};" |
9400 | +} |
9401 | + |
9402 | diff --git a/tools/objtool/orc.h b/tools/objtool/orc.h |
9403 | index a4139e386ef3..b0e92a6d0903 100644 |
9404 | --- a/tools/objtool/orc.h |
9405 | +++ b/tools/objtool/orc.h |
9406 | @@ -18,7 +18,7 @@ |
9407 | #ifndef _ORC_H |
9408 | #define _ORC_H |
9409 | |
9410 | -#include "orc_types.h" |
9411 | +#include <asm/orc_types.h> |
9412 | |
9413 | struct objtool_file; |
9414 | |
9415 | diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c |
9416 | index 36c5bf6a2675..c3343820916a 100644 |
9417 | --- a/tools/objtool/orc_dump.c |
9418 | +++ b/tools/objtool/orc_dump.c |
9419 | @@ -76,7 +76,8 @@ int orc_dump(const char *_objname) |
9420 | int fd, nr_entries, i, *orc_ip = NULL, orc_size = 0; |
9421 | struct orc_entry *orc = NULL; |
9422 | char *name; |
9423 | - unsigned long nr_sections, orc_ip_addr = 0; |
9424 | + size_t nr_sections; |
9425 | + Elf64_Addr orc_ip_addr = 0; |
9426 | size_t shstrtab_idx; |
9427 | Elf *elf; |
9428 | Elf_Scn *scn; |
9429 | @@ -187,10 +188,10 @@ int orc_dump(const char *_objname) |
9430 | return -1; |
9431 | } |
9432 | |
9433 | - printf("%s+%lx:", name, rela.r_addend); |
9434 | + printf("%s+%llx:", name, (unsigned long long)rela.r_addend); |
9435 | |
9436 | } else { |
9437 | - printf("%lx:", orc_ip_addr + (i * sizeof(int)) + orc_ip[i]); |
9438 | + printf("%llx:", (unsigned long long)(orc_ip_addr + (i * sizeof(int)) + orc_ip[i])); |
9439 | } |
9440 | |
9441 | |
9442 | diff --git a/tools/objtool/orc_types.h b/tools/objtool/orc_types.h |
9443 | deleted file mode 100644 |
9444 | index 9c9dc579bd7d..000000000000 |
9445 | --- a/tools/objtool/orc_types.h |
9446 | +++ /dev/null |
9447 | @@ -1,107 +0,0 @@ |
9448 | -/* |
9449 | - * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com> |
9450 | - * |
9451 | - * This program is free software; you can redistribute it and/or |
9452 | - * modify it under the terms of the GNU General Public License |
9453 | - * as published by the Free Software Foundation; either version 2 |
9454 | - * of the License, or (at your option) any later version. |
9455 | - * |
9456 | - * This program is distributed in the hope that it will be useful, |
9457 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9458 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
9459 | - * GNU General Public License for more details. |
9460 | - * |
9461 | - * You should have received a copy of the GNU General Public License |
9462 | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
9463 | - */ |
9464 | - |
9465 | -#ifndef _ORC_TYPES_H |
9466 | -#define _ORC_TYPES_H |
9467 | - |
9468 | -#include <linux/types.h> |
9469 | -#include <linux/compiler.h> |
9470 | - |
9471 | -/* |
9472 | - * The ORC_REG_* registers are base registers which are used to find other |
9473 | - * registers on the stack. |
9474 | - * |
9475 | - * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the |
9476 | - * address of the previous frame: the caller's SP before it called the current |
9477 | - * function. |
9478 | - * |
9479 | - * ORC_REG_UNDEFINED means the corresponding register's value didn't change in |
9480 | - * the current frame. |
9481 | - * |
9482 | - * The most commonly used base registers are SP and BP -- which the previous SP |
9483 | - * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is |
9484 | - * usually based on. |
9485 | - * |
9486 | - * The rest of the base registers are needed for special cases like entry code |
9487 | - * and GCC realigned stacks. |
9488 | - */ |
9489 | -#define ORC_REG_UNDEFINED 0 |
9490 | -#define ORC_REG_PREV_SP 1 |
9491 | -#define ORC_REG_DX 2 |
9492 | -#define ORC_REG_DI 3 |
9493 | -#define ORC_REG_BP 4 |
9494 | -#define ORC_REG_SP 5 |
9495 | -#define ORC_REG_R10 6 |
9496 | -#define ORC_REG_R13 7 |
9497 | -#define ORC_REG_BP_INDIRECT 8 |
9498 | -#define ORC_REG_SP_INDIRECT 9 |
9499 | -#define ORC_REG_MAX 15 |
9500 | - |
9501 | -/* |
9502 | - * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the |
9503 | - * caller's SP right before it made the call). Used for all callable |
9504 | - * functions, i.e. all C code and all callable asm functions. |
9505 | - * |
9506 | - * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points |
9507 | - * to a fully populated pt_regs from a syscall, interrupt, or exception. |
9508 | - * |
9509 | - * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset |
9510 | - * points to the iret return frame. |
9511 | - * |
9512 | - * The UNWIND_HINT macros are used only for the unwind_hint struct. They |
9513 | - * aren't used in struct orc_entry due to size and complexity constraints. |
9514 | - * Objtool converts them to real types when it converts the hints to orc |
9515 | - * entries. |
9516 | - */ |
9517 | -#define ORC_TYPE_CALL 0 |
9518 | -#define ORC_TYPE_REGS 1 |
9519 | -#define ORC_TYPE_REGS_IRET 2 |
9520 | -#define UNWIND_HINT_TYPE_SAVE 3 |
9521 | -#define UNWIND_HINT_TYPE_RESTORE 4 |
9522 | - |
9523 | -#ifndef __ASSEMBLY__ |
9524 | -/* |
9525 | - * This struct is more or less a vastly simplified version of the DWARF Call |
9526 | - * Frame Information standard. It contains only the necessary parts of DWARF |
9527 | - * CFI, simplified for ease of access by the in-kernel unwinder. It tells the |
9528 | - * unwinder how to find the previous SP and BP (and sometimes entry regs) on |
9529 | - * the stack for a given code address. Each instance of the struct corresponds |
9530 | - * to one or more code locations. |
9531 | - */ |
9532 | -struct orc_entry { |
9533 | - s16 sp_offset; |
9534 | - s16 bp_offset; |
9535 | - unsigned sp_reg:4; |
9536 | - unsigned bp_reg:4; |
9537 | - unsigned type:2; |
9538 | -} __packed; |
9539 | - |
9540 | -/* |
9541 | - * This struct is used by asm and inline asm code to manually annotate the |
9542 | - * location of registers on the stack for the ORC unwinder. |
9543 | - * |
9544 | - * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*. |
9545 | - */ |
9546 | -struct unwind_hint { |
9547 | - u32 ip; |
9548 | - s16 sp_offset; |
9549 | - u8 sp_reg; |
9550 | - u8 type; |
9551 | -}; |
9552 | -#endif /* __ASSEMBLY__ */ |
9553 | - |
9554 | -#endif /* _ORC_TYPES_H */ |
9555 | diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh |
9556 | new file mode 100755 |
9557 | index 000000000000..1470e74e9d66 |
9558 | --- /dev/null |
9559 | +++ b/tools/objtool/sync-check.sh |
9560 | @@ -0,0 +1,29 @@ |
9561 | +#!/bin/sh |
9562 | +# SPDX-License-Identifier: GPL-2.0 |
9563 | + |
9564 | +FILES=' |
9565 | +arch/x86/lib/insn.c |
9566 | +arch/x86/lib/inat.c |
9567 | +arch/x86/lib/x86-opcode-map.txt |
9568 | +arch/x86/tools/gen-insn-attr-x86.awk |
9569 | +arch/x86/include/asm/insn.h |
9570 | +arch/x86/include/asm/inat.h |
9571 | +arch/x86/include/asm/inat_types.h |
9572 | +arch/x86/include/asm/orc_types.h |
9573 | +' |
9574 | + |
9575 | +check() |
9576 | +{ |
9577 | + local file=$1 |
9578 | + |
9579 | + diff $file ../../$file > /dev/null || |
9580 | + echo "Warning: synced file at 'tools/objtool/$file' differs from latest kernel version at '$file'" |
9581 | +} |
9582 | + |
9583 | +if [ ! -d ../../kernel ] || [ ! -d ../../tools ] || [ ! -d ../objtool ]; then |
9584 | + exit 0 |
9585 | +fi |
9586 | + |
9587 | +for i in $FILES; do |
9588 | + check $i |
9589 | +done |
9590 | diff --git a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt |
9591 | index 12e377184ee4..e0b85930dd77 100644 |
9592 | --- a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt |
9593 | +++ b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt |
9594 | @@ -607,7 +607,7 @@ fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) |
9595 | fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) |
9596 | fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) |
9597 | fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) |
9598 | -ff: |
9599 | +ff: UD0 |
9600 | EndTable |
9601 | |
9602 | Table: 3-byte opcode 1 (0x0f 0x38) |
9603 | @@ -717,7 +717,7 @@ AVXcode: 2 |
9604 | 7e: vpermt2d/q Vx,Hx,Wx (66),(ev) |
9605 | 7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) |
9606 | 80: INVEPT Gy,Mdq (66) |
9607 | -81: INVPID Gy,Mdq (66) |
9608 | +81: INVVPID Gy,Mdq (66) |
9609 | 82: INVPCID Gy,Mdq (66) |
9610 | 83: vpmultishiftqb Vx,Hx,Wx (66),(ev) |
9611 | 88: vexpandps/d Vpd,Wpd (66),(ev) |
9612 | @@ -896,7 +896,7 @@ EndTable |
9613 | |
9614 | GrpTable: Grp3_1 |
9615 | 0: TEST Eb,Ib |
9616 | -1: |
9617 | +1: TEST Eb,Ib |
9618 | 2: NOT Eb |
9619 | 3: NEG Eb |
9620 | 4: MUL AL,Eb |
9621 | @@ -970,6 +970,15 @@ GrpTable: Grp9 |
9622 | EndTable |
9623 | |
9624 | GrpTable: Grp10 |
9625 | +# all are UD1 |
9626 | +0: UD1 |
9627 | +1: UD1 |
9628 | +2: UD1 |
9629 | +3: UD1 |
9630 | +4: UD1 |
9631 | +5: UD1 |
9632 | +6: UD1 |
9633 | +7: UD1 |
9634 | EndTable |
9635 | |
9636 | # Grp11A and Grp11B are expressed as Grp11 in Intel SDM |
9637 | diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c |
9638 | index 66e5ce5b91f0..0304ffb714f2 100644 |
9639 | --- a/tools/testing/selftests/x86/ldt_gdt.c |
9640 | +++ b/tools/testing/selftests/x86/ldt_gdt.c |
9641 | @@ -627,13 +627,10 @@ static void do_multicpu_tests(void) |
9642 | static int finish_exec_test(void) |
9643 | { |
9644 | /* |
9645 | - * In a sensible world, this would be check_invalid_segment(0, 1); |
9646 | - * For better or for worse, though, the LDT is inherited across exec. |
9647 | - * We can probably change this safely, but for now we test it. |
9648 | + * Older kernel versions did inherit the LDT on exec() which is |
9649 | + * wrong because exec() starts from a clean state. |
9650 | */ |
9651 | - check_valid_segment(0, 1, |
9652 | - AR_DPL3 | AR_TYPE_XRCODE | AR_S | AR_P | AR_DB, |
9653 | - 42, true); |
9654 | + check_invalid_segment(0, 1); |
9655 | |
9656 | return nerrs ? 1 : 0; |
9657 | } |
9658 | diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c |
9659 | index b36945d49986..b4b69c2d1012 100644 |
9660 | --- a/virt/kvm/arm/mmu.c |
9661 | +++ b/virt/kvm/arm/mmu.c |
9662 | @@ -509,8 +509,6 @@ static void unmap_hyp_range(pgd_t *pgdp, phys_addr_t start, u64 size) |
9663 | */ |
9664 | void free_hyp_pgds(void) |
9665 | { |
9666 | - unsigned long addr; |
9667 | - |
9668 | mutex_lock(&kvm_hyp_pgd_mutex); |
9669 | |
9670 | if (boot_hyp_pgd) { |
9671 | @@ -521,10 +519,10 @@ void free_hyp_pgds(void) |
9672 | |
9673 | if (hyp_pgd) { |
9674 | unmap_hyp_range(hyp_pgd, hyp_idmap_start, PAGE_SIZE); |
9675 | - for (addr = PAGE_OFFSET; virt_addr_valid(addr); addr += PGDIR_SIZE) |
9676 | - unmap_hyp_range(hyp_pgd, kern_hyp_va(addr), PGDIR_SIZE); |
9677 | - for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) |
9678 | - unmap_hyp_range(hyp_pgd, kern_hyp_va(addr), PGDIR_SIZE); |
9679 | + unmap_hyp_range(hyp_pgd, kern_hyp_va(PAGE_OFFSET), |
9680 | + (uintptr_t)high_memory - PAGE_OFFSET); |
9681 | + unmap_hyp_range(hyp_pgd, kern_hyp_va(VMALLOC_START), |
9682 | + VMALLOC_END - VMALLOC_START); |
9683 | |
9684 | free_pages((unsigned long)hyp_pgd, hyp_pgd_order); |
9685 | hyp_pgd = NULL; |