diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/x86/lib | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'arch/x86/lib')
-rw-r--r-- | arch/x86/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/lib/atomic64_32.c | 59 | ||||
-rw-r--r-- | arch/x86/lib/atomic64_386_32.S | 6 | ||||
-rw-r--r-- | arch/x86/lib/atomic64_cx8_32.S | 29 | ||||
-rw-r--r-- | arch/x86/lib/checksum_32.S | 9 | ||||
-rw-r--r-- | arch/x86/lib/copy_page_64.S | 128 | ||||
-rw-r--r-- | arch/x86/lib/copy_user_64.S | 70 | ||||
-rw-r--r-- | arch/x86/lib/copy_user_nocache_64.S | 53 | ||||
-rw-r--r-- | arch/x86/lib/csum-copy_64.S | 16 | ||||
-rw-r--r-- | arch/x86/lib/csum-wrappers_64.c | 2 | ||||
-rw-r--r-- | arch/x86/lib/delay.c | 6 | ||||
-rw-r--r-- | arch/x86/lib/getuser.S | 19 | ||||
-rw-r--r-- | arch/x86/lib/inat.c | 45 | ||||
-rw-r--r-- | arch/x86/lib/insn.c | 114 | ||||
-rw-r--r-- | arch/x86/lib/memcpy_64.S | 44 | ||||
-rw-r--r-- | arch/x86/lib/memset_64.S | 33 | ||||
-rw-r--r-- | arch/x86/lib/msr-reg-export.c | 4 | ||||
-rw-r--r-- | arch/x86/lib/msr-reg.S | 10 | ||||
-rw-r--r-- | arch/x86/lib/putuser.S | 20 | ||||
-rw-r--r-- | arch/x86/lib/string_32.c | 8 | ||||
-rw-r--r-- | arch/x86/lib/usercopy.c | 6 | ||||
-rw-r--r-- | arch/x86/lib/usercopy_32.c | 428 | ||||
-rw-r--r-- | arch/x86/lib/usercopy_64.c | 100 | ||||
-rw-r--r-- | arch/x86/lib/x86-opcode-map.txt | 612 |
24 files changed, 1026 insertions, 796 deletions
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 96b2c6697c9..b00f6785da7 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
@@ -32,6 +32,7 @@ ifeq ($(CONFIG_X86_32),y) | |||
32 | lib-y += checksum_32.o | 32 | lib-y += checksum_32.o |
33 | lib-y += strstr_32.o | 33 | lib-y += strstr_32.o |
34 | lib-y += string_32.o | 34 | lib-y += string_32.o |
35 | lib-y += cmpxchg.o | ||
35 | ifneq ($(CONFIG_X86_CMPXCHG64),y) | 36 | ifneq ($(CONFIG_X86_CMPXCHG64),y) |
36 | lib-y += cmpxchg8b_emu.o atomic64_386_32.o | 37 | lib-y += cmpxchg8b_emu.o atomic64_386_32.o |
37 | endif | 38 | endif |
diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c index a0b4a350daa..042f6826bf5 100644 --- a/arch/x86/lib/atomic64_32.c +++ b/arch/x86/lib/atomic64_32.c | |||
@@ -1,4 +1,59 @@ | |||
1 | #define ATOMIC64_EXPORT EXPORT_SYMBOL | 1 | #include <linux/compiler.h> |
2 | #include <linux/module.h> | ||
3 | #include <linux/types.h> | ||
2 | 4 | ||
3 | #include <linux/export.h> | 5 | #include <asm/processor.h> |
6 | #include <asm/cmpxchg.h> | ||
4 | #include <linux/atomic.h> | 7 | #include <linux/atomic.h> |
8 | |||
9 | long long atomic64_read_cx8(long long, const atomic64_t *v); | ||
10 | EXPORT_SYMBOL(atomic64_read_cx8); | ||
11 | long long atomic64_set_cx8(long long, const atomic64_t *v); | ||
12 | EXPORT_SYMBOL(atomic64_set_cx8); | ||
13 | long long atomic64_xchg_cx8(long long, unsigned high); | ||
14 | EXPORT_SYMBOL(atomic64_xchg_cx8); | ||
15 | long long atomic64_add_return_cx8(long long a, atomic64_t *v); | ||
16 | EXPORT_SYMBOL(atomic64_add_return_cx8); | ||
17 | long long atomic64_sub_return_cx8(long long a, atomic64_t *v); | ||
18 | EXPORT_SYMBOL(atomic64_sub_return_cx8); | ||
19 | long long atomic64_inc_return_cx8(long long a, atomic64_t *v); | ||
20 | EXPORT_SYMBOL(atomic64_inc_return_cx8); | ||
21 | long long atomic64_dec_return_cx8(long long a, atomic64_t *v); | ||
22 | EXPORT_SYMBOL(atomic64_dec_return_cx8); | ||
23 | long long atomic64_dec_if_positive_cx8(atomic64_t *v); | ||
24 | EXPORT_SYMBOL(atomic64_dec_if_positive_cx8); | ||
25 | int atomic64_inc_not_zero_cx8(atomic64_t *v); | ||
26 | EXPORT_SYMBOL(atomic64_inc_not_zero_cx8); | ||
27 | int atomic64_add_unless_cx8(atomic64_t *v, long long a, long long u); | ||
28 | EXPORT_SYMBOL(atomic64_add_unless_cx8); | ||
29 | |||
30 | #ifndef CONFIG_X86_CMPXCHG64 | ||
31 | long long atomic64_read_386(long long, const atomic64_t *v); | ||
32 | EXPORT_SYMBOL(atomic64_read_386); | ||
33 | long long atomic64_set_386(long long, const atomic64_t *v); | ||
34 | EXPORT_SYMBOL(atomic64_set_386); | ||
35 | long long atomic64_xchg_386(long long, unsigned high); | ||
36 | EXPORT_SYMBOL(atomic64_xchg_386); | ||
37 | long long atomic64_add_return_386(long long a, atomic64_t *v); | ||
38 | EXPORT_SYMBOL(atomic64_add_return_386); | ||
39 | long long atomic64_sub_return_386(long long a, atomic64_t *v); | ||
40 | EXPORT_SYMBOL(atomic64_sub_return_386); | ||
41 | long long atomic64_inc_return_386(long long a, atomic64_t *v); | ||
42 | EXPORT_SYMBOL(atomic64_inc_return_386); | ||
43 | long long atomic64_dec_return_386(long long a, atomic64_t *v); | ||
44 | EXPORT_SYMBOL(atomic64_dec_return_386); | ||
45 | long long atomic64_add_386(long long a, atomic64_t *v); | ||
46 | EXPORT_SYMBOL(atomic64_add_386); | ||
47 | long long atomic64_sub_386(long long a, atomic64_t *v); | ||
48 | EXPORT_SYMBOL(atomic64_sub_386); | ||
49 | long long atomic64_inc_386(long long a, atomic64_t *v); | ||
50 | EXPORT_SYMBOL(atomic64_inc_386); | ||
51 | long long atomic64_dec_386(long long a, atomic64_t *v); | ||
52 | EXPORT_SYMBOL(atomic64_dec_386); | ||
53 | long long atomic64_dec_if_positive_386(atomic64_t *v); | ||
54 | EXPORT_SYMBOL(atomic64_dec_if_positive_386); | ||
55 | int atomic64_inc_not_zero_386(atomic64_t *v); | ||
56 | EXPORT_SYMBOL(atomic64_inc_not_zero_386); | ||
57 | int atomic64_add_unless_386(atomic64_t *v, long long a, long long u); | ||
58 | EXPORT_SYMBOL(atomic64_add_unless_386); | ||
59 | #endif | ||
diff --git a/arch/x86/lib/atomic64_386_32.S b/arch/x86/lib/atomic64_386_32.S index 00933d5e992..e8e7e0d06f4 100644 --- a/arch/x86/lib/atomic64_386_32.S +++ b/arch/x86/lib/atomic64_386_32.S | |||
@@ -137,13 +137,13 @@ BEGIN(dec_return) | |||
137 | RET_ENDP | 137 | RET_ENDP |
138 | #undef v | 138 | #undef v |
139 | 139 | ||
140 | #define v %esi | 140 | #define v %ecx |
141 | BEGIN(add_unless) | 141 | BEGIN(add_unless) |
142 | addl %eax, %ecx | 142 | addl %eax, %esi |
143 | adcl %edx, %edi | 143 | adcl %edx, %edi |
144 | addl (v), %eax | 144 | addl (v), %eax |
145 | adcl 4(v), %edx | 145 | adcl 4(v), %edx |
146 | cmpl %eax, %ecx | 146 | cmpl %eax, %esi |
147 | je 3f | 147 | je 3f |
148 | 1: | 148 | 1: |
149 | movl %eax, (v) | 149 | movl %eax, (v) |
diff --git a/arch/x86/lib/atomic64_cx8_32.S b/arch/x86/lib/atomic64_cx8_32.S index f5cc9eb1d51..391a083674b 100644 --- a/arch/x86/lib/atomic64_cx8_32.S +++ b/arch/x86/lib/atomic64_cx8_32.S | |||
@@ -55,6 +55,8 @@ ENDPROC(atomic64_set_cx8) | |||
55 | ENTRY(atomic64_xchg_cx8) | 55 | ENTRY(atomic64_xchg_cx8) |
56 | CFI_STARTPROC | 56 | CFI_STARTPROC |
57 | 57 | ||
58 | movl %ebx, %eax | ||
59 | movl %ecx, %edx | ||
58 | 1: | 60 | 1: |
59 | LOCK_PREFIX | 61 | LOCK_PREFIX |
60 | cmpxchg8b (%esi) | 62 | cmpxchg8b (%esi) |
@@ -76,7 +78,7 @@ ENTRY(atomic64_\func\()_return_cx8) | |||
76 | movl %edx, %edi | 78 | movl %edx, %edi |
77 | movl %ecx, %ebp | 79 | movl %ecx, %ebp |
78 | 80 | ||
79 | read64 %ecx | 81 | read64 %ebp |
80 | 1: | 82 | 1: |
81 | movl %eax, %ebx | 83 | movl %eax, %ebx |
82 | movl %edx, %ecx | 84 | movl %edx, %ecx |
@@ -157,22 +159,23 @@ ENTRY(atomic64_add_unless_cx8) | |||
157 | SAVE ebx | 159 | SAVE ebx |
158 | /* these just push these two parameters on the stack */ | 160 | /* these just push these two parameters on the stack */ |
159 | SAVE edi | 161 | SAVE edi |
160 | SAVE ecx | 162 | SAVE esi |
161 | 163 | ||
162 | movl %eax, %ebp | 164 | movl %ecx, %ebp |
165 | movl %eax, %esi | ||
163 | movl %edx, %edi | 166 | movl %edx, %edi |
164 | 167 | ||
165 | read64 %esi | 168 | read64 %ebp |
166 | 1: | 169 | 1: |
167 | cmpl %eax, 0(%esp) | 170 | cmpl %eax, 0(%esp) |
168 | je 4f | 171 | je 4f |
169 | 2: | 172 | 2: |
170 | movl %eax, %ebx | 173 | movl %eax, %ebx |
171 | movl %edx, %ecx | 174 | movl %edx, %ecx |
172 | addl %ebp, %ebx | 175 | addl %esi, %ebx |
173 | adcl %edi, %ecx | 176 | adcl %edi, %ecx |
174 | LOCK_PREFIX | 177 | LOCK_PREFIX |
175 | cmpxchg8b (%esi) | 178 | cmpxchg8b (%ebp) |
176 | jne 1b | 179 | jne 1b |
177 | 180 | ||
178 | movl $1, %eax | 181 | movl $1, %eax |
@@ -196,13 +199,13 @@ ENTRY(atomic64_inc_not_zero_cx8) | |||
196 | 199 | ||
197 | read64 %esi | 200 | read64 %esi |
198 | 1: | 201 | 1: |
199 | movl %eax, %ecx | 202 | testl %eax, %eax |
200 | orl %edx, %ecx | 203 | je 4f |
201 | jz 3f | 204 | 2: |
202 | movl %eax, %ebx | 205 | movl %eax, %ebx |
203 | xorl %ecx, %ecx | 206 | movl %edx, %ecx |
204 | addl $1, %ebx | 207 | addl $1, %ebx |
205 | adcl %edx, %ecx | 208 | adcl $0, %ecx |
206 | LOCK_PREFIX | 209 | LOCK_PREFIX |
207 | cmpxchg8b (%esi) | 210 | cmpxchg8b (%esi) |
208 | jne 1b | 211 | jne 1b |
@@ -211,5 +214,9 @@ ENTRY(atomic64_inc_not_zero_cx8) | |||
211 | 3: | 214 | 3: |
212 | RESTORE ebx | 215 | RESTORE ebx |
213 | ret | 216 | ret |
217 | 4: | ||
218 | testl %edx, %edx | ||
219 | jne 2b | ||
220 | jmp 3b | ||
214 | CFI_ENDPROC | 221 | CFI_ENDPROC |
215 | ENDPROC(atomic64_inc_not_zero_cx8) | 222 | ENDPROC(atomic64_inc_not_zero_cx8) |
diff --git a/arch/x86/lib/checksum_32.S b/arch/x86/lib/checksum_32.S index 2af5df3ade7..78d16a554db 100644 --- a/arch/x86/lib/checksum_32.S +++ b/arch/x86/lib/checksum_32.S | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/linkage.h> | 28 | #include <linux/linkage.h> |
29 | #include <asm/dwarf2.h> | 29 | #include <asm/dwarf2.h> |
30 | #include <asm/errno.h> | 30 | #include <asm/errno.h> |
31 | #include <asm/asm.h> | ||
32 | 31 | ||
33 | /* | 32 | /* |
34 | * computes a partial checksum, e.g. for TCP/UDP fragments | 33 | * computes a partial checksum, e.g. for TCP/UDP fragments |
@@ -283,11 +282,15 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, | |||
283 | 282 | ||
284 | #define SRC(y...) \ | 283 | #define SRC(y...) \ |
285 | 9999: y; \ | 284 | 9999: y; \ |
286 | _ASM_EXTABLE(9999b, 6001f) | 285 | .section __ex_table, "a"; \ |
286 | .long 9999b, 6001f ; \ | ||
287 | .previous | ||
287 | 288 | ||
288 | #define DST(y...) \ | 289 | #define DST(y...) \ |
289 | 9999: y; \ | 290 | 9999: y; \ |
290 | _ASM_EXTABLE(9999b, 6002f) | 291 | .section __ex_table, "a"; \ |
292 | .long 9999b, 6002f ; \ | ||
293 | .previous | ||
291 | 294 | ||
292 | #ifndef CONFIG_X86_USE_PPRO_CHECKSUM | 295 | #ifndef CONFIG_X86_USE_PPRO_CHECKSUM |
293 | 296 | ||
diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S index 176cca67212..01c805ba535 100644 --- a/arch/x86/lib/copy_page_64.S +++ b/arch/x86/lib/copy_page_64.S | |||
@@ -5,90 +5,96 @@ | |||
5 | #include <asm/alternative-asm.h> | 5 | #include <asm/alternative-asm.h> |
6 | 6 | ||
7 | ALIGN | 7 | ALIGN |
8 | copy_page_rep: | 8 | copy_page_c: |
9 | CFI_STARTPROC | 9 | CFI_STARTPROC |
10 | movl $4096/8, %ecx | 10 | movl $4096/8,%ecx |
11 | rep movsq | 11 | rep movsq |
12 | ret | 12 | ret |
13 | CFI_ENDPROC | 13 | CFI_ENDPROC |
14 | ENDPROC(copy_page_rep) | 14 | ENDPROC(copy_page_c) |
15 | 15 | ||
16 | /* | 16 | /* Don't use streaming store because it's better when the target |
17 | * Don't use streaming copy unless the CPU indicates X86_FEATURE_REP_GOOD. | 17 | ends up in cache. */ |
18 | * Could vary the prefetch distance based on SMP/UP. | 18 | |
19 | */ | 19 | /* Could vary the prefetch distance based on SMP/UP */ |
20 | 20 | ||
21 | ENTRY(copy_page) | 21 | ENTRY(copy_page) |
22 | CFI_STARTPROC | 22 | CFI_STARTPROC |
23 | subq $2*8, %rsp | 23 | subq $3*8,%rsp |
24 | CFI_ADJUST_CFA_OFFSET 2*8 | 24 | CFI_ADJUST_CFA_OFFSET 3*8 |
25 | movq %rbx, (%rsp) | 25 | movq %rbx,(%rsp) |
26 | CFI_REL_OFFSET rbx, 0 | 26 | CFI_REL_OFFSET rbx, 0 |
27 | movq %r12, 1*8(%rsp) | 27 | movq %r12,1*8(%rsp) |
28 | CFI_REL_OFFSET r12, 1*8 | 28 | CFI_REL_OFFSET r12, 1*8 |
29 | movq %r13,2*8(%rsp) | ||
30 | CFI_REL_OFFSET r13, 2*8 | ||
29 | 31 | ||
30 | movl $(4096/64)-5, %ecx | 32 | movl $(4096/64)-5,%ecx |
31 | .p2align 4 | 33 | .p2align 4 |
32 | .Loop64: | 34 | .Loop64: |
33 | dec %rcx | 35 | dec %rcx |
34 | movq 0x8*0(%rsi), %rax | 36 | |
35 | movq 0x8*1(%rsi), %rbx | 37 | movq (%rsi), %rax |
36 | movq 0x8*2(%rsi), %rdx | 38 | movq 8 (%rsi), %rbx |
37 | movq 0x8*3(%rsi), %r8 | 39 | movq 16 (%rsi), %rdx |
38 | movq 0x8*4(%rsi), %r9 | 40 | movq 24 (%rsi), %r8 |
39 | movq 0x8*5(%rsi), %r10 | 41 | movq 32 (%rsi), %r9 |
40 | movq 0x8*6(%rsi), %r11 | 42 | movq 40 (%rsi), %r10 |
41 | movq 0x8*7(%rsi), %r12 | 43 | movq 48 (%rsi), %r11 |
44 | movq 56 (%rsi), %r12 | ||
42 | 45 | ||
43 | prefetcht0 5*64(%rsi) | 46 | prefetcht0 5*64(%rsi) |
44 | 47 | ||
45 | movq %rax, 0x8*0(%rdi) | 48 | movq %rax, (%rdi) |
46 | movq %rbx, 0x8*1(%rdi) | 49 | movq %rbx, 8 (%rdi) |
47 | movq %rdx, 0x8*2(%rdi) | 50 | movq %rdx, 16 (%rdi) |
48 | movq %r8, 0x8*3(%rdi) | 51 | movq %r8, 24 (%rdi) |
49 | movq %r9, 0x8*4(%rdi) | 52 | movq %r9, 32 (%rdi) |
50 | movq %r10, 0x8*5(%rdi) | 53 | movq %r10, 40 (%rdi) |
51 | movq %r11, 0x8*6(%rdi) | 54 | movq %r11, 48 (%rdi) |
52 | movq %r12, 0x8*7(%rdi) | 55 | movq %r12, 56 (%rdi) |
53 | 56 | ||
54 | leaq 64 (%rsi), %rsi | 57 | leaq 64 (%rsi), %rsi |
55 | leaq 64 (%rdi), %rdi | 58 | leaq 64 (%rdi), %rdi |
56 | 59 | ||
57 | jnz .Loop64 | 60 | jnz .Loop64 |
58 | 61 | ||
59 | movl $5, %ecx | 62 | movl $5,%ecx |
60 | .p2align 4 | 63 | .p2align 4 |
61 | .Loop2: | 64 | .Loop2: |
62 | decl %ecx | 65 | decl %ecx |
63 | 66 | ||
64 | movq 0x8*0(%rsi), %rax | 67 | movq (%rsi), %rax |
65 | movq 0x8*1(%rsi), %rbx | 68 | movq 8 (%rsi), %rbx |
66 | movq 0x8*2(%rsi), %rdx | 69 | movq 16 (%rsi), %rdx |
67 | movq 0x8*3(%rsi), %r8 | 70 | movq 24 (%rsi), %r8 |
68 | movq 0x8*4(%rsi), %r9 | 71 | movq 32 (%rsi), %r9 |
69 | movq 0x8*5(%rsi), %r10 | 72 | movq 40 (%rsi), %r10 |
70 | movq 0x8*6(%rsi), %r11 | 73 | movq 48 (%rsi), %r11 |
71 | movq 0x8*7(%rsi), %r12 | 74 | movq 56 (%rsi), %r12 |
72 | 75 | ||
73 | movq %rax, 0x8*0(%rdi) | 76 | movq %rax, (%rdi) |
74 | movq %rbx, 0x8*1(%rdi) | 77 | movq %rbx, 8 (%rdi) |
75 | movq %rdx, 0x8*2(%rdi) | 78 | movq %rdx, 16 (%rdi) |
76 | movq %r8, 0x8*3(%rdi) | 79 | movq %r8, 24 (%rdi) |
77 | movq %r9, 0x8*4(%rdi) | 80 | movq %r9, 32 (%rdi) |
78 | movq %r10, 0x8*5(%rdi) | 81 | movq %r10, 40 (%rdi) |
79 | movq %r11, 0x8*6(%rdi) | 82 | movq %r11, 48 (%rdi) |
80 | movq %r12, 0x8*7(%rdi) | 83 | movq %r12, 56 (%rdi) |
81 | 84 | ||
82 | leaq 64(%rdi), %rdi | 85 | leaq 64(%rdi),%rdi |
83 | leaq 64(%rsi), %rsi | 86 | leaq 64(%rsi),%rsi |
87 | |||
84 | jnz .Loop2 | 88 | jnz .Loop2 |
85 | 89 | ||
86 | movq (%rsp), %rbx | 90 | movq (%rsp),%rbx |
87 | CFI_RESTORE rbx | 91 | CFI_RESTORE rbx |
88 | movq 1*8(%rsp), %r12 | 92 | movq 1*8(%rsp),%r12 |
89 | CFI_RESTORE r12 | 93 | CFI_RESTORE r12 |
90 | addq $2*8, %rsp | 94 | movq 2*8(%rsp),%r13 |
91 | CFI_ADJUST_CFA_OFFSET -2*8 | 95 | CFI_RESTORE r13 |
96 | addq $3*8,%rsp | ||
97 | CFI_ADJUST_CFA_OFFSET -3*8 | ||
92 | ret | 98 | ret |
93 | .Lcopy_page_end: | 99 | .Lcopy_page_end: |
94 | CFI_ENDPROC | 100 | CFI_ENDPROC |
@@ -101,7 +107,7 @@ ENDPROC(copy_page) | |||
101 | 107 | ||
102 | .section .altinstr_replacement,"ax" | 108 | .section .altinstr_replacement,"ax" |
103 | 1: .byte 0xeb /* jmp <disp8> */ | 109 | 1: .byte 0xeb /* jmp <disp8> */ |
104 | .byte (copy_page_rep - copy_page) - (2f - 1b) /* offset */ | 110 | .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */ |
105 | 2: | 111 | 2: |
106 | .previous | 112 | .previous |
107 | .section .altinstructions,"a" | 113 | .section .altinstructions,"a" |
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index a30ca15be21..024840266ba 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S | |||
@@ -16,8 +16,6 @@ | |||
16 | #include <asm/thread_info.h> | 16 | #include <asm/thread_info.h> |
17 | #include <asm/cpufeature.h> | 17 | #include <asm/cpufeature.h> |
18 | #include <asm/alternative-asm.h> | 18 | #include <asm/alternative-asm.h> |
19 | #include <asm/asm.h> | ||
20 | #include <asm/smap.h> | ||
21 | 19 | ||
22 | /* | 20 | /* |
23 | * By placing feature2 after feature1 in altinstructions section, we logically | 21 | * By placing feature2 after feature1 in altinstructions section, we logically |
@@ -65,8 +63,11 @@ | |||
65 | jmp copy_user_handle_tail | 63 | jmp copy_user_handle_tail |
66 | .previous | 64 | .previous |
67 | 65 | ||
68 | _ASM_EXTABLE(100b,103b) | 66 | .section __ex_table,"a" |
69 | _ASM_EXTABLE(101b,103b) | 67 | .align 8 |
68 | .quad 100b,103b | ||
69 | .quad 101b,103b | ||
70 | .previous | ||
70 | #endif | 71 | #endif |
71 | .endm | 72 | .endm |
72 | 73 | ||
@@ -131,7 +132,6 @@ ENDPROC(bad_from_user) | |||
131 | */ | 132 | */ |
132 | ENTRY(copy_user_generic_unrolled) | 133 | ENTRY(copy_user_generic_unrolled) |
133 | CFI_STARTPROC | 134 | CFI_STARTPROC |
134 | ASM_STAC | ||
135 | cmpl $8,%edx | 135 | cmpl $8,%edx |
136 | jb 20f /* less then 8 bytes, go to byte copy loop */ | 136 | jb 20f /* less then 8 bytes, go to byte copy loop */ |
137 | ALIGN_DESTINATION | 137 | ALIGN_DESTINATION |
@@ -179,7 +179,6 @@ ENTRY(copy_user_generic_unrolled) | |||
179 | decl %ecx | 179 | decl %ecx |
180 | jnz 21b | 180 | jnz 21b |
181 | 23: xor %eax,%eax | 181 | 23: xor %eax,%eax |
182 | ASM_CLAC | ||
183 | ret | 182 | ret |
184 | 183 | ||
185 | .section .fixup,"ax" | 184 | .section .fixup,"ax" |
@@ -192,26 +191,29 @@ ENTRY(copy_user_generic_unrolled) | |||
192 | 60: jmp copy_user_handle_tail /* ecx is zerorest also */ | 191 | 60: jmp copy_user_handle_tail /* ecx is zerorest also */ |
193 | .previous | 192 | .previous |
194 | 193 | ||
195 | _ASM_EXTABLE(1b,30b) | 194 | .section __ex_table,"a" |
196 | _ASM_EXTABLE(2b,30b) | 195 | .align 8 |
197 | _ASM_EXTABLE(3b,30b) | 196 | .quad 1b,30b |
198 | _ASM_EXTABLE(4b,30b) | 197 | .quad 2b,30b |
199 | _ASM_EXTABLE(5b,30b) | 198 | .quad 3b,30b |
200 | _ASM_EXTABLE(6b,30b) | 199 | .quad 4b,30b |
201 | _ASM_EXTABLE(7b,30b) | 200 | .quad 5b,30b |
202 | _ASM_EXTABLE(8b,30b) | 201 | .quad 6b,30b |
203 | _ASM_EXTABLE(9b,30b) | 202 | .quad 7b,30b |
204 | _ASM_EXTABLE(10b,30b) | 203 | .quad 8b,30b |
205 | _ASM_EXTABLE(11b,30b) | 204 | .quad 9b,30b |
206 | _ASM_EXTABLE(12b,30b) | 205 | .quad 10b,30b |
207 | _ASM_EXTABLE(13b,30b) | 206 | .quad 11b,30b |
208 | _ASM_EXTABLE(14b,30b) | 207 | .quad 12b,30b |
209 | _ASM_EXTABLE(15b,30b) | 208 | .quad 13b,30b |
210 | _ASM_EXTABLE(16b,30b) | 209 | .quad 14b,30b |
211 | _ASM_EXTABLE(18b,40b) | 210 | .quad 15b,30b |
212 | _ASM_EXTABLE(19b,40b) | 211 | .quad 16b,30b |
213 | _ASM_EXTABLE(21b,50b) | 212 | .quad 18b,40b |
214 | _ASM_EXTABLE(22b,50b) | 213 | .quad 19b,40b |
214 | .quad 21b,50b | ||
215 | .quad 22b,50b | ||
216 | .previous | ||
215 | CFI_ENDPROC | 217 | CFI_ENDPROC |
216 | ENDPROC(copy_user_generic_unrolled) | 218 | ENDPROC(copy_user_generic_unrolled) |
217 | 219 | ||
@@ -235,7 +237,6 @@ ENDPROC(copy_user_generic_unrolled) | |||
235 | */ | 237 | */ |
236 | ENTRY(copy_user_generic_string) | 238 | ENTRY(copy_user_generic_string) |
237 | CFI_STARTPROC | 239 | CFI_STARTPROC |
238 | ASM_STAC | ||
239 | andl %edx,%edx | 240 | andl %edx,%edx |
240 | jz 4f | 241 | jz 4f |
241 | cmpl $8,%edx | 242 | cmpl $8,%edx |
@@ -250,7 +251,6 @@ ENTRY(copy_user_generic_string) | |||
250 | 3: rep | 251 | 3: rep |
251 | movsb | 252 | movsb |
252 | 4: xorl %eax,%eax | 253 | 4: xorl %eax,%eax |
253 | ASM_CLAC | ||
254 | ret | 254 | ret |
255 | 255 | ||
256 | .section .fixup,"ax" | 256 | .section .fixup,"ax" |
@@ -259,8 +259,11 @@ ENTRY(copy_user_generic_string) | |||
259 | jmp copy_user_handle_tail | 259 | jmp copy_user_handle_tail |
260 | .previous | 260 | .previous |
261 | 261 | ||
262 | _ASM_EXTABLE(1b,11b) | 262 | .section __ex_table,"a" |
263 | _ASM_EXTABLE(3b,12b) | 263 | .align 8 |
264 | .quad 1b,11b | ||
265 | .quad 3b,12b | ||
266 | .previous | ||
264 | CFI_ENDPROC | 267 | CFI_ENDPROC |
265 | ENDPROC(copy_user_generic_string) | 268 | ENDPROC(copy_user_generic_string) |
266 | 269 | ||
@@ -278,14 +281,12 @@ ENDPROC(copy_user_generic_string) | |||
278 | */ | 281 | */ |
279 | ENTRY(copy_user_enhanced_fast_string) | 282 | ENTRY(copy_user_enhanced_fast_string) |
280 | CFI_STARTPROC | 283 | CFI_STARTPROC |
281 | ASM_STAC | ||
282 | andl %edx,%edx | 284 | andl %edx,%edx |
283 | jz 2f | 285 | jz 2f |
284 | movl %edx,%ecx | 286 | movl %edx,%ecx |
285 | 1: rep | 287 | 1: rep |
286 | movsb | 288 | movsb |
287 | 2: xorl %eax,%eax | 289 | 2: xorl %eax,%eax |
288 | ASM_CLAC | ||
289 | ret | 290 | ret |
290 | 291 | ||
291 | .section .fixup,"ax" | 292 | .section .fixup,"ax" |
@@ -293,6 +294,9 @@ ENTRY(copy_user_enhanced_fast_string) | |||
293 | jmp copy_user_handle_tail | 294 | jmp copy_user_handle_tail |
294 | .previous | 295 | .previous |
295 | 296 | ||
296 | _ASM_EXTABLE(1b,12b) | 297 | .section __ex_table,"a" |
298 | .align 8 | ||
299 | .quad 1b,12b | ||
300 | .previous | ||
297 | CFI_ENDPROC | 301 | CFI_ENDPROC |
298 | ENDPROC(copy_user_enhanced_fast_string) | 302 | ENDPROC(copy_user_enhanced_fast_string) |
diff --git a/arch/x86/lib/copy_user_nocache_64.S b/arch/x86/lib/copy_user_nocache_64.S index 6a4f43c2d9e..cb0c112386f 100644 --- a/arch/x86/lib/copy_user_nocache_64.S +++ b/arch/x86/lib/copy_user_nocache_64.S | |||
@@ -14,8 +14,6 @@ | |||
14 | #include <asm/current.h> | 14 | #include <asm/current.h> |
15 | #include <asm/asm-offsets.h> | 15 | #include <asm/asm-offsets.h> |
16 | #include <asm/thread_info.h> | 16 | #include <asm/thread_info.h> |
17 | #include <asm/asm.h> | ||
18 | #include <asm/smap.h> | ||
19 | 17 | ||
20 | .macro ALIGN_DESTINATION | 18 | .macro ALIGN_DESTINATION |
21 | #ifdef FIX_ALIGNMENT | 19 | #ifdef FIX_ALIGNMENT |
@@ -38,8 +36,11 @@ | |||
38 | jmp copy_user_handle_tail | 36 | jmp copy_user_handle_tail |
39 | .previous | 37 | .previous |
40 | 38 | ||
41 | _ASM_EXTABLE(100b,103b) | 39 | .section __ex_table,"a" |
42 | _ASM_EXTABLE(101b,103b) | 40 | .align 8 |
41 | .quad 100b,103b | ||
42 | .quad 101b,103b | ||
43 | .previous | ||
43 | #endif | 44 | #endif |
44 | .endm | 45 | .endm |
45 | 46 | ||
@@ -49,7 +50,6 @@ | |||
49 | */ | 50 | */ |
50 | ENTRY(__copy_user_nocache) | 51 | ENTRY(__copy_user_nocache) |
51 | CFI_STARTPROC | 52 | CFI_STARTPROC |
52 | ASM_STAC | ||
53 | cmpl $8,%edx | 53 | cmpl $8,%edx |
54 | jb 20f /* less then 8 bytes, go to byte copy loop */ | 54 | jb 20f /* less then 8 bytes, go to byte copy loop */ |
55 | ALIGN_DESTINATION | 55 | ALIGN_DESTINATION |
@@ -97,7 +97,6 @@ ENTRY(__copy_user_nocache) | |||
97 | decl %ecx | 97 | decl %ecx |
98 | jnz 21b | 98 | jnz 21b |
99 | 23: xorl %eax,%eax | 99 | 23: xorl %eax,%eax |
100 | ASM_CLAC | ||
101 | sfence | 100 | sfence |
102 | ret | 101 | ret |
103 | 102 | ||
@@ -112,25 +111,27 @@ ENTRY(__copy_user_nocache) | |||
112 | jmp copy_user_handle_tail | 111 | jmp copy_user_handle_tail |
113 | .previous | 112 | .previous |
114 | 113 | ||
115 | _ASM_EXTABLE(1b,30b) | 114 | .section __ex_table,"a" |
116 | _ASM_EXTABLE(2b,30b) | 115 | .quad 1b,30b |
117 | _ASM_EXTABLE(3b,30b) | 116 | .quad 2b,30b |
118 | _ASM_EXTABLE(4b,30b) | 117 | .quad 3b,30b |
119 | _ASM_EXTABLE(5b,30b) | 118 | .quad 4b,30b |
120 | _ASM_EXTABLE(6b,30b) | 119 | .quad 5b,30b |
121 | _ASM_EXTABLE(7b,30b) | 120 | .quad 6b,30b |
122 | _ASM_EXTABLE(8b,30b) | 121 | .quad 7b,30b |
123 | _ASM_EXTABLE(9b,30b) | 122 | .quad 8b,30b |
124 | _ASM_EXTABLE(10b,30b) | 123 | .quad 9b,30b |
125 | _ASM_EXTABLE(11b,30b) | 124 | .quad 10b,30b |
126 | _ASM_EXTABLE(12b,30b) | 125 | .quad 11b,30b |
127 | _ASM_EXTABLE(13b,30b) | 126 | .quad 12b,30b |
128 | _ASM_EXTABLE(14b,30b) | 127 | .quad 13b,30b |
129 | _ASM_EXTABLE(15b,30b) | 128 | .quad 14b,30b |
130 | _ASM_EXTABLE(16b,30b) | 129 | .quad 15b,30b |
131 | _ASM_EXTABLE(18b,40b) | 130 | .quad 16b,30b |
132 | _ASM_EXTABLE(19b,40b) | 131 | .quad 18b,40b |
133 | _ASM_EXTABLE(21b,50b) | 132 | .quad 19b,40b |
134 | _ASM_EXTABLE(22b,50b) | 133 | .quad 21b,50b |
134 | .quad 22b,50b | ||
135 | .previous | ||
135 | CFI_ENDPROC | 136 | CFI_ENDPROC |
136 | ENDPROC(__copy_user_nocache) | 137 | ENDPROC(__copy_user_nocache) |
diff --git a/arch/x86/lib/csum-copy_64.S b/arch/x86/lib/csum-copy_64.S index 2419d5fefae..fb903b758da 100644 --- a/arch/x86/lib/csum-copy_64.S +++ b/arch/x86/lib/csum-copy_64.S | |||
@@ -8,7 +8,6 @@ | |||
8 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
9 | #include <asm/dwarf2.h> | 9 | #include <asm/dwarf2.h> |
10 | #include <asm/errno.h> | 10 | #include <asm/errno.h> |
11 | #include <asm/asm.h> | ||
12 | 11 | ||
13 | /* | 12 | /* |
14 | * Checksum copy with exception handling. | 13 | * Checksum copy with exception handling. |
@@ -32,17 +31,26 @@ | |||
32 | 31 | ||
33 | .macro source | 32 | .macro source |
34 | 10: | 33 | 10: |
35 | _ASM_EXTABLE(10b, .Lbad_source) | 34 | .section __ex_table, "a" |
35 | .align 8 | ||
36 | .quad 10b, .Lbad_source | ||
37 | .previous | ||
36 | .endm | 38 | .endm |
37 | 39 | ||
38 | .macro dest | 40 | .macro dest |
39 | 20: | 41 | 20: |
40 | _ASM_EXTABLE(20b, .Lbad_dest) | 42 | .section __ex_table, "a" |
43 | .align 8 | ||
44 | .quad 20b, .Lbad_dest | ||
45 | .previous | ||
41 | .endm | 46 | .endm |
42 | 47 | ||
43 | .macro ignore L=.Lignore | 48 | .macro ignore L=.Lignore |
44 | 30: | 49 | 30: |
45 | _ASM_EXTABLE(30b, \L) | 50 | .section __ex_table, "a" |
51 | .align 8 | ||
52 | .quad 30b, \L | ||
53 | .previous | ||
46 | .endm | 54 | .endm |
47 | 55 | ||
48 | 56 | ||
diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c index 25b7ae8d058..459b58a8a15 100644 --- a/arch/x86/lib/csum-wrappers_64.c +++ b/arch/x86/lib/csum-wrappers_64.c | |||
@@ -115,7 +115,7 @@ EXPORT_SYMBOL(csum_partial_copy_to_user); | |||
115 | * @src: source address | 115 | * @src: source address |
116 | * @dst: destination address | 116 | * @dst: destination address |
117 | * @len: number of bytes to be copied. | 117 | * @len: number of bytes to be copied. |
118 | * @sum: initial sum that is added into the result (32bit unfolded) | 118 | * @isum: initial sum that is added into the result (32bit unfolded) |
119 | * | 119 | * |
120 | * Returns an 32bit unfolded checksum of the buffer. | 120 | * Returns an 32bit unfolded checksum of the buffer. |
121 | */ | 121 | */ |
diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c index 7c3bee636e2..fc45ba887d0 100644 --- a/arch/x86/lib/delay.c +++ b/arch/x86/lib/delay.c | |||
@@ -48,9 +48,9 @@ static void delay_loop(unsigned long loops) | |||
48 | } | 48 | } |
49 | 49 | ||
50 | /* TSC based delay: */ | 50 | /* TSC based delay: */ |
51 | static void delay_tsc(unsigned long __loops) | 51 | static void delay_tsc(unsigned long loops) |
52 | { | 52 | { |
53 | u32 bclock, now, loops = __loops; | 53 | unsigned long bclock, now; |
54 | int cpu; | 54 | int cpu; |
55 | 55 | ||
56 | preempt_disable(); | 56 | preempt_disable(); |
@@ -98,7 +98,7 @@ void use_tsc_delay(void) | |||
98 | delay_fn = delay_tsc; | 98 | delay_fn = delay_tsc; |
99 | } | 99 | } |
100 | 100 | ||
101 | int read_current_timer(unsigned long *timer_val) | 101 | int __devinit read_current_timer(unsigned long *timer_val) |
102 | { | 102 | { |
103 | if (delay_fn == delay_tsc) { | 103 | if (delay_fn == delay_tsc) { |
104 | rdtscll(*timer_val); | 104 | rdtscll(*timer_val); |
diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S index 156b9c80467..51f1504cddd 100644 --- a/arch/x86/lib/getuser.S +++ b/arch/x86/lib/getuser.S | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <asm/asm-offsets.h> | 33 | #include <asm/asm-offsets.h> |
34 | #include <asm/thread_info.h> | 34 | #include <asm/thread_info.h> |
35 | #include <asm/asm.h> | 35 | #include <asm/asm.h> |
36 | #include <asm/smap.h> | ||
37 | 36 | ||
38 | .text | 37 | .text |
39 | ENTRY(__get_user_1) | 38 | ENTRY(__get_user_1) |
@@ -41,10 +40,8 @@ ENTRY(__get_user_1) | |||
41 | GET_THREAD_INFO(%_ASM_DX) | 40 | GET_THREAD_INFO(%_ASM_DX) |
42 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | 41 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX |
43 | jae bad_get_user | 42 | jae bad_get_user |
44 | ASM_STAC | ||
45 | 1: movzb (%_ASM_AX),%edx | 43 | 1: movzb (%_ASM_AX),%edx |
46 | xor %eax,%eax | 44 | xor %eax,%eax |
47 | ASM_CLAC | ||
48 | ret | 45 | ret |
49 | CFI_ENDPROC | 46 | CFI_ENDPROC |
50 | ENDPROC(__get_user_1) | 47 | ENDPROC(__get_user_1) |
@@ -56,10 +53,8 @@ ENTRY(__get_user_2) | |||
56 | GET_THREAD_INFO(%_ASM_DX) | 53 | GET_THREAD_INFO(%_ASM_DX) |
57 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | 54 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX |
58 | jae bad_get_user | 55 | jae bad_get_user |
59 | ASM_STAC | ||
60 | 2: movzwl -1(%_ASM_AX),%edx | 56 | 2: movzwl -1(%_ASM_AX),%edx |
61 | xor %eax,%eax | 57 | xor %eax,%eax |
62 | ASM_CLAC | ||
63 | ret | 58 | ret |
64 | CFI_ENDPROC | 59 | CFI_ENDPROC |
65 | ENDPROC(__get_user_2) | 60 | ENDPROC(__get_user_2) |
@@ -71,10 +66,8 @@ ENTRY(__get_user_4) | |||
71 | GET_THREAD_INFO(%_ASM_DX) | 66 | GET_THREAD_INFO(%_ASM_DX) |
72 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | 67 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX |
73 | jae bad_get_user | 68 | jae bad_get_user |
74 | ASM_STAC | ||
75 | 3: mov -3(%_ASM_AX),%edx | 69 | 3: mov -3(%_ASM_AX),%edx |
76 | xor %eax,%eax | 70 | xor %eax,%eax |
77 | ASM_CLAC | ||
78 | ret | 71 | ret |
79 | CFI_ENDPROC | 72 | CFI_ENDPROC |
80 | ENDPROC(__get_user_4) | 73 | ENDPROC(__get_user_4) |
@@ -87,10 +80,8 @@ ENTRY(__get_user_8) | |||
87 | GET_THREAD_INFO(%_ASM_DX) | 80 | GET_THREAD_INFO(%_ASM_DX) |
88 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | 81 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX |
89 | jae bad_get_user | 82 | jae bad_get_user |
90 | ASM_STAC | ||
91 | 4: movq -7(%_ASM_AX),%_ASM_DX | 83 | 4: movq -7(%_ASM_AX),%_ASM_DX |
92 | xor %eax,%eax | 84 | xor %eax,%eax |
93 | ASM_CLAC | ||
94 | ret | 85 | ret |
95 | CFI_ENDPROC | 86 | CFI_ENDPROC |
96 | ENDPROC(__get_user_8) | 87 | ENDPROC(__get_user_8) |
@@ -100,14 +91,14 @@ bad_get_user: | |||
100 | CFI_STARTPROC | 91 | CFI_STARTPROC |
101 | xor %edx,%edx | 92 | xor %edx,%edx |
102 | mov $(-EFAULT),%_ASM_AX | 93 | mov $(-EFAULT),%_ASM_AX |
103 | ASM_CLAC | ||
104 | ret | 94 | ret |
105 | CFI_ENDPROC | 95 | CFI_ENDPROC |
106 | END(bad_get_user) | 96 | END(bad_get_user) |
107 | 97 | ||
108 | _ASM_EXTABLE(1b,bad_get_user) | 98 | .section __ex_table,"a" |
109 | _ASM_EXTABLE(2b,bad_get_user) | 99 | _ASM_PTR 1b,bad_get_user |
110 | _ASM_EXTABLE(3b,bad_get_user) | 100 | _ASM_PTR 2b,bad_get_user |
101 | _ASM_PTR 3b,bad_get_user | ||
111 | #ifdef CONFIG_X86_64 | 102 | #ifdef CONFIG_X86_64 |
112 | _ASM_EXTABLE(4b,bad_get_user) | 103 | _ASM_PTR 4b,bad_get_user |
113 | #endif | 104 | #endif |
diff --git a/arch/x86/lib/inat.c b/arch/x86/lib/inat.c index c1f01a8e9f6..46fc4ee09fc 100644 --- a/arch/x86/lib/inat.c +++ b/arch/x86/lib/inat.c | |||
@@ -29,46 +29,46 @@ insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode) | |||
29 | return inat_primary_table[opcode]; | 29 | return inat_primary_table[opcode]; |
30 | } | 30 | } |
31 | 31 | ||
32 | int inat_get_last_prefix_id(insn_byte_t last_pfx) | 32 | insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, insn_byte_t last_pfx, |
33 | { | ||
34 | insn_attr_t lpfx_attr; | ||
35 | |||
36 | lpfx_attr = inat_get_opcode_attribute(last_pfx); | ||
37 | return inat_last_prefix_id(lpfx_attr); | ||
38 | } | ||
39 | |||
40 | insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id, | ||
41 | insn_attr_t esc_attr) | 33 | insn_attr_t esc_attr) |
42 | { | 34 | { |
43 | const insn_attr_t *table; | 35 | const insn_attr_t *table; |
44 | int n; | 36 | insn_attr_t lpfx_attr; |
37 | int n, m = 0; | ||
45 | 38 | ||
46 | n = inat_escape_id(esc_attr); | 39 | n = inat_escape_id(esc_attr); |
47 | 40 | if (last_pfx) { | |
41 | lpfx_attr = inat_get_opcode_attribute(last_pfx); | ||
42 | m = inat_last_prefix_id(lpfx_attr); | ||
43 | } | ||
48 | table = inat_escape_tables[n][0]; | 44 | table = inat_escape_tables[n][0]; |
49 | if (!table) | 45 | if (!table) |
50 | return 0; | 46 | return 0; |
51 | if (inat_has_variant(table[opcode]) && lpfx_id) { | 47 | if (inat_has_variant(table[opcode]) && m) { |
52 | table = inat_escape_tables[n][lpfx_id]; | 48 | table = inat_escape_tables[n][m]; |
53 | if (!table) | 49 | if (!table) |
54 | return 0; | 50 | return 0; |
55 | } | 51 | } |
56 | return table[opcode]; | 52 | return table[opcode]; |
57 | } | 53 | } |
58 | 54 | ||
59 | insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id, | 55 | insn_attr_t inat_get_group_attribute(insn_byte_t modrm, insn_byte_t last_pfx, |
60 | insn_attr_t grp_attr) | 56 | insn_attr_t grp_attr) |
61 | { | 57 | { |
62 | const insn_attr_t *table; | 58 | const insn_attr_t *table; |
63 | int n; | 59 | insn_attr_t lpfx_attr; |
60 | int n, m = 0; | ||
64 | 61 | ||
65 | n = inat_group_id(grp_attr); | 62 | n = inat_group_id(grp_attr); |
66 | 63 | if (last_pfx) { | |
64 | lpfx_attr = inat_get_opcode_attribute(last_pfx); | ||
65 | m = inat_last_prefix_id(lpfx_attr); | ||
66 | } | ||
67 | table = inat_group_tables[n][0]; | 67 | table = inat_group_tables[n][0]; |
68 | if (!table) | 68 | if (!table) |
69 | return inat_group_common_attribute(grp_attr); | 69 | return inat_group_common_attribute(grp_attr); |
70 | if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) { | 70 | if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && m) { |
71 | table = inat_group_tables[n][lpfx_id]; | 71 | table = inat_group_tables[n][m]; |
72 | if (!table) | 72 | if (!table) |
73 | return inat_group_common_attribute(grp_attr); | 73 | return inat_group_common_attribute(grp_attr); |
74 | } | 74 | } |
@@ -82,16 +82,9 @@ insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m, | |||
82 | const insn_attr_t *table; | 82 | const insn_attr_t *table; |
83 | if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX) | 83 | if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX) |
84 | return 0; | 84 | return 0; |
85 | /* At first, this checks the master table */ | 85 | table = inat_avx_tables[vex_m][vex_p]; |
86 | table = inat_avx_tables[vex_m][0]; | ||
87 | if (!table) | 86 | if (!table) |
88 | return 0; | 87 | return 0; |
89 | if (!inat_is_group(table[opcode]) && vex_p) { | ||
90 | /* If this is not a group, get attribute directly */ | ||
91 | table = inat_avx_tables[vex_m][vex_p]; | ||
92 | if (!table) | ||
93 | return 0; | ||
94 | } | ||
95 | return table[opcode]; | 88 | return table[opcode]; |
96 | } | 89 | } |
97 | 90 | ||
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c index 54fcffed28e..9f33b984d0e 100644 --- a/arch/x86/lib/insn.c +++ b/arch/x86/lib/insn.c | |||
@@ -18,31 +18,18 @@ | |||
18 | * Copyright (C) IBM Corporation, 2002, 2004, 2009 | 18 | * Copyright (C) IBM Corporation, 2002, 2004, 2009 |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #ifdef __KERNEL__ | ||
22 | #include <linux/string.h> | 21 | #include <linux/string.h> |
23 | #else | ||
24 | #include <string.h> | ||
25 | #endif | ||
26 | #include <asm/inat.h> | 22 | #include <asm/inat.h> |
27 | #include <asm/insn.h> | 23 | #include <asm/insn.h> |
28 | 24 | ||
29 | /* Verify next sizeof(t) bytes can be on the same instruction */ | ||
30 | #define validate_next(t, insn, n) \ | ||
31 | ((insn)->next_byte + sizeof(t) + n - (insn)->kaddr <= MAX_INSN_SIZE) | ||
32 | |||
33 | #define __get_next(t, insn) \ | ||
34 | ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) | ||
35 | |||
36 | #define __peek_nbyte_next(t, insn, n) \ | ||
37 | ({ t r = *(t*)((insn)->next_byte + n); r; }) | ||
38 | |||
39 | #define get_next(t, insn) \ | 25 | #define get_next(t, insn) \ |
40 | ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) | 26 | ({t r; r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) |
41 | 27 | ||
42 | #define peek_nbyte_next(t, insn, n) \ | 28 | #define peek_next(t, insn) \ |
43 | ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); }) | 29 | ({t r; r = *(t*)insn->next_byte; r; }) |
44 | 30 | ||
45 | #define peek_next(t, insn) peek_nbyte_next(t, insn, 0) | 31 | #define peek_nbyte_next(t, insn, n) \ |
32 | ({t r; r = *(t*)((insn)->next_byte + n); r; }) | ||
46 | 33 | ||
47 | /** | 34 | /** |
48 | * insn_init() - initialize struct insn | 35 | * insn_init() - initialize struct insn |
@@ -171,8 +158,6 @@ vex_end: | |||
171 | insn->vex_prefix.got = 1; | 158 | insn->vex_prefix.got = 1; |
172 | 159 | ||
173 | prefixes->got = 1; | 160 | prefixes->got = 1; |
174 | |||
175 | err_out: | ||
176 | return; | 161 | return; |
177 | } | 162 | } |
178 | 163 | ||
@@ -189,8 +174,7 @@ err_out: | |||
189 | void insn_get_opcode(struct insn *insn) | 174 | void insn_get_opcode(struct insn *insn) |
190 | { | 175 | { |
191 | struct insn_field *opcode = &insn->opcode; | 176 | struct insn_field *opcode = &insn->opcode; |
192 | insn_byte_t op; | 177 | insn_byte_t op, pfx; |
193 | int pfx_id; | ||
194 | if (opcode->got) | 178 | if (opcode->got) |
195 | return; | 179 | return; |
196 | if (!insn->prefixes.got) | 180 | if (!insn->prefixes.got) |
@@ -207,7 +191,7 @@ void insn_get_opcode(struct insn *insn) | |||
207 | m = insn_vex_m_bits(insn); | 191 | m = insn_vex_m_bits(insn); |
208 | p = insn_vex_p_bits(insn); | 192 | p = insn_vex_p_bits(insn); |
209 | insn->attr = inat_get_avx_attribute(op, m, p); | 193 | insn->attr = inat_get_avx_attribute(op, m, p); |
210 | if (!inat_accept_vex(insn->attr) && !inat_is_group(insn->attr)) | 194 | if (!inat_accept_vex(insn->attr)) |
211 | insn->attr = 0; /* This instruction is bad */ | 195 | insn->attr = 0; /* This instruction is bad */ |
212 | goto end; /* VEX has only 1 byte for opcode */ | 196 | goto end; /* VEX has only 1 byte for opcode */ |
213 | } | 197 | } |
@@ -217,16 +201,13 @@ void insn_get_opcode(struct insn *insn) | |||
217 | /* Get escaped opcode */ | 201 | /* Get escaped opcode */ |
218 | op = get_next(insn_byte_t, insn); | 202 | op = get_next(insn_byte_t, insn); |
219 | opcode->bytes[opcode->nbytes++] = op; | 203 | opcode->bytes[opcode->nbytes++] = op; |
220 | pfx_id = insn_last_prefix_id(insn); | 204 | pfx = insn_last_prefix(insn); |
221 | insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr); | 205 | insn->attr = inat_get_escape_attribute(op, pfx, insn->attr); |
222 | } | 206 | } |
223 | if (inat_must_vex(insn->attr)) | 207 | if (inat_must_vex(insn->attr)) |
224 | insn->attr = 0; /* This instruction is bad */ | 208 | insn->attr = 0; /* This instruction is bad */ |
225 | end: | 209 | end: |
226 | opcode->got = 1; | 210 | opcode->got = 1; |
227 | |||
228 | err_out: | ||
229 | return; | ||
230 | } | 211 | } |
231 | 212 | ||
232 | /** | 213 | /** |
@@ -240,7 +221,7 @@ err_out: | |||
240 | void insn_get_modrm(struct insn *insn) | 221 | void insn_get_modrm(struct insn *insn) |
241 | { | 222 | { |
242 | struct insn_field *modrm = &insn->modrm; | 223 | struct insn_field *modrm = &insn->modrm; |
243 | insn_byte_t pfx_id, mod; | 224 | insn_byte_t pfx, mod; |
244 | if (modrm->got) | 225 | if (modrm->got) |
245 | return; | 226 | return; |
246 | if (!insn->opcode.got) | 227 | if (!insn->opcode.got) |
@@ -251,20 +232,15 @@ void insn_get_modrm(struct insn *insn) | |||
251 | modrm->value = mod; | 232 | modrm->value = mod; |
252 | modrm->nbytes = 1; | 233 | modrm->nbytes = 1; |
253 | if (inat_is_group(insn->attr)) { | 234 | if (inat_is_group(insn->attr)) { |
254 | pfx_id = insn_last_prefix_id(insn); | 235 | pfx = insn_last_prefix(insn); |
255 | insn->attr = inat_get_group_attribute(mod, pfx_id, | 236 | insn->attr = inat_get_group_attribute(mod, pfx, |
256 | insn->attr); | 237 | insn->attr); |
257 | if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) | ||
258 | insn->attr = 0; /* This is bad */ | ||
259 | } | 238 | } |
260 | } | 239 | } |
261 | 240 | ||
262 | if (insn->x86_64 && inat_is_force64(insn->attr)) | 241 | if (insn->x86_64 && inat_is_force64(insn->attr)) |
263 | insn->opnd_bytes = 8; | 242 | insn->opnd_bytes = 8; |
264 | modrm->got = 1; | 243 | modrm->got = 1; |
265 | |||
266 | err_out: | ||
267 | return; | ||
268 | } | 244 | } |
269 | 245 | ||
270 | 246 | ||
@@ -314,9 +290,6 @@ void insn_get_sib(struct insn *insn) | |||
314 | } | 290 | } |
315 | } | 291 | } |
316 | insn->sib.got = 1; | 292 | insn->sib.got = 1; |
317 | |||
318 | err_out: | ||
319 | return; | ||
320 | } | 293 | } |
321 | 294 | ||
322 | 295 | ||
@@ -378,13 +351,10 @@ void insn_get_displacement(struct insn *insn) | |||
378 | } | 351 | } |
379 | out: | 352 | out: |
380 | insn->displacement.got = 1; | 353 | insn->displacement.got = 1; |
381 | |||
382 | err_out: | ||
383 | return; | ||
384 | } | 354 | } |
385 | 355 | ||
386 | /* Decode moffset16/32/64. Return 0 if failed */ | 356 | /* Decode moffset16/32/64 */ |
387 | static int __get_moffset(struct insn *insn) | 357 | static void __get_moffset(struct insn *insn) |
388 | { | 358 | { |
389 | switch (insn->addr_bytes) { | 359 | switch (insn->addr_bytes) { |
390 | case 2: | 360 | case 2: |
@@ -401,19 +371,12 @@ static int __get_moffset(struct insn *insn) | |||
401 | insn->moffset2.value = get_next(int, insn); | 371 | insn->moffset2.value = get_next(int, insn); |
402 | insn->moffset2.nbytes = 4; | 372 | insn->moffset2.nbytes = 4; |
403 | break; | 373 | break; |
404 | default: /* opnd_bytes must be modified manually */ | ||
405 | goto err_out; | ||
406 | } | 374 | } |
407 | insn->moffset1.got = insn->moffset2.got = 1; | 375 | insn->moffset1.got = insn->moffset2.got = 1; |
408 | |||
409 | return 1; | ||
410 | |||
411 | err_out: | ||
412 | return 0; | ||
413 | } | 376 | } |
414 | 377 | ||
415 | /* Decode imm v32(Iz). Return 0 if failed */ | 378 | /* Decode imm v32(Iz) */ |
416 | static int __get_immv32(struct insn *insn) | 379 | static void __get_immv32(struct insn *insn) |
417 | { | 380 | { |
418 | switch (insn->opnd_bytes) { | 381 | switch (insn->opnd_bytes) { |
419 | case 2: | 382 | case 2: |
@@ -425,18 +388,11 @@ static int __get_immv32(struct insn *insn) | |||
425 | insn->immediate.value = get_next(int, insn); | 388 | insn->immediate.value = get_next(int, insn); |
426 | insn->immediate.nbytes = 4; | 389 | insn->immediate.nbytes = 4; |
427 | break; | 390 | break; |
428 | default: /* opnd_bytes must be modified manually */ | ||
429 | goto err_out; | ||
430 | } | 391 | } |
431 | |||
432 | return 1; | ||
433 | |||
434 | err_out: | ||
435 | return 0; | ||
436 | } | 392 | } |
437 | 393 | ||
438 | /* Decode imm v64(Iv/Ov), Return 0 if failed */ | 394 | /* Decode imm v64(Iv/Ov) */ |
439 | static int __get_immv(struct insn *insn) | 395 | static void __get_immv(struct insn *insn) |
440 | { | 396 | { |
441 | switch (insn->opnd_bytes) { | 397 | switch (insn->opnd_bytes) { |
442 | case 2: | 398 | case 2: |
@@ -453,18 +409,12 @@ static int __get_immv(struct insn *insn) | |||
453 | insn->immediate2.value = get_next(int, insn); | 409 | insn->immediate2.value = get_next(int, insn); |
454 | insn->immediate2.nbytes = 4; | 410 | insn->immediate2.nbytes = 4; |
455 | break; | 411 | break; |
456 | default: /* opnd_bytes must be modified manually */ | ||
457 | goto err_out; | ||
458 | } | 412 | } |
459 | insn->immediate1.got = insn->immediate2.got = 1; | 413 | insn->immediate1.got = insn->immediate2.got = 1; |
460 | |||
461 | return 1; | ||
462 | err_out: | ||
463 | return 0; | ||
464 | } | 414 | } |
465 | 415 | ||
466 | /* Decode ptr16:16/32(Ap) */ | 416 | /* Decode ptr16:16/32(Ap) */ |
467 | static int __get_immptr(struct insn *insn) | 417 | static void __get_immptr(struct insn *insn) |
468 | { | 418 | { |
469 | switch (insn->opnd_bytes) { | 419 | switch (insn->opnd_bytes) { |
470 | case 2: | 420 | case 2: |
@@ -477,17 +427,11 @@ static int __get_immptr(struct insn *insn) | |||
477 | break; | 427 | break; |
478 | case 8: | 428 | case 8: |
479 | /* ptr16:64 is not exist (no segment) */ | 429 | /* ptr16:64 is not exist (no segment) */ |
480 | return 0; | 430 | return; |
481 | default: /* opnd_bytes must be modified manually */ | ||
482 | goto err_out; | ||
483 | } | 431 | } |
484 | insn->immediate2.value = get_next(unsigned short, insn); | 432 | insn->immediate2.value = get_next(unsigned short, insn); |
485 | insn->immediate2.nbytes = 2; | 433 | insn->immediate2.nbytes = 2; |
486 | insn->immediate1.got = insn->immediate2.got = 1; | 434 | insn->immediate1.got = insn->immediate2.got = 1; |
487 | |||
488 | return 1; | ||
489 | err_out: | ||
490 | return 0; | ||
491 | } | 435 | } |
492 | 436 | ||
493 | /** | 437 | /** |
@@ -507,8 +451,7 @@ void insn_get_immediate(struct insn *insn) | |||
507 | insn_get_displacement(insn); | 451 | insn_get_displacement(insn); |
508 | 452 | ||
509 | if (inat_has_moffset(insn->attr)) { | 453 | if (inat_has_moffset(insn->attr)) { |
510 | if (!__get_moffset(insn)) | 454 | __get_moffset(insn); |
511 | goto err_out; | ||
512 | goto done; | 455 | goto done; |
513 | } | 456 | } |
514 | 457 | ||
@@ -536,20 +479,16 @@ void insn_get_immediate(struct insn *insn) | |||
536 | insn->immediate2.nbytes = 4; | 479 | insn->immediate2.nbytes = 4; |
537 | break; | 480 | break; |
538 | case INAT_IMM_PTR: | 481 | case INAT_IMM_PTR: |
539 | if (!__get_immptr(insn)) | 482 | __get_immptr(insn); |
540 | goto err_out; | ||
541 | break; | 483 | break; |
542 | case INAT_IMM_VWORD32: | 484 | case INAT_IMM_VWORD32: |
543 | if (!__get_immv32(insn)) | 485 | __get_immv32(insn); |
544 | goto err_out; | ||
545 | break; | 486 | break; |
546 | case INAT_IMM_VWORD: | 487 | case INAT_IMM_VWORD: |
547 | if (!__get_immv(insn)) | 488 | __get_immv(insn); |
548 | goto err_out; | ||
549 | break; | 489 | break; |
550 | default: | 490 | default: |
551 | /* Here, insn must have an immediate, but failed */ | 491 | break; |
552 | goto err_out; | ||
553 | } | 492 | } |
554 | if (inat_has_second_immediate(insn->attr)) { | 493 | if (inat_has_second_immediate(insn->attr)) { |
555 | insn->immediate2.value = get_next(char, insn); | 494 | insn->immediate2.value = get_next(char, insn); |
@@ -557,9 +496,6 @@ void insn_get_immediate(struct insn *insn) | |||
557 | } | 496 | } |
558 | done: | 497 | done: |
559 | insn->immediate.got = 1; | 498 | insn->immediate.got = 1; |
560 | |||
561 | err_out: | ||
562 | return; | ||
563 | } | 499 | } |
564 | 500 | ||
565 | /** | 501 | /** |
diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S index 1c273be7c97..efbf2a0ecde 100644 --- a/arch/x86/lib/memcpy_64.S +++ b/arch/x86/lib/memcpy_64.S | |||
@@ -27,8 +27,9 @@ | |||
27 | .section .altinstr_replacement, "ax", @progbits | 27 | .section .altinstr_replacement, "ax", @progbits |
28 | .Lmemcpy_c: | 28 | .Lmemcpy_c: |
29 | movq %rdi, %rax | 29 | movq %rdi, %rax |
30 | movq %rdx, %rcx | 30 | |
31 | shrq $3, %rcx | 31 | movl %edx, %ecx |
32 | shrl $3, %ecx | ||
32 | andl $7, %edx | 33 | andl $7, %edx |
33 | rep movsq | 34 | rep movsq |
34 | movl %edx, %ecx | 35 | movl %edx, %ecx |
@@ -47,7 +48,8 @@ | |||
47 | .section .altinstr_replacement, "ax", @progbits | 48 | .section .altinstr_replacement, "ax", @progbits |
48 | .Lmemcpy_c_e: | 49 | .Lmemcpy_c_e: |
49 | movq %rdi, %rax | 50 | movq %rdi, %rax |
50 | movq %rdx, %rcx | 51 | |
52 | movl %edx, %ecx | ||
51 | rep movsb | 53 | rep movsb |
52 | ret | 54 | ret |
53 | .Lmemcpy_e_e: | 55 | .Lmemcpy_e_e: |
@@ -58,7 +60,10 @@ ENTRY(memcpy) | |||
58 | CFI_STARTPROC | 60 | CFI_STARTPROC |
59 | movq %rdi, %rax | 61 | movq %rdi, %rax |
60 | 62 | ||
61 | cmpq $0x20, %rdx | 63 | /* |
64 | * Use 32bit CMP here to avoid long NOP padding. | ||
65 | */ | ||
66 | cmp $0x20, %edx | ||
62 | jb .Lhandle_tail | 67 | jb .Lhandle_tail |
63 | 68 | ||
64 | /* | 69 | /* |
@@ -67,7 +72,7 @@ ENTRY(memcpy) | |||
67 | */ | 72 | */ |
68 | cmp %dil, %sil | 73 | cmp %dil, %sil |
69 | jl .Lcopy_backward | 74 | jl .Lcopy_backward |
70 | subq $0x20, %rdx | 75 | subl $0x20, %edx |
71 | .Lcopy_forward_loop: | 76 | .Lcopy_forward_loop: |
72 | subq $0x20, %rdx | 77 | subq $0x20, %rdx |
73 | 78 | ||
@@ -86,7 +91,7 @@ ENTRY(memcpy) | |||
86 | movq %r11, 3*8(%rdi) | 91 | movq %r11, 3*8(%rdi) |
87 | leaq 4*8(%rdi), %rdi | 92 | leaq 4*8(%rdi), %rdi |
88 | jae .Lcopy_forward_loop | 93 | jae .Lcopy_forward_loop |
89 | addl $0x20, %edx | 94 | addq $0x20, %rdx |
90 | jmp .Lhandle_tail | 95 | jmp .Lhandle_tail |
91 | 96 | ||
92 | .Lcopy_backward: | 97 | .Lcopy_backward: |
@@ -118,11 +123,11 @@ ENTRY(memcpy) | |||
118 | /* | 123 | /* |
119 | * Calculate copy position to head. | 124 | * Calculate copy position to head. |
120 | */ | 125 | */ |
121 | addl $0x20, %edx | 126 | addq $0x20, %rdx |
122 | subq %rdx, %rsi | 127 | subq %rdx, %rsi |
123 | subq %rdx, %rdi | 128 | subq %rdx, %rdi |
124 | .Lhandle_tail: | 129 | .Lhandle_tail: |
125 | cmpl $16, %edx | 130 | cmpq $16, %rdx |
126 | jb .Lless_16bytes | 131 | jb .Lless_16bytes |
127 | 132 | ||
128 | /* | 133 | /* |
@@ -139,7 +144,7 @@ ENTRY(memcpy) | |||
139 | retq | 144 | retq |
140 | .p2align 4 | 145 | .p2align 4 |
141 | .Lless_16bytes: | 146 | .Lless_16bytes: |
142 | cmpl $8, %edx | 147 | cmpq $8, %rdx |
143 | jb .Lless_8bytes | 148 | jb .Lless_8bytes |
144 | /* | 149 | /* |
145 | * Move data from 8 bytes to 15 bytes. | 150 | * Move data from 8 bytes to 15 bytes. |
@@ -151,7 +156,7 @@ ENTRY(memcpy) | |||
151 | retq | 156 | retq |
152 | .p2align 4 | 157 | .p2align 4 |
153 | .Lless_8bytes: | 158 | .Lless_8bytes: |
154 | cmpl $4, %edx | 159 | cmpq $4, %rdx |
155 | jb .Lless_3bytes | 160 | jb .Lless_3bytes |
156 | 161 | ||
157 | /* | 162 | /* |
@@ -164,19 +169,18 @@ ENTRY(memcpy) | |||
164 | retq | 169 | retq |
165 | .p2align 4 | 170 | .p2align 4 |
166 | .Lless_3bytes: | 171 | .Lless_3bytes: |
167 | subl $1, %edx | 172 | cmpl $0, %edx |
168 | jb .Lend | 173 | je .Lend |
169 | /* | 174 | /* |
170 | * Move data from 1 bytes to 3 bytes. | 175 | * Move data from 1 bytes to 3 bytes. |
171 | */ | 176 | */ |
172 | movzbl (%rsi), %ecx | 177 | .Lloop_1: |
173 | jz .Lstore_1byte | 178 | movb (%rsi), %r8b |
174 | movzbq 1(%rsi), %r8 | 179 | movb %r8b, (%rdi) |
175 | movzbq (%rsi, %rdx), %r9 | 180 | incq %rdi |
176 | movb %r8b, 1(%rdi) | 181 | incq %rsi |
177 | movb %r9b, (%rdi, %rdx) | 182 | decl %edx |
178 | .Lstore_1byte: | 183 | jnz .Lloop_1 |
179 | movb %cl, (%rdi) | ||
180 | 184 | ||
181 | .Lend: | 185 | .Lend: |
182 | retq | 186 | retq |
diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S index 2dcb3808cbd..79bd454b78a 100644 --- a/arch/x86/lib/memset_64.S +++ b/arch/x86/lib/memset_64.S | |||
@@ -19,15 +19,16 @@ | |||
19 | .section .altinstr_replacement, "ax", @progbits | 19 | .section .altinstr_replacement, "ax", @progbits |
20 | .Lmemset_c: | 20 | .Lmemset_c: |
21 | movq %rdi,%r9 | 21 | movq %rdi,%r9 |
22 | movq %rdx,%rcx | 22 | movl %edx,%r8d |
23 | andl $7,%edx | 23 | andl $7,%r8d |
24 | shrq $3,%rcx | 24 | movl %edx,%ecx |
25 | shrl $3,%ecx | ||
25 | /* expand byte value */ | 26 | /* expand byte value */ |
26 | movzbl %sil,%esi | 27 | movzbl %sil,%esi |
27 | movabs $0x0101010101010101,%rax | 28 | movabs $0x0101010101010101,%rax |
28 | imulq %rsi,%rax | 29 | mulq %rsi /* with rax, clobbers rdx */ |
29 | rep stosq | 30 | rep stosq |
30 | movl %edx,%ecx | 31 | movl %r8d,%ecx |
31 | rep stosb | 32 | rep stosb |
32 | movq %r9,%rax | 33 | movq %r9,%rax |
33 | ret | 34 | ret |
@@ -49,7 +50,7 @@ | |||
49 | .Lmemset_c_e: | 50 | .Lmemset_c_e: |
50 | movq %rdi,%r9 | 51 | movq %rdi,%r9 |
51 | movb %sil,%al | 52 | movb %sil,%al |
52 | movq %rdx,%rcx | 53 | movl %edx,%ecx |
53 | rep stosb | 54 | rep stosb |
54 | movq %r9,%rax | 55 | movq %r9,%rax |
55 | ret | 56 | ret |
@@ -60,11 +61,12 @@ ENTRY(memset) | |||
60 | ENTRY(__memset) | 61 | ENTRY(__memset) |
61 | CFI_STARTPROC | 62 | CFI_STARTPROC |
62 | movq %rdi,%r10 | 63 | movq %rdi,%r10 |
64 | movq %rdx,%r11 | ||
63 | 65 | ||
64 | /* expand byte value */ | 66 | /* expand byte value */ |
65 | movzbl %sil,%ecx | 67 | movzbl %sil,%ecx |
66 | movabs $0x0101010101010101,%rax | 68 | movabs $0x0101010101010101,%rax |
67 | imulq %rcx,%rax | 69 | mul %rcx /* with rax, clobbers rdx */ |
68 | 70 | ||
69 | /* align dst */ | 71 | /* align dst */ |
70 | movl %edi,%r9d | 72 | movl %edi,%r9d |
@@ -73,13 +75,13 @@ ENTRY(__memset) | |||
73 | CFI_REMEMBER_STATE | 75 | CFI_REMEMBER_STATE |
74 | .Lafter_bad_alignment: | 76 | .Lafter_bad_alignment: |
75 | 77 | ||
76 | movq %rdx,%rcx | 78 | movl %r11d,%ecx |
77 | shrq $6,%rcx | 79 | shrl $6,%ecx |
78 | jz .Lhandle_tail | 80 | jz .Lhandle_tail |
79 | 81 | ||
80 | .p2align 4 | 82 | .p2align 4 |
81 | .Lloop_64: | 83 | .Lloop_64: |
82 | decq %rcx | 84 | decl %ecx |
83 | movq %rax,(%rdi) | 85 | movq %rax,(%rdi) |
84 | movq %rax,8(%rdi) | 86 | movq %rax,8(%rdi) |
85 | movq %rax,16(%rdi) | 87 | movq %rax,16(%rdi) |
@@ -95,7 +97,7 @@ ENTRY(__memset) | |||
95 | to predict jump tables. */ | 97 | to predict jump tables. */ |
96 | .p2align 4 | 98 | .p2align 4 |
97 | .Lhandle_tail: | 99 | .Lhandle_tail: |
98 | movl %edx,%ecx | 100 | movl %r11d,%ecx |
99 | andl $63&(~7),%ecx | 101 | andl $63&(~7),%ecx |
100 | jz .Lhandle_7 | 102 | jz .Lhandle_7 |
101 | shrl $3,%ecx | 103 | shrl $3,%ecx |
@@ -107,11 +109,12 @@ ENTRY(__memset) | |||
107 | jnz .Lloop_8 | 109 | jnz .Lloop_8 |
108 | 110 | ||
109 | .Lhandle_7: | 111 | .Lhandle_7: |
110 | andl $7,%edx | 112 | movl %r11d,%ecx |
113 | andl $7,%ecx | ||
111 | jz .Lende | 114 | jz .Lende |
112 | .p2align 4 | 115 | .p2align 4 |
113 | .Lloop_1: | 116 | .Lloop_1: |
114 | decl %edx | 117 | decl %ecx |
115 | movb %al,(%rdi) | 118 | movb %al,(%rdi) |
116 | leaq 1(%rdi),%rdi | 119 | leaq 1(%rdi),%rdi |
117 | jnz .Lloop_1 | 120 | jnz .Lloop_1 |
@@ -122,13 +125,13 @@ ENTRY(__memset) | |||
122 | 125 | ||
123 | CFI_RESTORE_STATE | 126 | CFI_RESTORE_STATE |
124 | .Lbad_alignment: | 127 | .Lbad_alignment: |
125 | cmpq $7,%rdx | 128 | cmpq $7,%r11 |
126 | jbe .Lhandle_7 | 129 | jbe .Lhandle_7 |
127 | movq %rax,(%rdi) /* unaligned store */ | 130 | movq %rax,(%rdi) /* unaligned store */ |
128 | movq $8,%r8 | 131 | movq $8,%r8 |
129 | subq %r9,%r8 | 132 | subq %r9,%r8 |
130 | addq %r8,%rdi | 133 | addq %r8,%rdi |
131 | subq %r8,%rdx | 134 | subq %r8,%r11 |
132 | jmp .Lafter_bad_alignment | 135 | jmp .Lafter_bad_alignment |
133 | .Lfinal: | 136 | .Lfinal: |
134 | CFI_ENDPROC | 137 | CFI_ENDPROC |
diff --git a/arch/x86/lib/msr-reg-export.c b/arch/x86/lib/msr-reg-export.c index 8d6ef78b5d0..a311cc59b65 100644 --- a/arch/x86/lib/msr-reg-export.c +++ b/arch/x86/lib/msr-reg-export.c | |||
@@ -1,5 +1,5 @@ | |||
1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
2 | #include <asm/msr.h> | 2 | #include <asm/msr.h> |
3 | 3 | ||
4 | EXPORT_SYMBOL(rdmsr_safe_regs); | 4 | EXPORT_SYMBOL(native_rdmsr_safe_regs); |
5 | EXPORT_SYMBOL(wrmsr_safe_regs); | 5 | EXPORT_SYMBOL(native_wrmsr_safe_regs); |
diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S index f6d13eefad1..69fa10623f2 100644 --- a/arch/x86/lib/msr-reg.S +++ b/arch/x86/lib/msr-reg.S | |||
@@ -6,13 +6,13 @@ | |||
6 | 6 | ||
7 | #ifdef CONFIG_X86_64 | 7 | #ifdef CONFIG_X86_64 |
8 | /* | 8 | /* |
9 | * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]); | 9 | * int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]); |
10 | * | 10 | * |
11 | * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] | 11 | * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] |
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | .macro op_safe_regs op | 14 | .macro op_safe_regs op |
15 | ENTRY(\op\()_safe_regs) | 15 | ENTRY(native_\op\()_safe_regs) |
16 | CFI_STARTPROC | 16 | CFI_STARTPROC |
17 | pushq_cfi %rbx | 17 | pushq_cfi %rbx |
18 | pushq_cfi %rbp | 18 | pushq_cfi %rbp |
@@ -45,13 +45,13 @@ ENTRY(\op\()_safe_regs) | |||
45 | 45 | ||
46 | _ASM_EXTABLE(1b, 3b) | 46 | _ASM_EXTABLE(1b, 3b) |
47 | CFI_ENDPROC | 47 | CFI_ENDPROC |
48 | ENDPROC(\op\()_safe_regs) | 48 | ENDPROC(native_\op\()_safe_regs) |
49 | .endm | 49 | .endm |
50 | 50 | ||
51 | #else /* X86_32 */ | 51 | #else /* X86_32 */ |
52 | 52 | ||
53 | .macro op_safe_regs op | 53 | .macro op_safe_regs op |
54 | ENTRY(\op\()_safe_regs) | 54 | ENTRY(native_\op\()_safe_regs) |
55 | CFI_STARTPROC | 55 | CFI_STARTPROC |
56 | pushl_cfi %ebx | 56 | pushl_cfi %ebx |
57 | pushl_cfi %ebp | 57 | pushl_cfi %ebp |
@@ -92,7 +92,7 @@ ENTRY(\op\()_safe_regs) | |||
92 | 92 | ||
93 | _ASM_EXTABLE(1b, 3b) | 93 | _ASM_EXTABLE(1b, 3b) |
94 | CFI_ENDPROC | 94 | CFI_ENDPROC |
95 | ENDPROC(\op\()_safe_regs) | 95 | ENDPROC(native_\op\()_safe_regs) |
96 | .endm | 96 | .endm |
97 | 97 | ||
98 | #endif | 98 | #endif |
diff --git a/arch/x86/lib/putuser.S b/arch/x86/lib/putuser.S index fc6ba17a7ee..36b0d15ae6e 100644 --- a/arch/x86/lib/putuser.S +++ b/arch/x86/lib/putuser.S | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <asm/thread_info.h> | 15 | #include <asm/thread_info.h> |
16 | #include <asm/errno.h> | 16 | #include <asm/errno.h> |
17 | #include <asm/asm.h> | 17 | #include <asm/asm.h> |
18 | #include <asm/smap.h> | ||
19 | 18 | ||
20 | 19 | ||
21 | /* | 20 | /* |
@@ -32,8 +31,7 @@ | |||
32 | 31 | ||
33 | #define ENTER CFI_STARTPROC ; \ | 32 | #define ENTER CFI_STARTPROC ; \ |
34 | GET_THREAD_INFO(%_ASM_BX) | 33 | GET_THREAD_INFO(%_ASM_BX) |
35 | #define EXIT ASM_CLAC ; \ | 34 | #define EXIT ret ; \ |
36 | ret ; \ | ||
37 | CFI_ENDPROC | 35 | CFI_ENDPROC |
38 | 36 | ||
39 | .text | 37 | .text |
@@ -41,7 +39,6 @@ ENTRY(__put_user_1) | |||
41 | ENTER | 39 | ENTER |
42 | cmp TI_addr_limit(%_ASM_BX),%_ASM_CX | 40 | cmp TI_addr_limit(%_ASM_BX),%_ASM_CX |
43 | jae bad_put_user | 41 | jae bad_put_user |
44 | ASM_STAC | ||
45 | 1: movb %al,(%_ASM_CX) | 42 | 1: movb %al,(%_ASM_CX) |
46 | xor %eax,%eax | 43 | xor %eax,%eax |
47 | EXIT | 44 | EXIT |
@@ -53,7 +50,6 @@ ENTRY(__put_user_2) | |||
53 | sub $1,%_ASM_BX | 50 | sub $1,%_ASM_BX |
54 | cmp %_ASM_BX,%_ASM_CX | 51 | cmp %_ASM_BX,%_ASM_CX |
55 | jae bad_put_user | 52 | jae bad_put_user |
56 | ASM_STAC | ||
57 | 2: movw %ax,(%_ASM_CX) | 53 | 2: movw %ax,(%_ASM_CX) |
58 | xor %eax,%eax | 54 | xor %eax,%eax |
59 | EXIT | 55 | EXIT |
@@ -65,7 +61,6 @@ ENTRY(__put_user_4) | |||
65 | sub $3,%_ASM_BX | 61 | sub $3,%_ASM_BX |
66 | cmp %_ASM_BX,%_ASM_CX | 62 | cmp %_ASM_BX,%_ASM_CX |
67 | jae bad_put_user | 63 | jae bad_put_user |
68 | ASM_STAC | ||
69 | 3: movl %eax,(%_ASM_CX) | 64 | 3: movl %eax,(%_ASM_CX) |
70 | xor %eax,%eax | 65 | xor %eax,%eax |
71 | EXIT | 66 | EXIT |
@@ -77,7 +72,6 @@ ENTRY(__put_user_8) | |||
77 | sub $7,%_ASM_BX | 72 | sub $7,%_ASM_BX |
78 | cmp %_ASM_BX,%_ASM_CX | 73 | cmp %_ASM_BX,%_ASM_CX |
79 | jae bad_put_user | 74 | jae bad_put_user |
80 | ASM_STAC | ||
81 | 4: mov %_ASM_AX,(%_ASM_CX) | 75 | 4: mov %_ASM_AX,(%_ASM_CX) |
82 | #ifdef CONFIG_X86_32 | 76 | #ifdef CONFIG_X86_32 |
83 | 5: movl %edx,4(%_ASM_CX) | 77 | 5: movl %edx,4(%_ASM_CX) |
@@ -92,10 +86,12 @@ bad_put_user: | |||
92 | EXIT | 86 | EXIT |
93 | END(bad_put_user) | 87 | END(bad_put_user) |
94 | 88 | ||
95 | _ASM_EXTABLE(1b,bad_put_user) | 89 | .section __ex_table,"a" |
96 | _ASM_EXTABLE(2b,bad_put_user) | 90 | _ASM_PTR 1b,bad_put_user |
97 | _ASM_EXTABLE(3b,bad_put_user) | 91 | _ASM_PTR 2b,bad_put_user |
98 | _ASM_EXTABLE(4b,bad_put_user) | 92 | _ASM_PTR 3b,bad_put_user |
93 | _ASM_PTR 4b,bad_put_user | ||
99 | #ifdef CONFIG_X86_32 | 94 | #ifdef CONFIG_X86_32 |
100 | _ASM_EXTABLE(5b,bad_put_user) | 95 | _ASM_PTR 5b,bad_put_user |
101 | #endif | 96 | #endif |
97 | .previous | ||
diff --git a/arch/x86/lib/string_32.c b/arch/x86/lib/string_32.c index bd59090825d..82004d2bf05 100644 --- a/arch/x86/lib/string_32.c +++ b/arch/x86/lib/string_32.c | |||
@@ -164,13 +164,15 @@ EXPORT_SYMBOL(strchr); | |||
164 | size_t strlen(const char *s) | 164 | size_t strlen(const char *s) |
165 | { | 165 | { |
166 | int d0; | 166 | int d0; |
167 | size_t res; | 167 | int res; |
168 | asm volatile("repne\n\t" | 168 | asm volatile("repne\n\t" |
169 | "scasb" | 169 | "scasb\n\t" |
170 | "notl %0\n\t" | ||
171 | "decl %0" | ||
170 | : "=c" (res), "=&D" (d0) | 172 | : "=c" (res), "=&D" (d0) |
171 | : "1" (s), "a" (0), "0" (0xffffffffu) | 173 | : "1" (s), "a" (0), "0" (0xffffffffu) |
172 | : "memory"); | 174 | : "memory"); |
173 | return ~res - 1; | 175 | return res; |
174 | } | 176 | } |
175 | EXPORT_SYMBOL(strlen); | 177 | EXPORT_SYMBOL(strlen); |
176 | #endif | 178 | #endif |
diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c index 4f74d94c8d9..97be9cb5448 100644 --- a/arch/x86/lib/usercopy.c +++ b/arch/x86/lib/usercopy.c | |||
@@ -7,9 +7,6 @@ | |||
7 | #include <linux/highmem.h> | 7 | #include <linux/highmem.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | 9 | ||
10 | #include <asm/word-at-a-time.h> | ||
11 | #include <linux/sched.h> | ||
12 | |||
13 | /* | 10 | /* |
14 | * best effort, GUP based copy_from_user() that is NMI-safe | 11 | * best effort, GUP based copy_from_user() that is NMI-safe |
15 | */ | 12 | */ |
@@ -22,9 +19,6 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) | |||
22 | void *map; | 19 | void *map; |
23 | int ret; | 20 | int ret; |
24 | 21 | ||
25 | if (__range_not_ok(from, n, TASK_SIZE)) | ||
26 | return len; | ||
27 | |||
28 | do { | 22 | do { |
29 | ret = __get_user_pages_fast(addr, 1, 0, &page); | 23 | ret = __get_user_pages_fast(addr, 1, 0, &page); |
30 | if (!ret) | 24 | if (!ret) |
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c index f0312d74640..e218d5df85f 100644 --- a/arch/x86/lib/usercopy_32.c +++ b/arch/x86/lib/usercopy_32.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
15 | #include <asm/mmx.h> | 15 | #include <asm/mmx.h> |
16 | #include <asm/asm.h> | ||
17 | 16 | ||
18 | #ifdef CONFIG_X86_INTEL_USERCOPY | 17 | #ifdef CONFIG_X86_INTEL_USERCOPY |
19 | /* | 18 | /* |
@@ -34,6 +33,93 @@ static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned lon | |||
34 | __movsl_is_ok((unsigned long)(a1), (unsigned long)(a2), (n)) | 33 | __movsl_is_ok((unsigned long)(a1), (unsigned long)(a2), (n)) |
35 | 34 | ||
36 | /* | 35 | /* |
36 | * Copy a null terminated string from userspace. | ||
37 | */ | ||
38 | |||
39 | #define __do_strncpy_from_user(dst, src, count, res) \ | ||
40 | do { \ | ||
41 | int __d0, __d1, __d2; \ | ||
42 | might_fault(); \ | ||
43 | __asm__ __volatile__( \ | ||
44 | " testl %1,%1\n" \ | ||
45 | " jz 2f\n" \ | ||
46 | "0: lodsb\n" \ | ||
47 | " stosb\n" \ | ||
48 | " testb %%al,%%al\n" \ | ||
49 | " jz 1f\n" \ | ||
50 | " decl %1\n" \ | ||
51 | " jnz 0b\n" \ | ||
52 | "1: subl %1,%0\n" \ | ||
53 | "2:\n" \ | ||
54 | ".section .fixup,\"ax\"\n" \ | ||
55 | "3: movl %5,%0\n" \ | ||
56 | " jmp 2b\n" \ | ||
57 | ".previous\n" \ | ||
58 | _ASM_EXTABLE(0b,3b) \ | ||
59 | : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \ | ||
60 | "=&D" (__d2) \ | ||
61 | : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ | ||
62 | : "memory"); \ | ||
63 | } while (0) | ||
64 | |||
65 | /** | ||
66 | * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking. | ||
67 | * @dst: Destination address, in kernel space. This buffer must be at | ||
68 | * least @count bytes long. | ||
69 | * @src: Source address, in user space. | ||
70 | * @count: Maximum number of bytes to copy, including the trailing NUL. | ||
71 | * | ||
72 | * Copies a NUL-terminated string from userspace to kernel space. | ||
73 | * Caller must check the specified block with access_ok() before calling | ||
74 | * this function. | ||
75 | * | ||
76 | * On success, returns the length of the string (not including the trailing | ||
77 | * NUL). | ||
78 | * | ||
79 | * If access to userspace fails, returns -EFAULT (some data may have been | ||
80 | * copied). | ||
81 | * | ||
82 | * If @count is smaller than the length of the string, copies @count bytes | ||
83 | * and returns @count. | ||
84 | */ | ||
85 | long | ||
86 | __strncpy_from_user(char *dst, const char __user *src, long count) | ||
87 | { | ||
88 | long res; | ||
89 | __do_strncpy_from_user(dst, src, count, res); | ||
90 | return res; | ||
91 | } | ||
92 | EXPORT_SYMBOL(__strncpy_from_user); | ||
93 | |||
94 | /** | ||
95 | * strncpy_from_user: - Copy a NUL terminated string from userspace. | ||
96 | * @dst: Destination address, in kernel space. This buffer must be at | ||
97 | * least @count bytes long. | ||
98 | * @src: Source address, in user space. | ||
99 | * @count: Maximum number of bytes to copy, including the trailing NUL. | ||
100 | * | ||
101 | * Copies a NUL-terminated string from userspace to kernel space. | ||
102 | * | ||
103 | * On success, returns the length of the string (not including the trailing | ||
104 | * NUL). | ||
105 | * | ||
106 | * If access to userspace fails, returns -EFAULT (some data may have been | ||
107 | * copied). | ||
108 | * | ||
109 | * If @count is smaller than the length of the string, copies @count bytes | ||
110 | * and returns @count. | ||
111 | */ | ||
112 | long | ||
113 | strncpy_from_user(char *dst, const char __user *src, long count) | ||
114 | { | ||
115 | long res = -EFAULT; | ||
116 | if (access_ok(VERIFY_READ, src, 1)) | ||
117 | __do_strncpy_from_user(dst, src, count, res); | ||
118 | return res; | ||
119 | } | ||
120 | EXPORT_SYMBOL(strncpy_from_user); | ||
121 | |||
122 | /* | ||
37 | * Zero Userspace | 123 | * Zero Userspace |
38 | */ | 124 | */ |
39 | 125 | ||
@@ -42,11 +128,10 @@ do { \ | |||
42 | int __d0; \ | 128 | int __d0; \ |
43 | might_fault(); \ | 129 | might_fault(); \ |
44 | __asm__ __volatile__( \ | 130 | __asm__ __volatile__( \ |
45 | ASM_STAC "\n" \ | ||
46 | "0: rep; stosl\n" \ | 131 | "0: rep; stosl\n" \ |
47 | " movl %2,%0\n" \ | 132 | " movl %2,%0\n" \ |
48 | "1: rep; stosb\n" \ | 133 | "1: rep; stosb\n" \ |
49 | "2: " ASM_CLAC "\n" \ | 134 | "2:\n" \ |
50 | ".section .fixup,\"ax\"\n" \ | 135 | ".section .fixup,\"ax\"\n" \ |
51 | "3: lea 0(%2,%0,4),%0\n" \ | 136 | "3: lea 0(%2,%0,4),%0\n" \ |
52 | " jmp 2b\n" \ | 137 | " jmp 2b\n" \ |
@@ -96,6 +181,50 @@ __clear_user(void __user *to, unsigned long n) | |||
96 | } | 181 | } |
97 | EXPORT_SYMBOL(__clear_user); | 182 | EXPORT_SYMBOL(__clear_user); |
98 | 183 | ||
184 | /** | ||
185 | * strnlen_user: - Get the size of a string in user space. | ||
186 | * @s: The string to measure. | ||
187 | * @n: The maximum valid length | ||
188 | * | ||
189 | * Get the size of a NUL-terminated string in user space. | ||
190 | * | ||
191 | * Returns the size of the string INCLUDING the terminating NUL. | ||
192 | * On exception, returns 0. | ||
193 | * If the string is too long, returns a value greater than @n. | ||
194 | */ | ||
195 | long strnlen_user(const char __user *s, long n) | ||
196 | { | ||
197 | unsigned long mask = -__addr_ok(s); | ||
198 | unsigned long res, tmp; | ||
199 | |||
200 | might_fault(); | ||
201 | |||
202 | __asm__ __volatile__( | ||
203 | " testl %0, %0\n" | ||
204 | " jz 3f\n" | ||
205 | " andl %0,%%ecx\n" | ||
206 | "0: repne; scasb\n" | ||
207 | " setne %%al\n" | ||
208 | " subl %%ecx,%0\n" | ||
209 | " addl %0,%%eax\n" | ||
210 | "1:\n" | ||
211 | ".section .fixup,\"ax\"\n" | ||
212 | "2: xorl %%eax,%%eax\n" | ||
213 | " jmp 1b\n" | ||
214 | "3: movb $1,%%al\n" | ||
215 | " jmp 1b\n" | ||
216 | ".previous\n" | ||
217 | ".section __ex_table,\"a\"\n" | ||
218 | " .align 4\n" | ||
219 | " .long 0b,2b\n" | ||
220 | ".previous" | ||
221 | :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp) | ||
222 | :"0" (n), "1" (s), "2" (0), "3" (mask) | ||
223 | :"cc"); | ||
224 | return res & mask; | ||
225 | } | ||
226 | EXPORT_SYMBOL(strnlen_user); | ||
227 | |||
99 | #ifdef CONFIG_X86_INTEL_USERCOPY | 228 | #ifdef CONFIG_X86_INTEL_USERCOPY |
100 | static unsigned long | 229 | static unsigned long |
101 | __copy_user_intel(void __user *to, const void *from, unsigned long size) | 230 | __copy_user_intel(void __user *to, const void *from, unsigned long size) |
@@ -157,44 +286,47 @@ __copy_user_intel(void __user *to, const void *from, unsigned long size) | |||
157 | "101: lea 0(%%eax,%0,4),%0\n" | 286 | "101: lea 0(%%eax,%0,4),%0\n" |
158 | " jmp 100b\n" | 287 | " jmp 100b\n" |
159 | ".previous\n" | 288 | ".previous\n" |
160 | _ASM_EXTABLE(1b,100b) | 289 | ".section __ex_table,\"a\"\n" |
161 | _ASM_EXTABLE(2b,100b) | 290 | " .align 4\n" |
162 | _ASM_EXTABLE(3b,100b) | 291 | " .long 1b,100b\n" |
163 | _ASM_EXTABLE(4b,100b) | 292 | " .long 2b,100b\n" |
164 | _ASM_EXTABLE(5b,100b) | 293 | " .long 3b,100b\n" |
165 | _ASM_EXTABLE(6b,100b) | 294 | " .long 4b,100b\n" |
166 | _ASM_EXTABLE(7b,100b) | 295 | " .long 5b,100b\n" |
167 | _ASM_EXTABLE(8b,100b) | 296 | " .long 6b,100b\n" |
168 | _ASM_EXTABLE(9b,100b) | 297 | " .long 7b,100b\n" |
169 | _ASM_EXTABLE(10b,100b) | 298 | " .long 8b,100b\n" |
170 | _ASM_EXTABLE(11b,100b) | 299 | " .long 9b,100b\n" |
171 | _ASM_EXTABLE(12b,100b) | 300 | " .long 10b,100b\n" |
172 | _ASM_EXTABLE(13b,100b) | 301 | " .long 11b,100b\n" |
173 | _ASM_EXTABLE(14b,100b) | 302 | " .long 12b,100b\n" |
174 | _ASM_EXTABLE(15b,100b) | 303 | " .long 13b,100b\n" |
175 | _ASM_EXTABLE(16b,100b) | 304 | " .long 14b,100b\n" |
176 | _ASM_EXTABLE(17b,100b) | 305 | " .long 15b,100b\n" |
177 | _ASM_EXTABLE(18b,100b) | 306 | " .long 16b,100b\n" |
178 | _ASM_EXTABLE(19b,100b) | 307 | " .long 17b,100b\n" |
179 | _ASM_EXTABLE(20b,100b) | 308 | " .long 18b,100b\n" |
180 | _ASM_EXTABLE(21b,100b) | 309 | " .long 19b,100b\n" |
181 | _ASM_EXTABLE(22b,100b) | 310 | " .long 20b,100b\n" |
182 | _ASM_EXTABLE(23b,100b) | 311 | " .long 21b,100b\n" |
183 | _ASM_EXTABLE(24b,100b) | 312 | " .long 22b,100b\n" |
184 | _ASM_EXTABLE(25b,100b) | 313 | " .long 23b,100b\n" |
185 | _ASM_EXTABLE(26b,100b) | 314 | " .long 24b,100b\n" |
186 | _ASM_EXTABLE(27b,100b) | 315 | " .long 25b,100b\n" |
187 | _ASM_EXTABLE(28b,100b) | 316 | " .long 26b,100b\n" |
188 | _ASM_EXTABLE(29b,100b) | 317 | " .long 27b,100b\n" |
189 | _ASM_EXTABLE(30b,100b) | 318 | " .long 28b,100b\n" |
190 | _ASM_EXTABLE(31b,100b) | 319 | " .long 29b,100b\n" |
191 | _ASM_EXTABLE(32b,100b) | 320 | " .long 30b,100b\n" |
192 | _ASM_EXTABLE(33b,100b) | 321 | " .long 31b,100b\n" |
193 | _ASM_EXTABLE(34b,100b) | 322 | " .long 32b,100b\n" |
194 | _ASM_EXTABLE(35b,100b) | 323 | " .long 33b,100b\n" |
195 | _ASM_EXTABLE(36b,100b) | 324 | " .long 34b,100b\n" |
196 | _ASM_EXTABLE(37b,100b) | 325 | " .long 35b,100b\n" |
197 | _ASM_EXTABLE(99b,101b) | 326 | " .long 36b,100b\n" |
327 | " .long 37b,100b\n" | ||
328 | " .long 99b,101b\n" | ||
329 | ".previous" | ||
198 | : "=&c"(size), "=&D" (d0), "=&S" (d1) | 330 | : "=&c"(size), "=&D" (d0), "=&S" (d1) |
199 | : "1"(to), "2"(from), "0"(size) | 331 | : "1"(to), "2"(from), "0"(size) |
200 | : "eax", "edx", "memory"); | 332 | : "eax", "edx", "memory"); |
@@ -267,26 +399,29 @@ __copy_user_zeroing_intel(void *to, const void __user *from, unsigned long size) | |||
267 | " popl %0\n" | 399 | " popl %0\n" |
268 | " jmp 8b\n" | 400 | " jmp 8b\n" |
269 | ".previous\n" | 401 | ".previous\n" |
270 | _ASM_EXTABLE(0b,16b) | 402 | ".section __ex_table,\"a\"\n" |
271 | _ASM_EXTABLE(1b,16b) | 403 | " .align 4\n" |
272 | _ASM_EXTABLE(2b,16b) | 404 | " .long 0b,16b\n" |
273 | _ASM_EXTABLE(21b,16b) | 405 | " .long 1b,16b\n" |
274 | _ASM_EXTABLE(3b,16b) | 406 | " .long 2b,16b\n" |
275 | _ASM_EXTABLE(31b,16b) | 407 | " .long 21b,16b\n" |
276 | _ASM_EXTABLE(4b,16b) | 408 | " .long 3b,16b\n" |
277 | _ASM_EXTABLE(41b,16b) | 409 | " .long 31b,16b\n" |
278 | _ASM_EXTABLE(10b,16b) | 410 | " .long 4b,16b\n" |
279 | _ASM_EXTABLE(51b,16b) | 411 | " .long 41b,16b\n" |
280 | _ASM_EXTABLE(11b,16b) | 412 | " .long 10b,16b\n" |
281 | _ASM_EXTABLE(61b,16b) | 413 | " .long 51b,16b\n" |
282 | _ASM_EXTABLE(12b,16b) | 414 | " .long 11b,16b\n" |
283 | _ASM_EXTABLE(71b,16b) | 415 | " .long 61b,16b\n" |
284 | _ASM_EXTABLE(13b,16b) | 416 | " .long 12b,16b\n" |
285 | _ASM_EXTABLE(81b,16b) | 417 | " .long 71b,16b\n" |
286 | _ASM_EXTABLE(14b,16b) | 418 | " .long 13b,16b\n" |
287 | _ASM_EXTABLE(91b,16b) | 419 | " .long 81b,16b\n" |
288 | _ASM_EXTABLE(6b,9b) | 420 | " .long 14b,16b\n" |
289 | _ASM_EXTABLE(7b,16b) | 421 | " .long 91b,16b\n" |
422 | " .long 6b,9b\n" | ||
423 | " .long 7b,16b\n" | ||
424 | ".previous" | ||
290 | : "=&c"(size), "=&D" (d0), "=&S" (d1) | 425 | : "=&c"(size), "=&D" (d0), "=&S" (d1) |
291 | : "1"(to), "2"(from), "0"(size) | 426 | : "1"(to), "2"(from), "0"(size) |
292 | : "eax", "edx", "memory"); | 427 | : "eax", "edx", "memory"); |
@@ -366,26 +501,29 @@ static unsigned long __copy_user_zeroing_intel_nocache(void *to, | |||
366 | " popl %0\n" | 501 | " popl %0\n" |
367 | " jmp 8b\n" | 502 | " jmp 8b\n" |
368 | ".previous\n" | 503 | ".previous\n" |
369 | _ASM_EXTABLE(0b,16b) | 504 | ".section __ex_table,\"a\"\n" |
370 | _ASM_EXTABLE(1b,16b) | 505 | " .align 4\n" |
371 | _ASM_EXTABLE(2b,16b) | 506 | " .long 0b,16b\n" |
372 | _ASM_EXTABLE(21b,16b) | 507 | " .long 1b,16b\n" |
373 | _ASM_EXTABLE(3b,16b) | 508 | " .long 2b,16b\n" |
374 | _ASM_EXTABLE(31b,16b) | 509 | " .long 21b,16b\n" |
375 | _ASM_EXTABLE(4b,16b) | 510 | " .long 3b,16b\n" |
376 | _ASM_EXTABLE(41b,16b) | 511 | " .long 31b,16b\n" |
377 | _ASM_EXTABLE(10b,16b) | 512 | " .long 4b,16b\n" |
378 | _ASM_EXTABLE(51b,16b) | 513 | " .long 41b,16b\n" |
379 | _ASM_EXTABLE(11b,16b) | 514 | " .long 10b,16b\n" |
380 | _ASM_EXTABLE(61b,16b) | 515 | " .long 51b,16b\n" |
381 | _ASM_EXTABLE(12b,16b) | 516 | " .long 11b,16b\n" |
382 | _ASM_EXTABLE(71b,16b) | 517 | " .long 61b,16b\n" |
383 | _ASM_EXTABLE(13b,16b) | 518 | " .long 12b,16b\n" |
384 | _ASM_EXTABLE(81b,16b) | 519 | " .long 71b,16b\n" |
385 | _ASM_EXTABLE(14b,16b) | 520 | " .long 13b,16b\n" |
386 | _ASM_EXTABLE(91b,16b) | 521 | " .long 81b,16b\n" |
387 | _ASM_EXTABLE(6b,9b) | 522 | " .long 14b,16b\n" |
388 | _ASM_EXTABLE(7b,16b) | 523 | " .long 91b,16b\n" |
524 | " .long 6b,9b\n" | ||
525 | " .long 7b,16b\n" | ||
526 | ".previous" | ||
389 | : "=&c"(size), "=&D" (d0), "=&S" (d1) | 527 | : "=&c"(size), "=&D" (d0), "=&S" (d1) |
390 | : "1"(to), "2"(from), "0"(size) | 528 | : "1"(to), "2"(from), "0"(size) |
391 | : "eax", "edx", "memory"); | 529 | : "eax", "edx", "memory"); |
@@ -454,26 +592,29 @@ static unsigned long __copy_user_intel_nocache(void *to, | |||
454 | "9: lea 0(%%eax,%0,4),%0\n" | 592 | "9: lea 0(%%eax,%0,4),%0\n" |
455 | "16: jmp 8b\n" | 593 | "16: jmp 8b\n" |
456 | ".previous\n" | 594 | ".previous\n" |
457 | _ASM_EXTABLE(0b,16b) | 595 | ".section __ex_table,\"a\"\n" |
458 | _ASM_EXTABLE(1b,16b) | 596 | " .align 4\n" |
459 | _ASM_EXTABLE(2b,16b) | 597 | " .long 0b,16b\n" |
460 | _ASM_EXTABLE(21b,16b) | 598 | " .long 1b,16b\n" |
461 | _ASM_EXTABLE(3b,16b) | 599 | " .long 2b,16b\n" |
462 | _ASM_EXTABLE(31b,16b) | 600 | " .long 21b,16b\n" |
463 | _ASM_EXTABLE(4b,16b) | 601 | " .long 3b,16b\n" |
464 | _ASM_EXTABLE(41b,16b) | 602 | " .long 31b,16b\n" |
465 | _ASM_EXTABLE(10b,16b) | 603 | " .long 4b,16b\n" |
466 | _ASM_EXTABLE(51b,16b) | 604 | " .long 41b,16b\n" |
467 | _ASM_EXTABLE(11b,16b) | 605 | " .long 10b,16b\n" |
468 | _ASM_EXTABLE(61b,16b) | 606 | " .long 51b,16b\n" |
469 | _ASM_EXTABLE(12b,16b) | 607 | " .long 11b,16b\n" |
470 | _ASM_EXTABLE(71b,16b) | 608 | " .long 61b,16b\n" |
471 | _ASM_EXTABLE(13b,16b) | 609 | " .long 12b,16b\n" |
472 | _ASM_EXTABLE(81b,16b) | 610 | " .long 71b,16b\n" |
473 | _ASM_EXTABLE(14b,16b) | 611 | " .long 13b,16b\n" |
474 | _ASM_EXTABLE(91b,16b) | 612 | " .long 81b,16b\n" |
475 | _ASM_EXTABLE(6b,9b) | 613 | " .long 14b,16b\n" |
476 | _ASM_EXTABLE(7b,16b) | 614 | " .long 91b,16b\n" |
615 | " .long 6b,9b\n" | ||
616 | " .long 7b,16b\n" | ||
617 | ".previous" | ||
477 | : "=&c"(size), "=&D" (d0), "=&S" (d1) | 618 | : "=&c"(size), "=&D" (d0), "=&S" (d1) |
478 | : "1"(to), "2"(from), "0"(size) | 619 | : "1"(to), "2"(from), "0"(size) |
479 | : "eax", "edx", "memory"); | 620 | : "eax", "edx", "memory"); |
@@ -520,9 +661,12 @@ do { \ | |||
520 | "3: lea 0(%3,%0,4),%0\n" \ | 661 | "3: lea 0(%3,%0,4),%0\n" \ |
521 | " jmp 2b\n" \ | 662 | " jmp 2b\n" \ |
522 | ".previous\n" \ | 663 | ".previous\n" \ |
523 | _ASM_EXTABLE(4b,5b) \ | 664 | ".section __ex_table,\"a\"\n" \ |
524 | _ASM_EXTABLE(0b,3b) \ | 665 | " .align 4\n" \ |
525 | _ASM_EXTABLE(1b,2b) \ | 666 | " .long 4b,5b\n" \ |
667 | " .long 0b,3b\n" \ | ||
668 | " .long 1b,2b\n" \ | ||
669 | ".previous" \ | ||
526 | : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ | 670 | : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ |
527 | : "3"(size), "0"(size), "1"(to), "2"(from) \ | 671 | : "3"(size), "0"(size), "1"(to), "2"(from) \ |
528 | : "memory"); \ | 672 | : "memory"); \ |
@@ -559,9 +703,12 @@ do { \ | |||
559 | " popl %0\n" \ | 703 | " popl %0\n" \ |
560 | " jmp 2b\n" \ | 704 | " jmp 2b\n" \ |
561 | ".previous\n" \ | 705 | ".previous\n" \ |
562 | _ASM_EXTABLE(4b,5b) \ | 706 | ".section __ex_table,\"a\"\n" \ |
563 | _ASM_EXTABLE(0b,3b) \ | 707 | " .align 4\n" \ |
564 | _ASM_EXTABLE(1b,6b) \ | 708 | " .long 4b,5b\n" \ |
709 | " .long 0b,3b\n" \ | ||
710 | " .long 1b,6b\n" \ | ||
711 | ".previous" \ | ||
565 | : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ | 712 | : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ |
566 | : "3"(size), "0"(size), "1"(to), "2"(from) \ | 713 | : "3"(size), "0"(size), "1"(to), "2"(from) \ |
567 | : "memory"); \ | 714 | : "memory"); \ |
@@ -570,12 +717,67 @@ do { \ | |||
570 | unsigned long __copy_to_user_ll(void __user *to, const void *from, | 717 | unsigned long __copy_to_user_ll(void __user *to, const void *from, |
571 | unsigned long n) | 718 | unsigned long n) |
572 | { | 719 | { |
573 | stac(); | 720 | #ifndef CONFIG_X86_WP_WORKS_OK |
721 | if (unlikely(boot_cpu_data.wp_works_ok == 0) && | ||
722 | ((unsigned long)to) < TASK_SIZE) { | ||
723 | /* | ||
724 | * When we are in an atomic section (see | ||
725 | * mm/filemap.c:file_read_actor), return the full | ||
726 | * length to take the slow path. | ||
727 | */ | ||
728 | if (in_atomic()) | ||
729 | return n; | ||
730 | |||
731 | /* | ||
732 | * CPU does not honor the WP bit when writing | ||
733 | * from supervisory mode, and due to preemption or SMP, | ||
734 | * the page tables can change at any time. | ||
735 | * Do it manually. Manfred <manfred@colorfullife.com> | ||
736 | */ | ||
737 | while (n) { | ||
738 | unsigned long offset = ((unsigned long)to)%PAGE_SIZE; | ||
739 | unsigned long len = PAGE_SIZE - offset; | ||
740 | int retval; | ||
741 | struct page *pg; | ||
742 | void *maddr; | ||
743 | |||
744 | if (len > n) | ||
745 | len = n; | ||
746 | |||
747 | survive: | ||
748 | down_read(¤t->mm->mmap_sem); | ||
749 | retval = get_user_pages(current, current->mm, | ||
750 | (unsigned long)to, 1, 1, 0, &pg, NULL); | ||
751 | |||
752 | if (retval == -ENOMEM && is_global_init(current)) { | ||
753 | up_read(¤t->mm->mmap_sem); | ||
754 | congestion_wait(BLK_RW_ASYNC, HZ/50); | ||
755 | goto survive; | ||
756 | } | ||
757 | |||
758 | if (retval != 1) { | ||
759 | up_read(¤t->mm->mmap_sem); | ||
760 | break; | ||
761 | } | ||
762 | |||
763 | maddr = kmap_atomic(pg, KM_USER0); | ||
764 | memcpy(maddr + offset, from, len); | ||
765 | kunmap_atomic(maddr, KM_USER0); | ||
766 | set_page_dirty_lock(pg); | ||
767 | put_page(pg); | ||
768 | up_read(¤t->mm->mmap_sem); | ||
769 | |||
770 | from += len; | ||
771 | to += len; | ||
772 | n -= len; | ||
773 | } | ||
774 | return n; | ||
775 | } | ||
776 | #endif | ||
574 | if (movsl_is_ok(to, from, n)) | 777 | if (movsl_is_ok(to, from, n)) |
575 | __copy_user(to, from, n); | 778 | __copy_user(to, from, n); |
576 | else | 779 | else |
577 | n = __copy_user_intel(to, from, n); | 780 | n = __copy_user_intel(to, from, n); |
578 | clac(); | ||
579 | return n; | 781 | return n; |
580 | } | 782 | } |
581 | EXPORT_SYMBOL(__copy_to_user_ll); | 783 | EXPORT_SYMBOL(__copy_to_user_ll); |
@@ -583,12 +785,10 @@ EXPORT_SYMBOL(__copy_to_user_ll); | |||
583 | unsigned long __copy_from_user_ll(void *to, const void __user *from, | 785 | unsigned long __copy_from_user_ll(void *to, const void __user *from, |
584 | unsigned long n) | 786 | unsigned long n) |
585 | { | 787 | { |
586 | stac(); | ||
587 | if (movsl_is_ok(to, from, n)) | 788 | if (movsl_is_ok(to, from, n)) |
588 | __copy_user_zeroing(to, from, n); | 789 | __copy_user_zeroing(to, from, n); |
589 | else | 790 | else |
590 | n = __copy_user_zeroing_intel(to, from, n); | 791 | n = __copy_user_zeroing_intel(to, from, n); |
591 | clac(); | ||
592 | return n; | 792 | return n; |
593 | } | 793 | } |
594 | EXPORT_SYMBOL(__copy_from_user_ll); | 794 | EXPORT_SYMBOL(__copy_from_user_ll); |
@@ -596,13 +796,11 @@ EXPORT_SYMBOL(__copy_from_user_ll); | |||
596 | unsigned long __copy_from_user_ll_nozero(void *to, const void __user *from, | 796 | unsigned long __copy_from_user_ll_nozero(void *to, const void __user *from, |
597 | unsigned long n) | 797 | unsigned long n) |
598 | { | 798 | { |
599 | stac(); | ||
600 | if (movsl_is_ok(to, from, n)) | 799 | if (movsl_is_ok(to, from, n)) |
601 | __copy_user(to, from, n); | 800 | __copy_user(to, from, n); |
602 | else | 801 | else |
603 | n = __copy_user_intel((void __user *)to, | 802 | n = __copy_user_intel((void __user *)to, |
604 | (const void *)from, n); | 803 | (const void *)from, n); |
605 | clac(); | ||
606 | return n; | 804 | return n; |
607 | } | 805 | } |
608 | EXPORT_SYMBOL(__copy_from_user_ll_nozero); | 806 | EXPORT_SYMBOL(__copy_from_user_ll_nozero); |
@@ -610,7 +808,6 @@ EXPORT_SYMBOL(__copy_from_user_ll_nozero); | |||
610 | unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, | 808 | unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, |
611 | unsigned long n) | 809 | unsigned long n) |
612 | { | 810 | { |
613 | stac(); | ||
614 | #ifdef CONFIG_X86_INTEL_USERCOPY | 811 | #ifdef CONFIG_X86_INTEL_USERCOPY |
615 | if (n > 64 && cpu_has_xmm2) | 812 | if (n > 64 && cpu_has_xmm2) |
616 | n = __copy_user_zeroing_intel_nocache(to, from, n); | 813 | n = __copy_user_zeroing_intel_nocache(to, from, n); |
@@ -619,7 +816,6 @@ unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, | |||
619 | #else | 816 | #else |
620 | __copy_user_zeroing(to, from, n); | 817 | __copy_user_zeroing(to, from, n); |
621 | #endif | 818 | #endif |
622 | clac(); | ||
623 | return n; | 819 | return n; |
624 | } | 820 | } |
625 | EXPORT_SYMBOL(__copy_from_user_ll_nocache); | 821 | EXPORT_SYMBOL(__copy_from_user_ll_nocache); |
@@ -627,7 +823,6 @@ EXPORT_SYMBOL(__copy_from_user_ll_nocache); | |||
627 | unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from, | 823 | unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from, |
628 | unsigned long n) | 824 | unsigned long n) |
629 | { | 825 | { |
630 | stac(); | ||
631 | #ifdef CONFIG_X86_INTEL_USERCOPY | 826 | #ifdef CONFIG_X86_INTEL_USERCOPY |
632 | if (n > 64 && cpu_has_xmm2) | 827 | if (n > 64 && cpu_has_xmm2) |
633 | n = __copy_user_intel_nocache(to, from, n); | 828 | n = __copy_user_intel_nocache(to, from, n); |
@@ -636,7 +831,6 @@ unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *fr | |||
636 | #else | 831 | #else |
637 | __copy_user(to, from, n); | 832 | __copy_user(to, from, n); |
638 | #endif | 833 | #endif |
639 | clac(); | ||
640 | return n; | 834 | return n; |
641 | } | 835 | } |
642 | EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero); | 836 | EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero); |
diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index 05928aae911..b7c2849ffb6 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c | |||
@@ -9,6 +9,55 @@ | |||
9 | #include <asm/uaccess.h> | 9 | #include <asm/uaccess.h> |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * Copy a null terminated string from userspace. | ||
13 | */ | ||
14 | |||
15 | #define __do_strncpy_from_user(dst,src,count,res) \ | ||
16 | do { \ | ||
17 | long __d0, __d1, __d2; \ | ||
18 | might_fault(); \ | ||
19 | __asm__ __volatile__( \ | ||
20 | " testq %1,%1\n" \ | ||
21 | " jz 2f\n" \ | ||
22 | "0: lodsb\n" \ | ||
23 | " stosb\n" \ | ||
24 | " testb %%al,%%al\n" \ | ||
25 | " jz 1f\n" \ | ||
26 | " decq %1\n" \ | ||
27 | " jnz 0b\n" \ | ||
28 | "1: subq %1,%0\n" \ | ||
29 | "2:\n" \ | ||
30 | ".section .fixup,\"ax\"\n" \ | ||
31 | "3: movq %5,%0\n" \ | ||
32 | " jmp 2b\n" \ | ||
33 | ".previous\n" \ | ||
34 | _ASM_EXTABLE(0b,3b) \ | ||
35 | : "=&r"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \ | ||
36 | "=&D" (__d2) \ | ||
37 | : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ | ||
38 | : "memory"); \ | ||
39 | } while (0) | ||
40 | |||
41 | long | ||
42 | __strncpy_from_user(char *dst, const char __user *src, long count) | ||
43 | { | ||
44 | long res; | ||
45 | __do_strncpy_from_user(dst, src, count, res); | ||
46 | return res; | ||
47 | } | ||
48 | EXPORT_SYMBOL(__strncpy_from_user); | ||
49 | |||
50 | long | ||
51 | strncpy_from_user(char *dst, const char __user *src, long count) | ||
52 | { | ||
53 | long res = -EFAULT; | ||
54 | if (access_ok(VERIFY_READ, src, 1)) | ||
55 | return __strncpy_from_user(dst, src, count); | ||
56 | return res; | ||
57 | } | ||
58 | EXPORT_SYMBOL(strncpy_from_user); | ||
59 | |||
60 | /* | ||
12 | * Zero Userspace | 61 | * Zero Userspace |
13 | */ | 62 | */ |
14 | 63 | ||
@@ -18,7 +67,6 @@ unsigned long __clear_user(void __user *addr, unsigned long size) | |||
18 | might_fault(); | 67 | might_fault(); |
19 | /* no memory constraint because it doesn't change any memory gcc knows | 68 | /* no memory constraint because it doesn't change any memory gcc knows |
20 | about */ | 69 | about */ |
21 | stac(); | ||
22 | asm volatile( | 70 | asm volatile( |
23 | " testq %[size8],%[size8]\n" | 71 | " testq %[size8],%[size8]\n" |
24 | " jz 4f\n" | 72 | " jz 4f\n" |
@@ -41,7 +89,6 @@ unsigned long __clear_user(void __user *addr, unsigned long size) | |||
41 | : [size8] "=&c"(size), [dst] "=&D" (__d0) | 89 | : [size8] "=&c"(size), [dst] "=&D" (__d0) |
42 | : [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr), | 90 | : [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr), |
43 | [zero] "r" (0UL), [eight] "r" (8UL)); | 91 | [zero] "r" (0UL), [eight] "r" (8UL)); |
44 | clac(); | ||
45 | return size; | 92 | return size; |
46 | } | 93 | } |
47 | EXPORT_SYMBOL(__clear_user); | 94 | EXPORT_SYMBOL(__clear_user); |
@@ -54,6 +101,54 @@ unsigned long clear_user(void __user *to, unsigned long n) | |||
54 | } | 101 | } |
55 | EXPORT_SYMBOL(clear_user); | 102 | EXPORT_SYMBOL(clear_user); |
56 | 103 | ||
104 | /* | ||
105 | * Return the size of a string (including the ending 0) | ||
106 | * | ||
107 | * Return 0 on exception, a value greater than N if too long | ||
108 | */ | ||
109 | |||
110 | long __strnlen_user(const char __user *s, long n) | ||
111 | { | ||
112 | long res = 0; | ||
113 | char c; | ||
114 | |||
115 | while (1) { | ||
116 | if (res>n) | ||
117 | return n+1; | ||
118 | if (__get_user(c, s)) | ||
119 | return 0; | ||
120 | if (!c) | ||
121 | return res+1; | ||
122 | res++; | ||
123 | s++; | ||
124 | } | ||
125 | } | ||
126 | EXPORT_SYMBOL(__strnlen_user); | ||
127 | |||
128 | long strnlen_user(const char __user *s, long n) | ||
129 | { | ||
130 | if (!access_ok(VERIFY_READ, s, 1)) | ||
131 | return 0; | ||
132 | return __strnlen_user(s, n); | ||
133 | } | ||
134 | EXPORT_SYMBOL(strnlen_user); | ||
135 | |||
136 | long strlen_user(const char __user *s) | ||
137 | { | ||
138 | long res = 0; | ||
139 | char c; | ||
140 | |||
141 | for (;;) { | ||
142 | if (get_user(c, s)) | ||
143 | return 0; | ||
144 | if (!c) | ||
145 | return res+1; | ||
146 | res++; | ||
147 | s++; | ||
148 | } | ||
149 | } | ||
150 | EXPORT_SYMBOL(strlen_user); | ||
151 | |||
57 | unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len) | 152 | unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len) |
58 | { | 153 | { |
59 | if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { | 154 | if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { |
@@ -84,6 +179,5 @@ copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest) | |||
84 | for (c = 0, zero_len = len; zerorest && zero_len; --zero_len) | 179 | for (c = 0, zero_len = len; zerorest && zero_len; --zero_len) |
85 | if (__put_user_nocheck(c, to++, sizeof(char))) | 180 | if (__put_user_nocheck(c, to++, sizeof(char))) |
86 | break; | 181 | break; |
87 | clac(); | ||
88 | return len; | 182 | return len; |
89 | } | 183 | } |
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt index 5d7e51f3fd2..a793da5e560 100644 --- a/arch/x86/lib/x86-opcode-map.txt +++ b/arch/x86/lib/x86-opcode-map.txt | |||
@@ -1,11 +1,5 @@ | |||
1 | # x86 Opcode Maps | 1 | # x86 Opcode Maps |
2 | # | 2 | # |
3 | # This is (mostly) based on following documentations. | ||
4 | # - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2 | ||
5 | # (#325383-040US, October 2011) | ||
6 | # - Intel(R) Advanced Vector Extensions Programming Reference | ||
7 | # (#319433-011,JUNE 2011). | ||
8 | # | ||
9 | #<Opcode maps> | 3 | #<Opcode maps> |
10 | # Table: table-name | 4 | # Table: table-name |
11 | # Referrer: escaped-name | 5 | # Referrer: escaped-name |
@@ -21,14 +15,11 @@ | |||
21 | # EndTable | 15 | # EndTable |
22 | # | 16 | # |
23 | # AVX Superscripts | 17 | # AVX Superscripts |
24 | # (v): this opcode requires VEX prefix. | 18 | # (VEX): this opcode can accept VEX prefix. |
25 | # (v1): this opcode only supports 128bit VEX. | 19 | # (oVEX): this opcode requires VEX prefix. |
20 | # (o128): this opcode only supports 128bit VEX. | ||
21 | # (o256): this opcode only supports 256bit VEX. | ||
26 | # | 22 | # |
27 | # Last Prefix Superscripts | ||
28 | # - (66): the last prefix is 0x66 | ||
29 | # - (F3): the last prefix is 0xF3 | ||
30 | # - (F2): the last prefix is 0xF2 | ||
31 | # - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) | ||
32 | 23 | ||
33 | Table: one byte opcode | 24 | Table: one byte opcode |
34 | Referrer: | 25 | Referrer: |
@@ -208,8 +199,8 @@ a0: MOV AL,Ob | |||
208 | a1: MOV rAX,Ov | 199 | a1: MOV rAX,Ov |
209 | a2: MOV Ob,AL | 200 | a2: MOV Ob,AL |
210 | a3: MOV Ov,rAX | 201 | a3: MOV Ov,rAX |
211 | a4: MOVS/B Yb,Xb | 202 | a4: MOVS/B Xb,Yb |
212 | a5: MOVS/W/D/Q Yv,Xv | 203 | a5: MOVS/W/D/Q Xv,Yv |
213 | a6: CMPS/B Xb,Yb | 204 | a6: CMPS/B Xb,Yb |
214 | a7: CMPS/W/D Xv,Yv | 205 | a7: CMPS/W/D Xv,Yv |
215 | a8: TEST AL,Ib | 206 | a8: TEST AL,Ib |
@@ -219,9 +210,7 @@ ab: STOS/W/D/Q Yv,rAX | |||
219 | ac: LODS/B AL,Xb | 210 | ac: LODS/B AL,Xb |
220 | ad: LODS/W/D/Q rAX,Xv | 211 | ad: LODS/W/D/Q rAX,Xv |
221 | ae: SCAS/B AL,Yb | 212 | ae: SCAS/B AL,Yb |
222 | # Note: The May 2011 Intel manual shows Xv for the second parameter of the | 213 | af: SCAS/W/D/Q rAX,Xv |
223 | # next instruction but Yv is correct | ||
224 | af: SCAS/W/D/Q rAX,Yv | ||
225 | # 0xb0 - 0xbf | 214 | # 0xb0 - 0xbf |
226 | b0: MOV AL/R8L,Ib | 215 | b0: MOV AL/R8L,Ib |
227 | b1: MOV CL/R9L,Ib | 216 | b1: MOV CL/R9L,Ib |
@@ -244,8 +233,8 @@ c0: Grp2 Eb,Ib (1A) | |||
244 | c1: Grp2 Ev,Ib (1A) | 233 | c1: Grp2 Ev,Ib (1A) |
245 | c2: RETN Iw (f64) | 234 | c2: RETN Iw (f64) |
246 | c3: RETN | 235 | c3: RETN |
247 | c4: LES Gz,Mp (i64) | VEX+2byte (Prefix) | 236 | c4: LES Gz,Mp (i64) | 3bytes-VEX (Prefix) |
248 | c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix) | 237 | c5: LDS Gz,Mp (i64) | 2bytes-VEX (Prefix) |
249 | c6: Grp11 Eb,Ib (1A) | 238 | c6: Grp11 Eb,Ib (1A) |
250 | c7: Grp11 Ev,Iz (1A) | 239 | c7: Grp11 Ev,Iz (1A) |
251 | c8: ENTER Iw,Ib | 240 | c8: ENTER Iw,Ib |
@@ -331,19 +320,14 @@ AVXcode: 1 | |||
331 | # 3DNow! uses the last imm byte as opcode extension. | 320 | # 3DNow! uses the last imm byte as opcode extension. |
332 | 0f: 3DNow! Pq,Qq,Ib | 321 | 0f: 3DNow! Pq,Qq,Ib |
333 | # 0x0f 0x10-0x1f | 322 | # 0x0f 0x10-0x1f |
334 | # NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands | 323 | 10: movups Vps,Wps (VEX) | movss Vss,Wss (F3),(VEX),(o128) | movupd Vpd,Wpd (66),(VEX) | movsd Vsd,Wsd (F2),(VEX),(o128) |
335 | # but it actually has operands. And also, vmovss and vmovsd only accept 128bit. | 324 | 11: movups Wps,Vps (VEX) | movss Wss,Vss (F3),(VEX),(o128) | movupd Wpd,Vpd (66),(VEX) | movsd Wsd,Vsd (F2),(VEX),(o128) |
336 | # MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form. | 325 | 12: movlps Vq,Mq (VEX),(o128) | movlpd Vq,Mq (66),(VEX),(o128) | movhlps Vq,Uq (VEX),(o128) | movddup Vq,Wq (F2),(VEX) | movsldup Vq,Wq (F3),(VEX) |
337 | # Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming | 326 | 13: mpvlps Mq,Vq (VEX),(o128) | movlpd Mq,Vq (66),(VEX),(o128) |
338 | # Reference A.1 | 327 | 14: unpcklps Vps,Wq (VEX) | unpcklpd Vpd,Wq (66),(VEX) |
339 | 10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1) | 328 | 15: unpckhps Vps,Wq (VEX) | unpckhpd Vpd,Wq (66),(VEX) |
340 | 11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1) | 329 | 16: movhps Vq,Mq (VEX),(o128) | movhpd Vq,Mq (66),(VEX),(o128) | movlsps Vq,Uq (VEX),(o128) | movshdup Vq,Wq (F3),(VEX) |
341 | 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) | 330 | 17: movhps Mq,Vq (VEX),(o128) | movhpd Mq,Vq (66),(VEX),(o128) |
342 | 13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1) | ||
343 | 14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66) | ||
344 | 15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66) | ||
345 | 16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3) | ||
346 | 17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1) | ||
347 | 18: Grp16 (1A) | 331 | 18: Grp16 (1A) |
348 | 19: | 332 | 19: |
349 | 1a: | 333 | 1a: |
@@ -361,14 +345,14 @@ AVXcode: 1 | |||
361 | 25: | 345 | 25: |
362 | 26: | 346 | 26: |
363 | 27: | 347 | 27: |
364 | 28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66) | 348 | 28: movaps Vps,Wps (VEX) | movapd Vpd,Wpd (66),(VEX) |
365 | 29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66) | 349 | 29: movaps Wps,Vps (VEX) | movapd Wpd,Vpd (66),(VEX) |
366 | 2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1) | 350 | 2a: cvtpi2ps Vps,Qpi | cvtsi2ss Vss,Ed/q (F3),(VEX),(o128) | cvtpi2pd Vpd,Qpi (66) | cvtsi2sd Vsd,Ed/q (F2),(VEX),(o128) |
367 | 2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66) | 351 | 2b: movntps Mps,Vps (VEX) | movntpd Mpd,Vpd (66),(VEX) |
368 | 2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1) | 352 | 2c: cvttps2pi Ppi,Wps | cvttss2si Gd/q,Wss (F3),(VEX),(o128) | cvttpd2pi Ppi,Wpd (66) | cvttsd2si Gd/q,Wsd (F2),(VEX),(o128) |
369 | 2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1) | 353 | 2d: cvtps2pi Ppi,Wps | cvtss2si Gd/q,Wss (F3),(VEX),(o128) | cvtpd2pi Qpi,Wpd (66) | cvtsd2si Gd/q,Wsd (F2),(VEX),(o128) |
370 | 2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1) | 354 | 2e: ucomiss Vss,Wss (VEX),(o128) | ucomisd Vsd,Wsd (66),(VEX),(o128) |
371 | 2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1) | 355 | 2f: comiss Vss,Wss (VEX),(o128) | comisd Vsd,Wsd (66),(VEX),(o128) |
372 | # 0x0f 0x30-0x3f | 356 | # 0x0f 0x30-0x3f |
373 | 30: WRMSR | 357 | 30: WRMSR |
374 | 31: RDTSC | 358 | 31: RDTSC |
@@ -404,66 +388,65 @@ AVXcode: 1 | |||
404 | 4e: CMOVLE/NG Gv,Ev | 388 | 4e: CMOVLE/NG Gv,Ev |
405 | 4f: CMOVNLE/G Gv,Ev | 389 | 4f: CMOVNLE/G Gv,Ev |
406 | # 0x0f 0x50-0x5f | 390 | # 0x0f 0x50-0x5f |
407 | 50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66) | 391 | 50: movmskps Gd/q,Ups (VEX) | movmskpd Gd/q,Upd (66),(VEX) |
408 | 51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1) | 392 | 51: sqrtps Vps,Wps (VEX) | sqrtss Vss,Wss (F3),(VEX),(o128) | sqrtpd Vpd,Wpd (66),(VEX) | sqrtsd Vsd,Wsd (F2),(VEX),(o128) |
409 | 52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1) | 393 | 52: rsqrtps Vps,Wps (VEX) | rsqrtss Vss,Wss (F3),(VEX),(o128) |
410 | 53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1) | 394 | 53: rcpps Vps,Wps (VEX) | rcpss Vss,Wss (F3),(VEX),(o128) |
411 | 54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66) | 395 | 54: andps Vps,Wps (VEX) | andpd Vpd,Wpd (66),(VEX) |
412 | 55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66) | 396 | 55: andnps Vps,Wps (VEX) | andnpd Vpd,Wpd (66),(VEX) |
413 | 56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66) | 397 | 56: orps Vps,Wps (VEX) | orpd Vpd,Wpd (66),(VEX) |
414 | 57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66) | 398 | 57: xorps Vps,Wps (VEX) | xorpd Vpd,Wpd (66),(VEX) |
415 | 58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1) | 399 | 58: addps Vps,Wps (VEX) | addss Vss,Wss (F3),(VEX),(o128) | addpd Vpd,Wpd (66),(VEX) | addsd Vsd,Wsd (F2),(VEX),(o128) |
416 | 59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1) | 400 | 59: mulps Vps,Wps (VEX) | mulss Vss,Wss (F3),(VEX),(o128) | mulpd Vpd,Wpd (66),(VEX) | mulsd Vsd,Wsd (F2),(VEX),(o128) |
417 | 5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1) | 401 | 5a: cvtps2pd Vpd,Wps (VEX) | cvtss2sd Vsd,Wss (F3),(VEX),(o128) | cvtpd2ps Vps,Wpd (66),(VEX) | cvtsd2ss Vsd,Wsd (F2),(VEX),(o128) |
418 | 5b: vcvtdq2ps Vps,Wdq | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3) | 402 | 5b: cvtdq2ps Vps,Wdq (VEX) | cvtps2dq Vdq,Wps (66),(VEX) | cvttps2dq Vdq,Wps (F3),(VEX) |
419 | 5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1) | 403 | 5c: subps Vps,Wps (VEX) | subss Vss,Wss (F3),(VEX),(o128) | subpd Vpd,Wpd (66),(VEX) | subsd Vsd,Wsd (F2),(VEX),(o128) |
420 | 5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1) | 404 | 5d: minps Vps,Wps (VEX) | minss Vss,Wss (F3),(VEX),(o128) | minpd Vpd,Wpd (66),(VEX) | minsd Vsd,Wsd (F2),(VEX),(o128) |
421 | 5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1) | 405 | 5e: divps Vps,Wps (VEX) | divss Vss,Wss (F3),(VEX),(o128) | divpd Vpd,Wpd (66),(VEX) | divsd Vsd,Wsd (F2),(VEX),(o128) |
422 | 5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1) | 406 | 5f: maxps Vps,Wps (VEX) | maxss Vss,Wss (F3),(VEX),(o128) | maxpd Vpd,Wpd (66),(VEX) | maxsd Vsd,Wsd (F2),(VEX),(o128) |
423 | # 0x0f 0x60-0x6f | 407 | # 0x0f 0x60-0x6f |
424 | 60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1) | 408 | 60: punpcklbw Pq,Qd | punpcklbw Vdq,Wdq (66),(VEX),(o128) |
425 | 61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1) | 409 | 61: punpcklwd Pq,Qd | punpcklwd Vdq,Wdq (66),(VEX),(o128) |
426 | 62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1) | 410 | 62: punpckldq Pq,Qd | punpckldq Vdq,Wdq (66),(VEX),(o128) |
427 | 63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1) | 411 | 63: packsswb Pq,Qq | packsswb Vdq,Wdq (66),(VEX),(o128) |
428 | 64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1) | 412 | 64: pcmpgtb Pq,Qq | pcmpgtb Vdq,Wdq (66),(VEX),(o128) |
429 | 65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1) | 413 | 65: pcmpgtw Pq,Qq | pcmpgtw Vdq,Wdq (66),(VEX),(o128) |
430 | 66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1) | 414 | 66: pcmpgtd Pq,Qq | pcmpgtd Vdq,Wdq (66),(VEX),(o128) |
431 | 67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1) | 415 | 67: packuswb Pq,Qq | packuswb Vdq,Wdq (66),(VEX),(o128) |
432 | 68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1) | 416 | 68: punpckhbw Pq,Qd | punpckhbw Vdq,Wdq (66),(VEX),(o128) |
433 | 69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1) | 417 | 69: punpckhwd Pq,Qd | punpckhwd Vdq,Wdq (66),(VEX),(o128) |
434 | 6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1) | 418 | 6a: punpckhdq Pq,Qd | punpckhdq Vdq,Wdq (66),(VEX),(o128) |
435 | 6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1) | 419 | 6b: packssdw Pq,Qd | packssdw Vdq,Wdq (66),(VEX),(o128) |
436 | 6c: vpunpcklqdq Vx,Hx,Wx (66),(v1) | 420 | 6c: punpcklqdq Vdq,Wdq (66),(VEX),(o128) |
437 | 6d: vpunpckhqdq Vx,Hx,Wx (66),(v1) | 421 | 6d: punpckhqdq Vdq,Wdq (66),(VEX),(o128) |
438 | 6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1) | 422 | 6e: movd/q/ Pd,Ed/q | movd/q Vdq,Ed/q (66),(VEX),(o128) |
439 | 6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqu Vx,Wx (F3) | 423 | 6f: movq Pq,Qq | movdqa Vdq,Wdq (66),(VEX) | movdqu Vdq,Wdq (F3),(VEX) |
440 | # 0x0f 0x70-0x7f | 424 | # 0x0f 0x70-0x7f |
441 | 70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1) | 425 | 70: pshufw Pq,Qq,Ib | pshufd Vdq,Wdq,Ib (66),(VEX),(o128) | pshufhw Vdq,Wdq,Ib (F3),(VEX),(o128) | pshuflw VdqWdq,Ib (F2),(VEX),(o128) |
442 | 71: Grp12 (1A) | 426 | 71: Grp12 (1A) |
443 | 72: Grp13 (1A) | 427 | 72: Grp13 (1A) |
444 | 73: Grp14 (1A) | 428 | 73: Grp14 (1A) |
445 | 74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1) | 429 | 74: pcmpeqb Pq,Qq | pcmpeqb Vdq,Wdq (66),(VEX),(o128) |
446 | 75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1) | 430 | 75: pcmpeqw Pq,Qq | pcmpeqw Vdq,Wdq (66),(VEX),(o128) |
447 | 76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1) | 431 | 76: pcmpeqd Pq,Qq | pcmpeqd Vdq,Wdq (66),(VEX),(o128) |
448 | # Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX. | 432 | 77: emms/vzeroupper/vzeroall (VEX) |
449 | 77: emms | vzeroupper | vzeroall | 433 | 78: VMREAD Ed/q,Gd/q |
450 | 78: VMREAD Ey,Gy | 434 | 79: VMWRITE Gd/q,Ed/q |
451 | 79: VMWRITE Gy,Ey | ||
452 | 7a: | 435 | 7a: |
453 | 7b: | 436 | 7b: |
454 | 7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2) | 437 | 7c: haddps Vps,Wps (F2),(VEX) | haddpd Vpd,Wpd (66),(VEX) |
455 | 7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2) | 438 | 7d: hsubps Vps,Wps (F2),(VEX) | hsubpd Vpd,Wpd (66),(VEX) |
456 | 7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1) | 439 | 7e: movd/q Ed/q,Pd | movd/q Ed/q,Vdq (66),(VEX),(o128) | movq Vq,Wq (F3),(VEX),(o128) |
457 | 7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqu Wx,Vx (F3) | 440 | 7f: movq Qq,Pq | movdqa Wdq,Vdq (66),(VEX) | movdqu Wdq,Vdq (F3),(VEX) |
458 | # 0x0f 0x80-0x8f | 441 | # 0x0f 0x80-0x8f |
459 | 80: JO Jz (f64) | 442 | 80: JO Jz (f64) |
460 | 81: JNO Jz (f64) | 443 | 81: JNO Jz (f64) |
461 | 82: JB/JC/JNAE Jz (f64) | 444 | 82: JB/JNAE/JC Jz (f64) |
462 | 83: JAE/JNB/JNC Jz (f64) | 445 | 83: JNB/JAE/JNC Jz (f64) |
463 | 84: JE/JZ Jz (f64) | 446 | 84: JZ/JE Jz (f64) |
464 | 85: JNE/JNZ Jz (f64) | 447 | 85: JNZ/JNE Jz (f64) |
465 | 86: JBE/JNA Jz (f64) | 448 | 86: JBE/JNA Jz (f64) |
466 | 87: JA/JNBE Jz (f64) | 449 | 87: JNBE/JA Jz (f64) |
467 | 88: JS Jz (f64) | 450 | 88: JS Jz (f64) |
468 | 89: JNS Jz (f64) | 451 | 89: JNS Jz (f64) |
469 | 8a: JP/JPE Jz (f64) | 452 | 8a: JP/JPE Jz (f64) |
@@ -515,22 +498,22 @@ b4: LFS Gv,Mp | |||
515 | b5: LGS Gv,Mp | 498 | b5: LGS Gv,Mp |
516 | b6: MOVZX Gv,Eb | 499 | b6: MOVZX Gv,Eb |
517 | b7: MOVZX Gv,Ew | 500 | b7: MOVZX Gv,Ew |
518 | b8: JMPE (!F3) | POPCNT Gv,Ev (F3) | 501 | b8: JMPE | POPCNT Gv,Ev (F3) |
519 | b9: Grp10 (1A) | 502 | b9: Grp10 (1A) |
520 | ba: Grp8 Ev,Ib (1A) | 503 | ba: Grp8 Ev,Ib (1A) |
521 | bb: BTC Ev,Gv | 504 | bb: BTC Ev,Gv |
522 | bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3) | 505 | bc: BSF Gv,Ev |
523 | bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3) | 506 | bd: BSR Gv,Ev |
524 | be: MOVSX Gv,Eb | 507 | be: MOVSX Gv,Eb |
525 | bf: MOVSX Gv,Ew | 508 | bf: MOVSX Gv,Ew |
526 | # 0x0f 0xc0-0xcf | 509 | # 0x0f 0xc0-0xcf |
527 | c0: XADD Eb,Gb | 510 | c0: XADD Eb,Gb |
528 | c1: XADD Ev,Gv | 511 | c1: XADD Ev,Gv |
529 | 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) | 512 | c2: cmpps Vps,Wps,Ib (VEX) | cmpss Vss,Wss,Ib (F3),(VEX),(o128) | cmppd Vpd,Wpd,Ib (66),(VEX) | cmpsd Vsd,Wsd,Ib (F2),(VEX) |
530 | c3: movnti My,Gy | 513 | c3: movnti Md/q,Gd/q |
531 | c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1) | 514 | c4: pinsrw Pq,Rd/q/Mw,Ib | pinsrw Vdq,Rd/q/Mw,Ib (66),(VEX),(o128) |
532 | c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1) | 515 | c5: pextrw Gd,Nq,Ib | pextrw Gd,Udq,Ib (66),(VEX),(o128) |
533 | c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66) | 516 | c6: shufps Vps,Wps,Ib (VEX) | shufpd Vpd,Wpd,Ib (66),(VEX) |
534 | c7: Grp9 (1A) | 517 | c7: Grp9 (1A) |
535 | c8: BSWAP RAX/EAX/R8/R8D | 518 | c8: BSWAP RAX/EAX/R8/R8D |
536 | c9: BSWAP RCX/ECX/R9/R9D | 519 | c9: BSWAP RCX/ECX/R9/R9D |
@@ -541,55 +524,55 @@ cd: BSWAP RBP/EBP/R13/R13D | |||
541 | ce: BSWAP RSI/ESI/R14/R14D | 524 | ce: BSWAP RSI/ESI/R14/R14D |
542 | cf: BSWAP RDI/EDI/R15/R15D | 525 | cf: BSWAP RDI/EDI/R15/R15D |
543 | # 0x0f 0xd0-0xdf | 526 | # 0x0f 0xd0-0xdf |
544 | d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2) | 527 | d0: addsubps Vps,Wps (F2),(VEX) | addsubpd Vpd,Wpd (66),(VEX) |
545 | d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1) | 528 | d1: psrlw Pq,Qq | psrlw Vdq,Wdq (66),(VEX),(o128) |
546 | d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1) | 529 | d2: psrld Pq,Qq | psrld Vdq,Wdq (66),(VEX),(o128) |
547 | d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1) | 530 | d3: psrlq Pq,Qq | psrlq Vdq,Wdq (66),(VEX),(o128) |
548 | d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1) | 531 | d4: paddq Pq,Qq | paddq Vdq,Wdq (66),(VEX),(o128) |
549 | d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1) | 532 | d5: pmullw Pq,Qq | pmullw Vdq,Wdq (66),(VEX),(o128) |
550 | d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2) | 533 | d6: movq Wq,Vq (66),(VEX),(o128) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2) |
551 | d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1) | 534 | d7: pmovmskb Gd,Nq | pmovmskb Gd,Udq (66),(VEX),(o128) |
552 | d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1) | 535 | d8: psubusb Pq,Qq | psubusb Vdq,Wdq (66),(VEX),(o128) |
553 | d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1) | 536 | d9: psubusw Pq,Qq | psubusw Vdq,Wdq (66),(VEX),(o128) |
554 | da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1) | 537 | da: pminub Pq,Qq | pminub Vdq,Wdq (66),(VEX),(o128) |
555 | db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | 538 | db: pand Pq,Qq | pand Vdq,Wdq (66),(VEX),(o128) |
556 | dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1) | 539 | dc: paddusb Pq,Qq | paddusb Vdq,Wdq (66),(VEX),(o128) |
557 | dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1) | 540 | dd: paddusw Pq,Qq | paddusw Vdq,Wdq (66),(VEX),(o128) |
558 | de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1) | 541 | de: pmaxub Pq,Qq | pmaxub Vdq,Wdq (66),(VEX),(o128) |
559 | df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | 542 | df: pandn Pq,Qq | pandn Vdq,Wdq (66),(VEX),(o128) |
560 | # 0x0f 0xe0-0xef | 543 | # 0x0f 0xe0-0xef |
561 | e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1) | 544 | e0: pavgb Pq,Qq | pavgb Vdq,Wdq (66),(VEX),(o128) |
562 | e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1) | 545 | e1: psraw Pq,Qq | psraw Vdq,Wdq (66),(VEX),(o128) |
563 | e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1) | 546 | e2: psrad Pq,Qq | psrad Vdq,Wdq (66),(VEX),(o128) |
564 | e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1) | 547 | e3: pavgw Pq,Qq | pavgw Vdq,Wdq (66),(VEX),(o128) |
565 | e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1) | 548 | e4: pmulhuw Pq,Qq | pmulhuw Vdq,Wdq (66),(VEX),(o128) |
566 | e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1) | 549 | e5: pmulhw Pq,Qq | pmulhw Vdq,Wdq (66),(VEX),(o128) |
567 | e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtpd2dq Vx,Wpd (F2) | 550 | e6: cvtpd2dq Vdq,Wpd (F2),(VEX) | cvttpd2dq Vdq,Wpd (66),(VEX) | cvtdq2pd Vpd,Wdq (F3),(VEX) |
568 | e7: movntq Mq,Pq | vmovntdq Mx,Vx (66) | 551 | e7: movntq Mq,Pq | movntdq Mdq,Vdq (66),(VEX) |
569 | e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1) | 552 | e8: psubsb Pq,Qq | psubsb Vdq,Wdq (66),(VEX),(o128) |
570 | e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1) | 553 | e9: psubsw Pq,Qq | psubsw Vdq,Wdq (66),(VEX),(o128) |
571 | ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1) | 554 | ea: pminsw Pq,Qq | pminsw Vdq,Wdq (66),(VEX),(o128) |
572 | eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | 555 | eb: por Pq,Qq | por Vdq,Wdq (66),(VEX),(o128) |
573 | ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1) | 556 | ec: paddsb Pq,Qq | paddsb Vdq,Wdq (66),(VEX),(o128) |
574 | ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1) | 557 | ed: paddsw Pq,Qq | paddsw Vdq,Wdq (66),(VEX),(o128) |
575 | ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1) | 558 | ee: pmaxsw Pq,Qq | pmaxsw Vdq,Wdq (66),(VEX),(o128) |
576 | ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | 559 | ef: pxor Pq,Qq | pxor Vdq,Wdq (66),(VEX),(o128) |
577 | # 0x0f 0xf0-0xff | 560 | # 0x0f 0xf0-0xff |
578 | f0: vlddqu Vx,Mx (F2) | 561 | f0: lddqu Vdq,Mdq (F2),(VEX) |
579 | f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1) | 562 | f1: psllw Pq,Qq | psllw Vdq,Wdq (66),(VEX),(o128) |
580 | f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1) | 563 | f2: pslld Pq,Qq | pslld Vdq,Wdq (66),(VEX),(o128) |
581 | f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1) | 564 | f3: psllq Pq,Qq | psllq Vdq,Wdq (66),(VEX),(o128) |
582 | f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1) | 565 | f4: pmuludq Pq,Qq | pmuludq Vdq,Wdq (66),(VEX),(o128) |
583 | f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1) | 566 | f5: pmaddwd Pq,Qq | pmaddwd Vdq,Wdq (66),(VEX),(o128) |
584 | f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1) | 567 | f6: psadbw Pq,Qq | psadbw Vdq,Wdq (66),(VEX),(o128) |
585 | f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1) | 568 | f7: maskmovq Pq,Nq | maskmovdqu Vdq,Udq (66),(VEX),(o128) |
586 | f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1) | 569 | f8: psubb Pq,Qq | psubb Vdq,Wdq (66),(VEX),(o128) |
587 | f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1) | 570 | f9: psubw Pq,Qq | psubw Vdq,Wdq (66),(VEX),(o128) |
588 | fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1) | 571 | fa: psubd Pq,Qq | psubd Vdq,Wdq (66),(VEX),(o128) |
589 | fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) | 572 | fb: psubq Pq,Qq | psubq Vdq,Wdq (66),(VEX),(o128) |
590 | fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) | 573 | fc: paddb Pq,Qq | paddb Vdq,Wdq (66),(VEX),(o128) |
591 | fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) | 574 | fd: paddw Pq,Qq | paddw Vdq,Wdq (66),(VEX),(o128) |
592 | fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) | 575 | fe: paddd Pq,Qq | paddd Vdq,Wdq (66),(VEX),(o128) |
593 | ff: | 576 | ff: |
594 | EndTable | 577 | EndTable |
595 | 578 | ||
@@ -597,193 +580,155 @@ Table: 3-byte opcode 1 (0x0f 0x38) | |||
597 | Referrer: 3-byte escape 1 | 580 | Referrer: 3-byte escape 1 |
598 | AVXcode: 2 | 581 | AVXcode: 2 |
599 | # 0x0f 0x38 0x00-0x0f | 582 | # 0x0f 0x38 0x00-0x0f |
600 | 00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1) | 583 | 00: pshufb Pq,Qq | pshufb Vdq,Wdq (66),(VEX),(o128) |
601 | 01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1) | 584 | 01: phaddw Pq,Qq | phaddw Vdq,Wdq (66),(VEX),(o128) |
602 | 02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1) | 585 | 02: phaddd Pq,Qq | phaddd Vdq,Wdq (66),(VEX),(o128) |
603 | 03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1) | 586 | 03: phaddsw Pq,Qq | phaddsw Vdq,Wdq (66),(VEX),(o128) |
604 | 04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1) | 587 | 04: pmaddubsw Pq,Qq | pmaddubsw Vdq,Wdq (66),(VEX),(o128) |
605 | 05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1) | 588 | 05: phsubw Pq,Qq | phsubw Vdq,Wdq (66),(VEX),(o128) |
606 | 06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1) | 589 | 06: phsubd Pq,Qq | phsubd Vdq,Wdq (66),(VEX),(o128) |
607 | 07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1) | 590 | 07: phsubsw Pq,Qq | phsubsw Vdq,Wdq (66),(VEX),(o128) |
608 | 08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1) | 591 | 08: psignb Pq,Qq | psignb Vdq,Wdq (66),(VEX),(o128) |
609 | 09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1) | 592 | 09: psignw Pq,Qq | psignw Vdq,Wdq (66),(VEX),(o128) |
610 | 0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1) | 593 | 0a: psignd Pq,Qq | psignd Vdq,Wdq (66),(VEX),(o128) |
611 | 0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1) | 594 | 0b: pmulhrsw Pq,Qq | pmulhrsw Vdq,Wdq (66),(VEX),(o128) |
612 | 0c: vpermilps Vx,Hx,Wx (66),(v) | 595 | 0c: Vpermilps /r (66),(oVEX) |
613 | 0d: vpermilpd Vx,Hx,Wx (66),(v) | 596 | 0d: Vpermilpd /r (66),(oVEX) |
614 | 0e: vtestps Vx,Wx (66),(v) | 597 | 0e: vtestps /r (66),(oVEX) |
615 | 0f: vtestpd Vx,Wx (66),(v) | 598 | 0f: vtestpd /r (66),(oVEX) |
616 | # 0x0f 0x38 0x10-0x1f | 599 | # 0x0f 0x38 0x10-0x1f |
617 | 10: pblendvb Vdq,Wdq (66) | 600 | 10: pblendvb Vdq,Wdq (66) |
618 | 11: | 601 | 11: |
619 | 12: | 602 | 12: |
620 | 13: vcvtph2ps Vx,Wx,Ib (66),(v) | 603 | 13: |
621 | 14: blendvps Vdq,Wdq (66) | 604 | 14: blendvps Vdq,Wdq (66) |
622 | 15: blendvpd Vdq,Wdq (66) | 605 | 15: blendvpd Vdq,Wdq (66) |
623 | 16: vpermps Vqq,Hqq,Wqq (66),(v) | 606 | 16: |
624 | 17: vptest Vx,Wx (66) | 607 | 17: ptest Vdq,Wdq (66),(VEX) |
625 | 18: vbroadcastss Vx,Wd (66),(v) | 608 | 18: vbroadcastss /r (66),(oVEX) |
626 | 19: vbroadcastsd Vqq,Wq (66),(v) | 609 | 19: vbroadcastsd /r (66),(oVEX),(o256) |
627 | 1a: vbroadcastf128 Vqq,Mdq (66),(v) | 610 | 1a: vbroadcastf128 /r (66),(oVEX),(o256) |
628 | 1b: | 611 | 1b: |
629 | 1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1) | 612 | 1c: pabsb Pq,Qq | pabsb Vdq,Wdq (66),(VEX),(o128) |
630 | 1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1) | 613 | 1d: pabsw Pq,Qq | pabsw Vdq,Wdq (66),(VEX),(o128) |
631 | 1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1) | 614 | 1e: pabsd Pq,Qq | pabsd Vdq,Wdq (66),(VEX),(o128) |
632 | 1f: | 615 | 1f: |
633 | # 0x0f 0x38 0x20-0x2f | 616 | # 0x0f 0x38 0x20-0x2f |
634 | 20: vpmovsxbw Vx,Ux/Mq (66),(v1) | 617 | 20: pmovsxbw Vdq,Udq/Mq (66),(VEX),(o128) |
635 | 21: vpmovsxbd Vx,Ux/Md (66),(v1) | 618 | 21: pmovsxbd Vdq,Udq/Md (66),(VEX),(o128) |
636 | 22: vpmovsxbq Vx,Ux/Mw (66),(v1) | 619 | 22: pmovsxbq Vdq,Udq/Mw (66),(VEX),(o128) |
637 | 23: vpmovsxwd Vx,Ux/Mq (66),(v1) | 620 | 23: pmovsxwd Vdq,Udq/Mq (66),(VEX),(o128) |
638 | 24: vpmovsxwq Vx,Ux/Md (66),(v1) | 621 | 24: pmovsxwq Vdq,Udq/Md (66),(VEX),(o128) |
639 | 25: vpmovsxdq Vx,Ux/Mq (66),(v1) | 622 | 25: pmovsxdq Vdq,Udq/Mq (66),(VEX),(o128) |
640 | 26: | 623 | 26: |
641 | 27: | 624 | 27: |
642 | 28: vpmuldq Vx,Hx,Wx (66),(v1) | 625 | 28: pmuldq Vdq,Wdq (66),(VEX),(o128) |
643 | 29: vpcmpeqq Vx,Hx,Wx (66),(v1) | 626 | 29: pcmpeqq Vdq,Wdq (66),(VEX),(o128) |
644 | 2a: vmovntdqa Vx,Mx (66),(v1) | 627 | 2a: movntdqa Vdq,Mdq (66),(VEX),(o128) |
645 | 2b: vpackusdw Vx,Hx,Wx (66),(v1) | 628 | 2b: packusdw Vdq,Wdq (66),(VEX),(o128) |
646 | 2c: vmaskmovps Vx,Hx,Mx (66),(v) | 629 | 2c: vmaskmovps(ld) /r (66),(oVEX) |
647 | 2d: vmaskmovpd Vx,Hx,Mx (66),(v) | 630 | 2d: vmaskmovpd(ld) /r (66),(oVEX) |
648 | 2e: vmaskmovps Mx,Hx,Vx (66),(v) | 631 | 2e: vmaskmovps(st) /r (66),(oVEX) |
649 | 2f: vmaskmovpd Mx,Hx,Vx (66),(v) | 632 | 2f: vmaskmovpd(st) /r (66),(oVEX) |
650 | # 0x0f 0x38 0x30-0x3f | 633 | # 0x0f 0x38 0x30-0x3f |
651 | 30: vpmovzxbw Vx,Ux/Mq (66),(v1) | 634 | 30: pmovzxbw Vdq,Udq/Mq (66),(VEX),(o128) |
652 | 31: vpmovzxbd Vx,Ux/Md (66),(v1) | 635 | 31: pmovzxbd Vdq,Udq/Md (66),(VEX),(o128) |
653 | 32: vpmovzxbq Vx,Ux/Mw (66),(v1) | 636 | 32: pmovzxbq Vdq,Udq/Mw (66),(VEX),(o128) |
654 | 33: vpmovzxwd Vx,Ux/Mq (66),(v1) | 637 | 33: pmovzxwd Vdq,Udq/Mq (66),(VEX),(o128) |
655 | 34: vpmovzxwq Vx,Ux/Md (66),(v1) | 638 | 34: pmovzxwq Vdq,Udq/Md (66),(VEX),(o128) |
656 | 35: vpmovzxdq Vx,Ux/Mq (66),(v1) | 639 | 35: pmovzxdq Vdq,Udq/Mq (66),(VEX),(o128) |
657 | 36: vpermd Vqq,Hqq,Wqq (66),(v) | 640 | 36: |
658 | 37: vpcmpgtq Vx,Hx,Wx (66),(v1) | 641 | 37: pcmpgtq Vdq,Wdq (66),(VEX),(o128) |
659 | 38: vpminsb Vx,Hx,Wx (66),(v1) | 642 | 38: pminsb Vdq,Wdq (66),(VEX),(o128) |
660 | 39: vpminsd Vx,Hx,Wx (66),(v1) | 643 | 39: pminsd Vdq,Wdq (66),(VEX),(o128) |
661 | 3a: vpminuw Vx,Hx,Wx (66),(v1) | 644 | 3a: pminuw Vdq,Wdq (66),(VEX),(o128) |
662 | 3b: vpminud Vx,Hx,Wx (66),(v1) | 645 | 3b: pminud Vdq,Wdq (66),(VEX),(o128) |
663 | 3c: vpmaxsb Vx,Hx,Wx (66),(v1) | 646 | 3c: pmaxsb Vdq,Wdq (66),(VEX),(o128) |
664 | 3d: vpmaxsd Vx,Hx,Wx (66),(v1) | 647 | 3d: pmaxsd Vdq,Wdq (66),(VEX),(o128) |
665 | 3e: vpmaxuw Vx,Hx,Wx (66),(v1) | 648 | 3e: pmaxuw Vdq,Wdq (66),(VEX),(o128) |
666 | 3f: vpmaxud Vx,Hx,Wx (66),(v1) | 649 | 3f: pmaxud Vdq,Wdq (66),(VEX),(o128) |
667 | # 0x0f 0x38 0x40-0x8f | 650 | # 0x0f 0x38 0x40-0x8f |
668 | 40: vpmulld Vx,Hx,Wx (66),(v1) | 651 | 40: pmulld Vdq,Wdq (66),(VEX),(o128) |
669 | 41: vphminposuw Vdq,Wdq (66),(v1) | 652 | 41: phminposuw Vdq,Wdq (66),(VEX),(o128) |
670 | 42: | 653 | 80: INVEPT Gd/q,Mdq (66) |
671 | 43: | 654 | 81: INVPID Gd/q,Mdq (66) |
672 | 44: | ||
673 | 45: vpsrlvd/q Vx,Hx,Wx (66),(v) | ||
674 | 46: vpsravd Vx,Hx,Wx (66),(v) | ||
675 | 47: vpsllvd/q Vx,Hx,Wx (66),(v) | ||
676 | # Skip 0x48-0x57 | ||
677 | 58: vpbroadcastd Vx,Wx (66),(v) | ||
678 | 59: vpbroadcastq Vx,Wx (66),(v) | ||
679 | 5a: vbroadcasti128 Vqq,Mdq (66),(v) | ||
680 | # Skip 0x5b-0x77 | ||
681 | 78: vpbroadcastb Vx,Wx (66),(v) | ||
682 | 79: vpbroadcastw Vx,Wx (66),(v) | ||
683 | # Skip 0x7a-0x7f | ||
684 | 80: INVEPT Gy,Mdq (66) | ||
685 | 81: INVPID Gy,Mdq (66) | ||
686 | 82: INVPCID Gy,Mdq (66) | ||
687 | 8c: vpmaskmovd/q Vx,Hx,Mx (66),(v) | ||
688 | 8e: vpmaskmovd/q Mx,Vx,Hx (66),(v) | ||
689 | # 0x0f 0x38 0x90-0xbf (FMA) | 655 | # 0x0f 0x38 0x90-0xbf (FMA) |
690 | 90: vgatherdd/q Vx,Hx,Wx (66),(v) | 656 | 96: vfmaddsub132pd/ps /r (66),(VEX) |
691 | 91: vgatherqd/q Vx,Hx,Wx (66),(v) | 657 | 97: vfmsubadd132pd/ps /r (66),(VEX) |
692 | 92: vgatherdps/d Vx,Hx,Wx (66),(v) | 658 | 98: vfmadd132pd/ps /r (66),(VEX) |
693 | 93: vgatherqps/d Vx,Hx,Wx (66),(v) | 659 | 99: vfmadd132sd/ss /r (66),(VEX),(o128) |
694 | 94: | 660 | 9a: vfmsub132pd/ps /r (66),(VEX) |
695 | 95: | 661 | 9b: vfmsub132sd/ss /r (66),(VEX),(o128) |
696 | 96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v) | 662 | 9c: vfnmadd132pd/ps /r (66),(VEX) |
697 | 97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v) | 663 | 9d: vfnmadd132sd/ss /r (66),(VEX),(o128) |
698 | 98: vfmadd132ps/d Vx,Hx,Wx (66),(v) | 664 | 9e: vfnmsub132pd/ps /r (66),(VEX) |
699 | 99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1) | 665 | 9f: vfnmsub132sd/ss /r (66),(VEX),(o128) |
700 | 9a: vfmsub132ps/d Vx,Hx,Wx (66),(v) | 666 | a6: vfmaddsub213pd/ps /r (66),(VEX) |
701 | 9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1) | 667 | a7: vfmsubadd213pd/ps /r (66),(VEX) |
702 | 9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v) | 668 | a8: vfmadd213pd/ps /r (66),(VEX) |
703 | 9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) | 669 | a9: vfmadd213sd/ss /r (66),(VEX),(o128) |
704 | 9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) | 670 | aa: vfmsub213pd/ps /r (66),(VEX) |
705 | 9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1) | 671 | ab: vfmsub213sd/ss /r (66),(VEX),(o128) |
706 | a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) | 672 | ac: vfnmadd213pd/ps /r (66),(VEX) |
707 | a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) | 673 | ad: vfnmadd213sd/ss /r (66),(VEX),(o128) |
708 | a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) | 674 | ae: vfnmsub213pd/ps /r (66),(VEX) |
709 | a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1) | 675 | af: vfnmsub213sd/ss /r (66),(VEX),(o128) |
710 | aa: vfmsub213ps/d Vx,Hx,Wx (66),(v) | 676 | b6: vfmaddsub231pd/ps /r (66),(VEX) |
711 | ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1) | 677 | b7: vfmsubadd231pd/ps /r (66),(VEX) |
712 | ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v) | 678 | b8: vfmadd231pd/ps /r (66),(VEX) |
713 | ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) | 679 | b9: vfmadd231sd/ss /r (66),(VEX),(o128) |
714 | ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) | 680 | ba: vfmsub231pd/ps /r (66),(VEX) |
715 | af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) | 681 | bb: vfmsub231sd/ss /r (66),(VEX),(o128) |
716 | b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) | 682 | bc: vfnmadd231pd/ps /r (66),(VEX) |
717 | b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) | 683 | bd: vfnmadd231sd/ss /r (66),(VEX),(o128) |
718 | b8: vfmadd231ps/d Vx,Hx,Wx (66),(v) | 684 | be: vfnmsub231pd/ps /r (66),(VEX) |
719 | b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1) | 685 | bf: vfnmsub231sd/ss /r (66),(VEX),(o128) |
720 | ba: vfmsub231ps/d Vx,Hx,Wx (66),(v) | ||
721 | bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1) | ||
722 | bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v) | ||
723 | bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1) | ||
724 | be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) | ||
725 | bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) | ||
726 | # 0x0f 0x38 0xc0-0xff | 686 | # 0x0f 0x38 0xc0-0xff |
727 | db: VAESIMC Vdq,Wdq (66),(v1) | 687 | db: aesimc Vdq,Wdq (66),(VEX),(o128) |
728 | dc: VAESENC Vdq,Hdq,Wdq (66),(v1) | 688 | dc: aesenc Vdq,Wdq (66),(VEX),(o128) |
729 | dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) | 689 | dd: aesenclast Vdq,Wdq (66),(VEX),(o128) |
730 | de: VAESDEC Vdq,Hdq,Wdq (66),(v1) | 690 | de: aesdec Vdq,Wdq (66),(VEX),(o128) |
731 | df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1) | 691 | df: aesdeclast Vdq,Wdq (66),(VEX),(o128) |
732 | f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | 692 | f0: MOVBE Gv,Mv | CRC32 Gd,Eb (F2) |
733 | f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | 693 | f1: MOVBE Mv,Gv | CRC32 Gd,Ev (F2) |
734 | f2: ANDN Gy,By,Ey (v) | ||
735 | f3: Grp17 (1A) | ||
736 | f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) | ||
737 | f6: MULX By,Gy,rDX,Ey (F2),(v) | ||
738 | f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) | ||
739 | EndTable | 694 | EndTable |
740 | 695 | ||
741 | Table: 3-byte opcode 2 (0x0f 0x3a) | 696 | Table: 3-byte opcode 2 (0x0f 0x3a) |
742 | Referrer: 3-byte escape 2 | 697 | Referrer: 3-byte escape 2 |
743 | AVXcode: 3 | 698 | AVXcode: 3 |
744 | # 0x0f 0x3a 0x00-0xff | 699 | # 0x0f 0x3a 0x00-0xff |
745 | 00: vpermq Vqq,Wqq,Ib (66),(v) | 700 | 04: vpermilps /r,Ib (66),(oVEX) |
746 | 01: vpermpd Vqq,Wqq,Ib (66),(v) | 701 | 05: vpermilpd /r,Ib (66),(oVEX) |
747 | 02: vpblendd Vx,Hx,Wx,Ib (66),(v) | 702 | 06: vperm2f128 /r,Ib (66),(oVEX),(o256) |
748 | 03: | 703 | 08: roundps Vdq,Wdq,Ib (66),(VEX) |
749 | 04: vpermilps Vx,Wx,Ib (66),(v) | 704 | 09: roundpd Vdq,Wdq,Ib (66),(VEX) |
750 | 05: vpermilpd Vx,Wx,Ib (66),(v) | 705 | 0a: roundss Vss,Wss,Ib (66),(VEX),(o128) |
751 | 06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v) | 706 | 0b: roundsd Vsd,Wsd,Ib (66),(VEX),(o128) |
752 | 07: | 707 | 0c: blendps Vdq,Wdq,Ib (66),(VEX) |
753 | 08: vroundps Vx,Wx,Ib (66) | 708 | 0d: blendpd Vdq,Wdq,Ib (66),(VEX) |
754 | 09: vroundpd Vx,Wx,Ib (66) | 709 | 0e: pblendw Vdq,Wdq,Ib (66),(VEX),(o128) |
755 | 0a: vroundss Vss,Wss,Ib (66),(v1) | 710 | 0f: palignr Pq,Qq,Ib | palignr Vdq,Wdq,Ib (66),(VEX),(o128) |
756 | 0b: vroundsd Vsd,Wsd,Ib (66),(v1) | 711 | 14: pextrb Rd/Mb,Vdq,Ib (66),(VEX),(o128) |
757 | 0c: vblendps Vx,Hx,Wx,Ib (66) | 712 | 15: pextrw Rd/Mw,Vdq,Ib (66),(VEX),(o128) |
758 | 0d: vblendpd Vx,Hx,Wx,Ib (66) | 713 | 16: pextrd/pextrq Ed/q,Vdq,Ib (66),(VEX),(o128) |
759 | 0e: vpblendw Vx,Hx,Wx,Ib (66),(v1) | 714 | 17: extractps Ed,Vdq,Ib (66),(VEX),(o128) |
760 | 0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1) | 715 | 18: vinsertf128 /r,Ib (66),(oVEX),(o256) |
761 | 14: vpextrb Rd/Mb,Vdq,Ib (66),(v1) | 716 | 19: vextractf128 /r,Ib (66),(oVEX),(o256) |
762 | 15: vpextrw Rd/Mw,Vdq,Ib (66),(v1) | 717 | 20: pinsrb Vdq,Rd/q/Mb,Ib (66),(VEX),(o128) |
763 | 16: vpextrd/q Ey,Vdq,Ib (66),(v1) | 718 | 21: insertps Vdq,Udq/Md,Ib (66),(VEX),(o128) |
764 | 17: vextractps Ed,Vdq,Ib (66),(v1) | 719 | 22: pinsrd/pinsrq Vdq,Ed/q,Ib (66),(VEX),(o128) |
765 | 18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | 720 | 40: dpps Vdq,Wdq,Ib (66),(VEX) |
766 | 19: vextractf128 Wdq,Vqq,Ib (66),(v) | 721 | 41: dppd Vdq,Wdq,Ib (66),(VEX),(o128) |
767 | 1d: vcvtps2ph Wx,Vx,Ib (66),(v) | 722 | 42: mpsadbw Vdq,Wdq,Ib (66),(VEX),(o128) |
768 | 20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1) | 723 | 44: pclmulq Vdq,Wdq,Ib (66),(VEX),(o128) |
769 | 21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1) | 724 | 4a: vblendvps /r,Ib (66),(oVEX) |
770 | 22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1) | 725 | 4b: vblendvpd /r,Ib (66),(oVEX) |
771 | 38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | 726 | 4c: vpblendvb /r,Ib (66),(oVEX),(o128) |
772 | 39: vextracti128 Wdq,Vqq,Ib (66),(v) | 727 | 60: pcmpestrm Vdq,Wdq,Ib (66),(VEX),(o128) |
773 | 40: vdpps Vx,Hx,Wx,Ib (66) | 728 | 61: pcmpestri Vdq,Wdq,Ib (66),(VEX),(o128) |
774 | 41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) | 729 | 62: pcmpistrm Vdq,Wdq,Ib (66),(VEX),(o128) |
775 | 42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | 730 | 63: pcmpistri Vdq,Wdq,Ib (66),(VEX),(o128) |
776 | 44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) | 731 | df: aeskeygenassist Vdq,Wdq,Ib (66),(VEX),(o128) |
777 | 46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) | ||
778 | 4a: vblendvps Vx,Hx,Wx,Lx (66),(v) | ||
779 | 4b: vblendvpd Vx,Hx,Wx,Lx (66),(v) | ||
780 | 4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1) | ||
781 | 60: vpcmpestrm Vdq,Wdq,Ib (66),(v1) | ||
782 | 61: vpcmpestri Vdq,Wdq,Ib (66),(v1) | ||
783 | 62: vpcmpistrm Vdq,Wdq,Ib (66),(v1) | ||
784 | 63: vpcmpistri Vdq,Wdq,Ib (66),(v1) | ||
785 | df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) | ||
786 | f0: RORX Gy,Ey,Ib (F2),(v) | ||
787 | EndTable | 732 | EndTable |
788 | 733 | ||
789 | GrpTable: Grp1 | 734 | GrpTable: Grp1 |
@@ -845,7 +790,7 @@ GrpTable: Grp5 | |||
845 | 2: CALLN Ev (f64) | 790 | 2: CALLN Ev (f64) |
846 | 3: CALLF Ep | 791 | 3: CALLF Ep |
847 | 4: JMPN Ev (f64) | 792 | 4: JMPN Ev (f64) |
848 | 5: JMPF Mp | 793 | 5: JMPF Ep |
849 | 6: PUSH Ev (d64) | 794 | 6: PUSH Ev (d64) |
850 | 7: | 795 | 7: |
851 | EndTable | 796 | EndTable |
@@ -862,7 +807,7 @@ EndTable | |||
862 | GrpTable: Grp7 | 807 | GrpTable: Grp7 |
863 | 0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) | 808 | 0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) |
864 | 1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001) | 809 | 1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001) |
865 | 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | 810 | 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) |
866 | 3: LIDT Ms | 811 | 3: LIDT Ms |
867 | 4: SMSW Mw/Rv | 812 | 4: SMSW Mw/Rv |
868 | 5: | 813 | 5: |
@@ -879,45 +824,44 @@ EndTable | |||
879 | 824 | ||
880 | GrpTable: Grp9 | 825 | GrpTable: Grp9 |
881 | 1: CMPXCHG8B/16B Mq/Mdq | 826 | 1: CMPXCHG8B/16B Mq/Mdq |
882 | 6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) | 827 | 6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) |
883 | 7: VMPTRST Mq | VMPTRST Mq (F3) | 828 | 7: VMPTRST Mq |
884 | EndTable | 829 | EndTable |
885 | 830 | ||
886 | GrpTable: Grp10 | 831 | GrpTable: Grp10 |
887 | EndTable | 832 | EndTable |
888 | 833 | ||
889 | GrpTable: Grp11 | 834 | GrpTable: Grp11 |
890 | # Note: the operands are given by group opcode | ||
891 | 0: MOV | 835 | 0: MOV |
892 | EndTable | 836 | EndTable |
893 | 837 | ||
894 | GrpTable: Grp12 | 838 | GrpTable: Grp12 |
895 | 2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1) | 839 | 2: psrlw Nq,Ib (11B) | psrlw Udq,Ib (66),(11B),(VEX),(o128) |
896 | 4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1) | 840 | 4: psraw Nq,Ib (11B) | psraw Udq,Ib (66),(11B),(VEX),(o128) |
897 | 6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1) | 841 | 6: psllw Nq,Ib (11B) | psllw Udq,Ib (66),(11B),(VEX),(o128) |
898 | EndTable | 842 | EndTable |
899 | 843 | ||
900 | GrpTable: Grp13 | 844 | GrpTable: Grp13 |
901 | 2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1) | 845 | 2: psrld Nq,Ib (11B) | psrld Udq,Ib (66),(11B),(VEX),(o128) |
902 | 4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | 846 | 4: psrad Nq,Ib (11B) | psrad Udq,Ib (66),(11B),(VEX),(o128) |
903 | 6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1) | 847 | 6: pslld Nq,Ib (11B) | pslld Udq,Ib (66),(11B),(VEX),(o128) |
904 | EndTable | 848 | EndTable |
905 | 849 | ||
906 | GrpTable: Grp14 | 850 | GrpTable: Grp14 |
907 | 2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1) | 851 | 2: psrlq Nq,Ib (11B) | psrlq Udq,Ib (66),(11B),(VEX),(o128) |
908 | 3: vpsrldq Hx,Ux,Ib (66),(11B),(v1) | 852 | 3: psrldq Udq,Ib (66),(11B),(VEX),(o128) |
909 | 6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1) | 853 | 6: psllq Nq,Ib (11B) | psllq Udq,Ib (66),(11B),(VEX),(o128) |
910 | 7: vpslldq Hx,Ux,Ib (66),(11B),(v1) | 854 | 7: pslldq Udq,Ib (66),(11B),(VEX),(o128) |
911 | EndTable | 855 | EndTable |
912 | 856 | ||
913 | GrpTable: Grp15 | 857 | GrpTable: Grp15 |
914 | 0: fxsave | RDFSBASE Ry (F3),(11B) | 858 | 0: fxsave |
915 | 1: fxstor | RDGSBASE Ry (F3),(11B) | 859 | 1: fxstor |
916 | 2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B) | 860 | 2: ldmxcsr (VEX) |
917 | 3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) | 861 | 3: stmxcsr (VEX) |
918 | 4: XSAVE | 862 | 4: XSAVE |
919 | 5: XRSTOR | lfence (11B) | 863 | 5: XRSTOR | lfence (11B) |
920 | 6: XSAVEOPT | mfence (11B) | 864 | 6: mfence (11B) |
921 | 7: clflush | sfence (11B) | 865 | 7: clflush | sfence (11B) |
922 | EndTable | 866 | EndTable |
923 | 867 | ||
@@ -928,12 +872,6 @@ GrpTable: Grp16 | |||
928 | 3: prefetch T2 | 872 | 3: prefetch T2 |
929 | EndTable | 873 | EndTable |
930 | 874 | ||
931 | GrpTable: Grp17 | ||
932 | 1: BLSR By,Ey (v) | ||
933 | 2: BLSMSK By,Ey (v) | ||
934 | 3: BLSI By,Ey (v) | ||
935 | EndTable | ||
936 | |||
937 | # AMD's Prefetch Group | 875 | # AMD's Prefetch Group |
938 | GrpTable: GrpP | 876 | GrpTable: GrpP |
939 | 0: PREFETCH | 877 | 0: PREFETCH |