Re: [Xen-devel] [PATCH] x86emul: fix 3-operand IMUL

2018-12-18 Thread Andrew Cooper
On 18/12/2018 11:29, Jan Beulich wrote:
> While commit 75066cd4ea ("x86emul: fix {,i}mul and {,i}div") indeed did
> as its title says, it broke the 3-operand form by uniformly using AL/AX/
> EAX/RAX as second source operand. Fix this and add tests covering both
> cases.
>
> Reported-by: Andrei Lutas 
> Signed-off-by: Jan Beulich 

Reviewed-by: Andrew Cooper 

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH] x86emul: fix 3-operand IMUL

2018-12-18 Thread Razvan Cojocaru
On 12/18/18 1:29 PM, Jan Beulich wrote:
> While commit 75066cd4ea ("x86emul: fix {,i}mul and {,i}div") indeed did
> as its title says, it broke the 3-operand form by uniformly using AL/AX/
> EAX/RAX as second source operand. Fix this and add tests covering both
> cases.
> 
> Reported-by: Andrei Lutas 
> Signed-off-by: Jan Beulich 

Tested-by: Razvan Cojocaru 


Thank you,
Razvan

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH] x86emul: fix 3-operand IMUL

2018-12-18 Thread Jan Beulich
While commit 75066cd4ea ("x86emul: fix {,i}mul and {,i}div") indeed did
as its title says, it broke the 3-operand form by uniformly using AL/AX/
EAX/RAX as second source operand. Fix this and add tests covering both
cases.

Reported-by: Andrei Lutas 
Signed-off-by: Jan Beulich 

--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -890,6 +890,42 @@ int main(int argc, char **argv)
 goto fail;
 printf("okay\n");
 
+printf("%-40s", "Testing imull -4(%ecx)...");
+instr[0] = 0xf7; instr[1] = 0x69; instr[2] = 0xfc;
+regs.eflags = EFLAGS_ALWAYS_SET;
+regs.eip= (unsigned long)[0];
+regs.eax= 0x89abcdef;
+res[0]  = 0x12345678;
+regs.ecx= (unsigned long)(res + 1);
+rc = x86_emulate(, );
+if ( (rc != X86EMUL_OKAY) ||
+ (regs.eax != 0x89abcdef * 0x12345678) ||
+ (regs.edx != (uint64_t)((int64_t)(int32_t)0x89abcdef *
+ 0x12345678) >> 32) ||
+ ((regs.eflags & (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF |
+  X86_EFLAGS_OF)) !=
+  (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF | X86_EFLAGS_OF)) ||
+ (regs.eip != (unsigned long)[3]) )
+goto fail;
+printf("okay\n");
+
+printf("%-40s", "Testing imul $3,-4(%edx),%ecx...");
+instr[0] = 0x6b; instr[1] = 0x4a; instr[2] = 0xfc; instr[3] = 0x03;
+regs.eflags = EFLAGS_ALWAYS_SET;
+regs.eip= (unsigned long)[0];
+regs.ecx= 0x12345678;
+res[0]  = 0x89abcdef;
+regs.edx= (unsigned long)(res + 1);
+rc = x86_emulate(, );
+if ( (rc != X86EMUL_OKAY) ||
+ (regs.ecx != 0x89abcdef * 3) ||
+ ((regs.eflags & (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF |
+  X86_EFLAGS_OF)) !=
+  (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF | X86_EFLAGS_OF)) ||
+ (regs.eip != (unsigned long)[4]) )
+goto fail;
+printf("okay\n");
+
 #ifndef __x86_64__
 printf("%-40s", "Testing daa/das (all inputs)...");
 /* Bits 0-7: AL; Bit 8: EFLAGS.AF; Bit 9: EFLAGS.CF; Bit 10: DAA vs. DAS. 
*/
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -5055,12 +5055,13 @@ x86_emulate(
 }
 break;
 case 5: /* imul */
+dst.val = _regs.r(ax);
 imul:
 _regs.eflags &= ~(X86_EFLAGS_OF | X86_EFLAGS_CF);
 switch ( dst.bytes )
 {
 case 1:
-dst.val = (int8_t)src.val * (int8_t)_regs.al;
+dst.val = (int8_t)src.val * (int8_t)dst.val;
 if ( (int8_t)dst.val != (int16_t)dst.val )
 _regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF;
 ASSERT(b > 0x6b);
@@ -5068,7 +5069,7 @@ x86_emulate(
 break;
 case 2:
 dst.val = ((uint32_t)(int16_t)src.val *
-   (uint32_t)(int16_t)_regs.ax);
+   (uint32_t)(int16_t)dst.val);
 if ( (int16_t)dst.val != (int32_t)dst.val )
 _regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF;
 if ( b > 0x6b )
@@ -5077,7 +5078,7 @@ x86_emulate(
 #ifdef __x86_64__
 case 4:
 dst.val = ((uint64_t)(int32_t)src.val *
-   (uint64_t)(int32_t)_regs.eax);
+   (uint64_t)(int32_t)dst.val);
 if ( (int32_t)dst.val != dst.val )
 _regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF;
 if ( b > 0x6b )
@@ -5086,7 +5087,7 @@ x86_emulate(
 #endif
 default:
 u[0] = src.val;
-u[1] = _regs.r(ax);
+u[1] = dst.val;
 if ( imul_dbl(u) )
 _regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF;
 if ( b > 0x6b )





___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel