From 2b4fa16c4af51f06e09d5a6a35a48e0ec5027af9 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Fri, 23 May 2008 13:46:52 +0000 Subject: [PATCH] Fixed EFLAGS update in IRET --- bochs/cpu/iret.cc | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/bochs/cpu/iret.cc b/bochs/cpu/iret.cc index c32f42800..4b251ce81 100755 --- a/bochs/cpu/iret.cc +++ b/bochs/cpu/iret.cc @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////// -// $Id: iret.cc,v 1.36 2008-05-20 22:15:16 sshwarts Exp $ +// $Id: iret.cc,v 1.37 2008-05-23 13:46:52 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2005 Stanislav Shwartsman @@ -289,27 +289,25 @@ BX_CPU_C::iret_protected(bxInstruction_c *i) new_eip = read_virtual_word(BX_SEG_REG_SS, temp_ESP + 0); } - Bit8u prev_cpl = CPL; /* previous CPL */ - - /* load CS:EIP from stack */ - /* load the CS-cache with CS descriptor */ - /* set CPL to the RPL of the return CS selector */ - branch_far32(&cs_selector, &cs_descriptor, new_eip, cs_selector.rpl); - // ID,VIP,VIF,AC,VM,RF,x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF Bit32u changeMask = EFlagsOSZAPCMask | EFlagsTFMask | EFlagsDFMask | EFlagsNTMask | EFlagsRFMask; #if BX_CPU_LEVEL >= 4 changeMask |= (EFlagsIDMask | EFlagsACMask); // ID/AC #endif - if (prev_cpl <= BX_CPU_THIS_PTR get_IOPL()) + if (CPL <= BX_CPU_THIS_PTR get_IOPL()) changeMask |= EFlagsIFMask; - if (prev_cpl == 0) + if (CPL == 0) changeMask |= EFlagsVIPMask | EFlagsVIFMask | EFlagsIOPLMask; - if (! cs_descriptor.u.segment.d_b) // 16 bit + if (! i->os32L()) // 16 bit changeMask &= 0xffff; + /* load CS:EIP from stack */ + /* load the CS-cache with CS descriptor */ + /* set CPL to the RPL of the return CS selector */ + branch_far32(&cs_selector, &cs_descriptor, new_eip, cs_selector.rpl); + // IF only changed if (prev_CPL <= EFLAGS.IOPL) // VIF, VIP, IOPL only changed if prev_CPL == 0 // VM unaffected @@ -428,6 +426,9 @@ BX_CPU_C::long_iret(bxInstruction_c *i) if (CPL == 0) changeMask |= EFlagsVIPMask | EFlagsVIFMask | EFlagsIOPLMask; + if (! i->os32L()) // 16 bit + changeMask &= 0xffff; + // IF only changed if (CPL <= EFLAGS.IOPL) // VIF, VIP, IOPL only changed if CPL == 0 // VM unaffected @@ -515,9 +516,6 @@ BX_CPU_C::long_iret(bxInstruction_c *i) Bit8u prev_cpl = CPL; /* previous CPL */ - /* set CPL to the RPL of the return CS selector */ - branch_far64(&cs_selector, &cs_descriptor, new_rip, cs_selector.rpl); - // ID,VIP,VIF,AC,VM,RF,x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF Bit32u changeMask = EFlagsOSZAPCMask | EFlagsTFMask | EFlagsDFMask | EFlagsNTMask | EFlagsRFMask | EFlagsIDMask | EFlagsACMask; @@ -526,9 +524,12 @@ BX_CPU_C::long_iret(bxInstruction_c *i) if (prev_cpl == 0) changeMask |= EFlagsVIPMask | EFlagsVIFMask | EFlagsIOPLMask; - if (! cs_descriptor.u.segment.d_b) // 16 bit + if (! i->os32L()) // 16 bit changeMask &= 0xffff; + /* set CPL to the RPL of the return CS selector */ + branch_far64(&cs_selector, &cs_descriptor, new_rip, cs_selector.rpl); + // IF only changed if (prev_CPL <= EFLAGS.IOPL) // VIF, VIP, IOPL only changed if prev_CPL == 0 // VM unaffected