x86: Fix to decode grouped AVX with VEX pp bits
Fix to decode grouped AVX with VEX pp bits which should be handled as same as last-prefixes. This fixes below warnings in posttest with CONFIG_CRYPTO_SHA1_SSSE3=y. Warning: arch/x86/tools/test_get_len found difference at <sha1_transform_avx>:ffffffff810d5fc0 Warning: ffffffff810d6069: c5 f9 73 de 04 vpsrldq $0x4,%xmm6,%xmm0 Warning: objdump says 5 bytes, but insn_get_length() says 4 ... With this change, test_get_len can decode it correctly. $ arch/x86/tools/test_get_len -v -y ffffffff810d6069: c5 f9 73 de 04 vpsrldq $0x4,%xmm6,%xmm0 Succeed: decoded and checked 1 instructions Reported-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: yrl.pp-manager.tt@hitachi.com Link: http://lkml.kernel.org/r/20120210053340.30429.73410.stgit@localhost.localdomain Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:

committed by
Ingo Molnar

parent
86f5e6a7b1
commit
f8d98f1095
@@ -29,46 +29,46 @@ insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
|
||||
return inat_primary_table[opcode];
|
||||
}
|
||||
|
||||
insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, insn_byte_t last_pfx,
|
||||
int inat_get_last_prefix_id(insn_byte_t last_pfx)
|
||||
{
|
||||
insn_attr_t lpfx_attr;
|
||||
|
||||
lpfx_attr = inat_get_opcode_attribute(last_pfx);
|
||||
return inat_last_prefix_id(lpfx_attr);
|
||||
}
|
||||
|
||||
insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id,
|
||||
insn_attr_t esc_attr)
|
||||
{
|
||||
const insn_attr_t *table;
|
||||
insn_attr_t lpfx_attr;
|
||||
int n, m = 0;
|
||||
int n;
|
||||
|
||||
n = inat_escape_id(esc_attr);
|
||||
if (last_pfx) {
|
||||
lpfx_attr = inat_get_opcode_attribute(last_pfx);
|
||||
m = inat_last_prefix_id(lpfx_attr);
|
||||
}
|
||||
|
||||
table = inat_escape_tables[n][0];
|
||||
if (!table)
|
||||
return 0;
|
||||
if (inat_has_variant(table[opcode]) && m) {
|
||||
table = inat_escape_tables[n][m];
|
||||
if (inat_has_variant(table[opcode]) && lpfx_id) {
|
||||
table = inat_escape_tables[n][lpfx_id];
|
||||
if (!table)
|
||||
return 0;
|
||||
}
|
||||
return table[opcode];
|
||||
}
|
||||
|
||||
insn_attr_t inat_get_group_attribute(insn_byte_t modrm, insn_byte_t last_pfx,
|
||||
insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id,
|
||||
insn_attr_t grp_attr)
|
||||
{
|
||||
const insn_attr_t *table;
|
||||
insn_attr_t lpfx_attr;
|
||||
int n, m = 0;
|
||||
int n;
|
||||
|
||||
n = inat_group_id(grp_attr);
|
||||
if (last_pfx) {
|
||||
lpfx_attr = inat_get_opcode_attribute(last_pfx);
|
||||
m = inat_last_prefix_id(lpfx_attr);
|
||||
}
|
||||
|
||||
table = inat_group_tables[n][0];
|
||||
if (!table)
|
||||
return inat_group_common_attribute(grp_attr);
|
||||
if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && m) {
|
||||
table = inat_group_tables[n][m];
|
||||
if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) {
|
||||
table = inat_group_tables[n][lpfx_id];
|
||||
if (!table)
|
||||
return inat_group_common_attribute(grp_attr);
|
||||
}
|
||||
|
Reference in New Issue
Block a user