Commit cc05152a authored by Marcin Slusarz's avatar Marcin Slusarz Committed by Frederic Weisbecker

x86,mmiotrace: Add support for tracing STOS instruction

Add support for stos access tracing with mmiotrace.
Signed-off-by: default avatarMarcin Slusarz <marcin.slusarz@gmail.com>
Acked-by: default avatarPekka Paalanen <pq@iki.fi>
Cc: Nouveau <nouveau@lists.freedesktop.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <20100731205101.GA5860@joi.lan>
Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
parent 1b0ff06e
...@@ -40,16 +40,16 @@ static unsigned char prefix_codes[] = { ...@@ -40,16 +40,16 @@ static unsigned char prefix_codes[] = {
static unsigned int reg_rop[] = { static unsigned int reg_rop[] = {
0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F 0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F
}; };
static unsigned int reg_wop[] = { 0x88, 0x89 }; static unsigned int reg_wop[] = { 0x88, 0x89, 0xAA, 0xAB };
static unsigned int imm_wop[] = { 0xC6, 0xC7 }; static unsigned int imm_wop[] = { 0xC6, 0xC7 };
/* IA32 Manual 3, 3-432*/ /* IA32 Manual 3, 3-432*/
static unsigned int rw8[] = { 0x88, 0x8A, 0xC6 }; static unsigned int rw8[] = { 0x88, 0x8A, 0xC6, 0xAA };
static unsigned int rw32[] = { static unsigned int rw32[] = {
0x89, 0x8B, 0xC7, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F 0x89, 0x8B, 0xC7, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F, 0xAB
}; };
static unsigned int mw8[] = { 0x88, 0x8A, 0xC6, 0xB60F, 0xBE0F }; static unsigned int mw8[] = { 0x88, 0x8A, 0xC6, 0xB60F, 0xBE0F, 0xAA };
static unsigned int mw16[] = { 0xB70F, 0xBF0F }; static unsigned int mw16[] = { 0xB70F, 0xBF0F };
static unsigned int mw32[] = { 0x89, 0x8B, 0xC7 }; static unsigned int mw32[] = { 0x89, 0x8B, 0xC7, 0xAB };
static unsigned int mw64[] = {}; static unsigned int mw64[] = {};
#else /* not __i386__ */ #else /* not __i386__ */
static unsigned char prefix_codes[] = { static unsigned char prefix_codes[] = {
...@@ -63,20 +63,20 @@ static unsigned char prefix_codes[] = { ...@@ -63,20 +63,20 @@ static unsigned char prefix_codes[] = {
static unsigned int reg_rop[] = { static unsigned int reg_rop[] = {
0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F 0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F
}; };
static unsigned int reg_wop[] = { 0x88, 0x89 }; static unsigned int reg_wop[] = { 0x88, 0x89, 0xAA, 0xAB };
static unsigned int imm_wop[] = { 0xC6, 0xC7 }; static unsigned int imm_wop[] = { 0xC6, 0xC7 };
static unsigned int rw8[] = { 0xC6, 0x88, 0x8A }; static unsigned int rw8[] = { 0xC6, 0x88, 0x8A, 0xAA };
static unsigned int rw32[] = { static unsigned int rw32[] = {
0xC7, 0x89, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F 0xC7, 0x89, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F, 0xAB
}; };
/* 8 bit only */ /* 8 bit only */
static unsigned int mw8[] = { 0xC6, 0x88, 0x8A, 0xB60F, 0xBE0F }; static unsigned int mw8[] = { 0xC6, 0x88, 0x8A, 0xB60F, 0xBE0F, 0xAA };
/* 16 bit only */ /* 16 bit only */
static unsigned int mw16[] = { 0xB70F, 0xBF0F }; static unsigned int mw16[] = { 0xB70F, 0xBF0F };
/* 16 or 32 bit */ /* 16 or 32 bit */
static unsigned int mw32[] = { 0xC7 }; static unsigned int mw32[] = { 0xC7 };
/* 16, 32 or 64 bit */ /* 16, 32 or 64 bit */
static unsigned int mw64[] = { 0x89, 0x8B }; static unsigned int mw64[] = { 0x89, 0x8B, 0xAB };
#endif /* not __i386__ */ #endif /* not __i386__ */
struct prefix_bits { struct prefix_bits {
...@@ -410,7 +410,6 @@ static unsigned long *get_reg_w32(int no, struct pt_regs *regs) ...@@ -410,7 +410,6 @@ static unsigned long *get_reg_w32(int no, struct pt_regs *regs)
unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs) unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs)
{ {
unsigned int opcode; unsigned int opcode;
unsigned char mod_rm;
int reg; int reg;
unsigned char *p; unsigned char *p;
struct prefix_bits prf; struct prefix_bits prf;
...@@ -437,8 +436,13 @@ unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs) ...@@ -437,8 +436,13 @@ unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs)
goto err; goto err;
do_work: do_work:
mod_rm = *p; /* for STOS, source register is fixed */
if (opcode == 0xAA || opcode == 0xAB) {
reg = arg_AX;
} else {
unsigned char mod_rm = *p;
reg = ((mod_rm >> 3) & 0x7) | (prf.rexr << 3); reg = ((mod_rm >> 3) & 0x7) | (prf.rexr << 3);
}
switch (get_ins_reg_width(ins_addr)) { switch (get_ins_reg_width(ins_addr)) {
case 1: case 1:
return *get_reg_w8(reg, prf.rex, regs); return *get_reg_w8(reg, prf.rex, regs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment