Annotation of /trunk/kernel-alx/patches-4.14/0109-4.14.10-all-fixes.patch
Parent Directory | Revision Log
Revision 3238 -
(hide 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 | niro | 3238 | 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; |