[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v10 10/10] test_x86_emulator.c: Add tests for #GP usage
Test out special #GP handling for the VMware port 0x5658. This is done in two "modes", j=0 and j=1. Testing 4 instructions (all the basic PIO) in both modes. The port used is based on j. For IN, eax should change. For OUT eax should not change. All 4 PIO instructions are 1 byte long, so eip should only change by 1. Signed-off-by: Don Slutz <dslutz@xxxxxxxxxxx> --- v10: More comments and simpler error checking. Dropped un-needed new routines. tools/tests/x86_emulator/test_x86_emulator.c | 189 +++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c index 1b78bf7..a509dad 100644 --- a/tools/tests/x86_emulator/test_x86_emulator.c +++ b/tools/tests/x86_emulator/test_x86_emulator.c @@ -154,6 +154,47 @@ int get_fpu( return X86EMUL_OKAY; } +static int read_io( + unsigned int port, + unsigned int bytes, + unsigned long *val, + struct x86_emulate_ctxt *ctxt) +{ + *val = 0xffffffff; + if ( port == 0x5658 ) + { + ctxt->regs->_ebx++; + ctxt->regs->_ecx++; + ctxt->regs->_esi++; + } + return X86EMUL_OKAY; +} + +static int write_io( + unsigned int port, + unsigned int bytes, + unsigned long val, + struct x86_emulate_ctxt *ctxt) +{ + if ( port == 0x5658 ) + { + ctxt->regs->_ebx++; + ctxt->regs->_ecx++; + ctxt->regs->_esi++; + } + return X86EMUL_OKAY; +} + +static int vmport_check( + unsigned int first_port, + struct x86_emulate_ctxt *ctxt) +{ + if ( first_port == 0x5658 ) + return 0; + else + return 1; +} + static struct x86_emulate_ops emulops = { .read = read, .insn_fetch = fetch, @@ -163,6 +204,13 @@ static struct x86_emulate_ops emulops = { .get_fpu = get_fpu, }; +static struct x86_emulate_ops emulops_gp = { + .insn_fetch = fetch, + .read_io = read_io, + .write_io = write_io, + .vmport_check = vmport_check, +}; + int main(int argc, char **argv) { struct x86_emulate_ctxt ctxt; @@ -928,6 +976,147 @@ int main(int argc, char **argv) goto fail; printf("okay\n"); + /* + * Test out special #GP handling for the VMware port 0x5658. + * This is done in two "modes", j=0 and j=1. Testing 4 + * instructions (all the basic PIO) in both modes. + * + * The port used is based on j. + * + * For IN, eax should change. For OUT eax should not change. + * + * All 4 PIO instructions are 1 byte long, so eip should only + * change by 1. + */ + for ( j = 0; j <= 1; j++ ) + { + regs.eflags = 0x20002; + regs.edx = 0x5658 + j; + printf("Testing %s dx=%x ... ", "in (%dx),%eax", (int)regs.edx); + instr[0] = 0xed; /* in (%dx),%eax or in (%dx),%ax */ + regs.eip = (unsigned long)&instr[0]; + regs.eax = 0x12345678; + regs.ebx = 0; + regs.ecx = 0; + regs.esi = 0; + rc = x86_emulate(&ctxt, &emulops_gp); + /* + * In j=0, there should not be an error returned. + * In j=1, there should be an error returned. + */ + if ( rc == X86EMUL_OKAY ? j : !j ) + goto fail; + /* Check for only 1 byte used or 0 if #GP. */ + if ( regs.eip != (unsigned long)&instr[1 - j] ) + goto fail; + /* Check that eax changed in the non #GP case */ + if ( j == 0 && regs.eax == 0x12345678 ) + goto fail; + /* Check that ebx has the correct value */ + if ( regs.ebx == j ) + goto fail; + /* Check that ecx has the correct value */ + if ( regs.ecx == j ) + goto fail; + /* Check that esi has the correct value */ + if ( regs.esi == j ) + goto fail; + printf("okay\n"); + + printf("Testing %s dx=%x ... ", "in (%dx),%al", (int)regs.edx); + instr[0] = 0xec; /* in (%dx),%al */ + regs.eip = (unsigned long)&instr[0]; + regs.eax = 0x12345678; + regs.ebx = 0; + regs.ecx = 0; + regs.esi = 0; + rc = x86_emulate(&ctxt, &emulops_gp); + /* + * In j=0, there should not be an error returned. + * In j=1, there should be an error returned. + */ + if ( rc == X86EMUL_OKAY ? j : !j ) + goto fail; + /* Check for only 1 byte used or 0 if #GP. */ + if ( regs.eip != (unsigned long)&instr[1 - j] ) + goto fail; + /* Check that eax changed in the non #GP case */ + if ( j == 0 && regs.eax == 0x12345678 ) + goto fail; + /* Check that ebx has the correct value */ + if ( regs.ebx == j ) + goto fail; + /* Check that ecx has the correct value */ + if ( regs.ecx == j ) + goto fail; + /* Check that esi has the correct value */ + if ( regs.esi == j ) + goto fail; + printf("okay\n"); + + printf("Testing %s dx=%x ... ", "out %eax,(%dx)", (int)regs.edx); + instr[0] = 0xef; /* out %eax,(%dx) or out %ax,(%dx) */ + regs.eip = (unsigned long)&instr[0]; + regs.eax = 0x12345678; + regs.ebx = 0; + regs.ecx = 0; + regs.esi = 0; + rc = x86_emulate(&ctxt, &emulops_gp); + /* + * In j=0, there should not be an error returned. + * In j=1, there should be an error returned. + */ + if ( rc == X86EMUL_OKAY ? j : !j ) + goto fail; + /* Check for only 1 byte used or 0 if #GP. */ + if ( regs.eip != (unsigned long)&instr[1 - j] ) + goto fail; + /* Check that eax did not change */ + if ( regs.eax != 0x12345678 ) + goto fail; + /* Check that ebx has the correct value */ + if ( regs.ebx == j ) + goto fail; + /* Check that ecx has the correct value */ + if ( regs.ecx == j ) + goto fail; + /* Check that esi has the correct value */ + if ( regs.esi == j ) + goto fail; + printf("okay\n"); + + printf("Testing %s dx=%x ... ", "out %al,(%dx)", (int)regs.edx); + instr[0] = 0xee; /* out %al,(%dx) */ + regs.eip = (unsigned long)&instr[0]; + regs.eax = 0x12345678; + regs.ebx = 0; + regs.ecx = 0; + regs.esi = 0; + rc = x86_emulate(&ctxt, &emulops_gp); + /* + * In j=0, there should not be an error returned. + * In j=1, there should be an error returned. + */ + if ( rc == X86EMUL_OKAY ? j : !j ) + goto fail; + /* Check for only 1 byte used or 0 if #GP. */ + if ( regs.eip != (unsigned long)&instr[1 - j] ) + goto fail; + /* Check that eax did not change */ + if ( regs.eax != 0x12345678 ) + goto fail; + /* Check that ebx has the correct value */ + if ( regs.ebx == j ) + goto fail; + /* Check that ecx has the correct value */ + if ( regs.ecx == j ) + goto fail; + /* Check that esi has the correct value */ + if ( regs.esi == j ) + goto fail; + printf("okay\n"); + } + return 0; fail: -- 1.8.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |