From cea169f5e7d382f520ebdab07c0779d66e795c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Jos=C3=A9=20G=C3=B3mez=20Hern=C3=A1ndez?= Date: Thu, 23 Nov 2023 09:52:41 +0100 Subject: [PATCH 1/2] arch-x86: Fix segment registers in instructions 8C and 8E MOV instructions 8C and 8E can be prefixed with a REX prefix to extend the source/destination register. However, the R bit in REX will be applied to the segment register. The decoder file checks for valid segment registers, checking the MODRM_REG only, however, later this will be extended with the REX_R when adding the register to the sources/destinations of the instruction. This will trigger an assert. This patch checks that the REX_R is not set, otherwise, UD2 will be generated. Change-Id: I78a93c35116232fe37e5ec50025e721b8c633c5f --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index ef596dfd71..13b05e62ff 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -287,25 +287,31 @@ 0x1: MOV(Ev,Gv); 0x2: MOV(Gb,Eb); 0x3: MOV(Gv,Ev); - 0x4: decode MODRM_REG { - 0x0, 0x1, 0x2, - 0x3, 0x4, 0x5: MOV(Ev,Sv); + 0x4: decode REX_R { + 0x0: decode MODRM_REG { + 0x0, 0x1, 0x2, + 0x3, 0x4, 0x5: MOV(Ev,Sv); + } + default: UD2(); } 0x5: LEA(Gv,M); - 0x6: decode MODE_SUBMODE { - 0x3, 0x4: decode MODRM_REG { - // Moving to the CS selector (0x1) is illegal, and 0x6 and - // 0x7 are reserved. - 0x1, 0x6, 0x7: UD2(); - default: MOV_REAL(Sv,Ev); - } - default: decode MODRM_REG { - // Moving to the CS selector (0x1) is illegal, and 0x6 and - // 0x7 are reserved. - 0x1, 0x6, 0x7: UD2(); - 0x2: MOVSS(Sv,Ev); - default: MOV(Sv,Ev); + 0x6: decode REX_R { + 0x0: decode MODE_SUBMODE { + 0x3, 0x4: decode MODRM_REG { + // Moving to the CS selector (0x1) is illegal, and 0x6 and + // 0x7 are reserved. + 0x1, 0x6, 0x7: UD2(); + default: MOV_REAL(Sv,Ev); + } + default: decode MODRM_REG { + // Moving to the CS selector (0x1) is illegal, and 0x6 and + // 0x7 are reserved. + 0x1, 0x6, 0x7: UD2(); + 0x2: MOVSS(Sv,Ev); + default: MOV(Sv,Ev); + } } + default: UD2(); } //0x7: group10_Ev(); 0x7: decode MODRM_REG { From 670bf6a488a12a61840655644d4c0baf4377ecf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Jos=C3=A9=20G=C3=B3mez=20Hern=C3=A1ndez?= Date: Fri, 24 Nov 2023 13:33:38 +0100 Subject: [PATCH 2/2] arch-x86: Check REX_R for MOV misc registers Change-Id: I08ea37ffe695df500ea84cbddd94be246f916caf --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index dac5706a06..48c3a2d20d 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -287,24 +287,27 @@ 0x6: HINT_NOP(); 0x7: HINT_NOP(); } - 0x04: decode LEGACY_DECODEVAL { - // no prefix - 0x0: decode OPCODE_OP_BOTTOM3 { - 0x0: Cpl0CondInst::MOV( - {{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Rd,Cd); - 0x1: Cpl0CondInst::MOV({{MODRM_REG < 8}},Rd,Dd); - 0x2: Cpl0CondInst::MOV( - {{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Cd,Rd); - 0x3: Cpl0CondInst::MOV({{MODRM_REG < 8}},Dd,Rd); + 0x04: decode REX_R { + 0x0: decode LEGACY_DECODEVAL { + // no prefix + 0x0: decode OPCODE_OP_BOTTOM3 { + 0x6: Cpl0CondInst::MOV( + {{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Rd,Cd); + 0x1: Cpl0CondInst::MOV({{MODRM_REG < 8}},Rd,Dd); + 0x2: Cpl0CondInst::MOV( + {{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Cd,Rd); + 0x3: Cpl0CondInst::MOV({{MODRM_REG < 8}},Dd,Rd); + default: UD2(); + } + // operand size (0x66) + 0x1: decode OPCODE_OP_BOTTOM3 { + 0x0: Cpl0CondInst::MOV( + {{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Rd,Cd); + 0x2: Cpl0CondInst::MOV( + {{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Cd,Rd); + } default: UD2(); } - // operand size (0x66) - 0x1: decode OPCODE_OP_BOTTOM3 { - 0x0: Cpl0CondInst::MOV( - {{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Rd,Cd); - 0x2: Cpl0CondInst::MOV( - {{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Cd,Rd); - } default: UD2(); } 0x05: decode LEGACY_DECODEVAL {