aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-26 11:07:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-26 11:07:07 -0400
commit8686a0e200419322654a75155e2e6f80346a1297 (patch)
treee55b4509df7fceb1c1414f34c1b92b460a567bb0 /arch
parent7115e3fcf45514db7525a05365b10454ff7f345e (diff)
parent53a019a951fae849471e4a620948c5f6886bd1a4 (diff)
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86: Fix insn decoder for longer instruction
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/lib/insn.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 9f33b984d0e..374562ed670 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -22,14 +22,23 @@
22#include <asm/inat.h> 22#include <asm/inat.h>
23#include <asm/insn.h> 23#include <asm/insn.h>
24 24
25#define get_next(t, insn) \ 25/* Verify next sizeof(t) bytes can be on the same instruction */
26 ({t r; r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) 26#define validate_next(t, insn, n) \
27 ((insn)->next_byte + sizeof(t) + n - (insn)->kaddr <= MAX_INSN_SIZE)
28
29#define __get_next(t, insn) \
30 ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
31
32#define __peek_nbyte_next(t, insn, n) \
33 ({ t r = *(t*)((insn)->next_byte + n); r; })
27 34
28#define peek_next(t, insn) \ 35#define get_next(t, insn) \
29 ({t r; r = *(t*)insn->next_byte; r; }) 36 ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
30 37
31#define peek_nbyte_next(t, insn, n) \ 38#define peek_nbyte_next(t, insn, n) \
32 ({t r; r = *(t*)((insn)->next_byte + n); r; }) 39 ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); })
40
41#define peek_next(t, insn) peek_nbyte_next(t, insn, 0)
33 42
34/** 43/**
35 * insn_init() - initialize struct insn 44 * insn_init() - initialize struct insn
@@ -158,6 +167,8 @@ vex_end:
158 insn->vex_prefix.got = 1; 167 insn->vex_prefix.got = 1;
159 168
160 prefixes->got = 1; 169 prefixes->got = 1;
170
171err_out:
161 return; 172 return;
162} 173}
163 174
@@ -208,6 +219,9 @@ void insn_get_opcode(struct insn *insn)
208 insn->attr = 0; /* This instruction is bad */ 219 insn->attr = 0; /* This instruction is bad */
209end: 220end:
210 opcode->got = 1; 221 opcode->got = 1;
222
223err_out:
224 return;
211} 225}
212 226
213/** 227/**
@@ -241,6 +255,9 @@ void insn_get_modrm(struct insn *insn)
241 if (insn->x86_64 && inat_is_force64(insn->attr)) 255 if (insn->x86_64 && inat_is_force64(insn->attr))
242 insn->opnd_bytes = 8; 256 insn->opnd_bytes = 8;
243 modrm->got = 1; 257 modrm->got = 1;
258
259err_out:
260 return;
244} 261}
245 262
246 263
@@ -290,6 +307,9 @@ void insn_get_sib(struct insn *insn)
290 } 307 }
291 } 308 }
292 insn->sib.got = 1; 309 insn->sib.got = 1;
310
311err_out:
312 return;
293} 313}
294 314
295 315
@@ -351,6 +371,9 @@ void insn_get_displacement(struct insn *insn)
351 } 371 }
352out: 372out:
353 insn->displacement.got = 1; 373 insn->displacement.got = 1;
374
375err_out:
376 return;
354} 377}
355 378
356/* Decode moffset16/32/64 */ 379/* Decode moffset16/32/64 */
@@ -373,6 +396,9 @@ static void __get_moffset(struct insn *insn)
373 break; 396 break;
374 } 397 }
375 insn->moffset1.got = insn->moffset2.got = 1; 398 insn->moffset1.got = insn->moffset2.got = 1;
399
400err_out:
401 return;
376} 402}
377 403
378/* Decode imm v32(Iz) */ 404/* Decode imm v32(Iz) */
@@ -389,6 +415,9 @@ static void __get_immv32(struct insn *insn)
389 insn->immediate.nbytes = 4; 415 insn->immediate.nbytes = 4;
390 break; 416 break;
391 } 417 }
418
419err_out:
420 return;
392} 421}
393 422
394/* Decode imm v64(Iv/Ov) */ 423/* Decode imm v64(Iv/Ov) */
@@ -411,6 +440,9 @@ static void __get_immv(struct insn *insn)
411 break; 440 break;
412 } 441 }
413 insn->immediate1.got = insn->immediate2.got = 1; 442 insn->immediate1.got = insn->immediate2.got = 1;
443
444err_out:
445 return;
414} 446}
415 447
416/* Decode ptr16:16/32(Ap) */ 448/* Decode ptr16:16/32(Ap) */
@@ -432,6 +464,9 @@ static void __get_immptr(struct insn *insn)
432 insn->immediate2.value = get_next(unsigned short, insn); 464 insn->immediate2.value = get_next(unsigned short, insn);
433 insn->immediate2.nbytes = 2; 465 insn->immediate2.nbytes = 2;
434 insn->immediate1.got = insn->immediate2.got = 1; 466 insn->immediate1.got = insn->immediate2.got = 1;
467
468err_out:
469 return;
435} 470}
436 471
437/** 472/**
@@ -496,6 +531,9 @@ void insn_get_immediate(struct insn *insn)
496 } 531 }
497done: 532done:
498 insn->immediate.got = 1; 533 insn->immediate.got = 1;
534
535err_out:
536 return;
499} 537}
500 538
501/** 539/**