Optimized alignment check

This commit is contained in:
Stanislav Shwartsman 2007-11-20 21:22:03 +00:00
parent 9e5d132793
commit 48650a70b4
9 changed files with 119 additions and 69 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: access.cc,v 1.78 2007-11-20 17:15:32 sshwarts Exp $
// $Id: access.cc,v 1.79 2007-11-20 21:22:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -570,9 +570,9 @@ accessOK:
BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 2, BX_WRITE);
pl = (CPL==3);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (pl && BX_CPU_THIS_PTR alignment_check) {
if (BX_CPU_THIS_PTR alignment_check) {
if (laddr & 1) {
BX_ERROR(("write_virtual_word(): misaligned access"));
BX_ERROR(("write_virtual_word(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -628,9 +628,9 @@ accessOK:
BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 4, BX_WRITE);
pl = (CPL==3);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (pl && BX_CPU_THIS_PTR alignment_check) {
if (BX_CPU_THIS_PTR alignment_check) {
if (laddr & 3) {
BX_ERROR(("write_virtual_dword(): misaligned access"));
BX_ERROR(("write_virtual_dword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -686,9 +686,9 @@ accessOK:
BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 8, BX_WRITE);
pl = (CPL==3);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (pl && BX_CPU_THIS_PTR alignment_check) {
if (BX_CPU_THIS_PTR alignment_check) {
if (laddr & 7) {
BX_ERROR(("write_virtual_qword(): misaligned access"));
BX_ERROR(("write_virtual_qword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -788,9 +788,9 @@ accessOK:
BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 2, BX_READ);
pl = (CPL==3);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (pl && BX_CPU_THIS_PTR alignment_check) {
if (BX_CPU_THIS_PTR alignment_check) {
if (laddr & 1) {
BX_ERROR(("read_virtual_word(): misaligned access"));
BX_ERROR(("read_virtual_word(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -842,9 +842,9 @@ accessOK:
BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 4, BX_READ);
pl = (CPL==3);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (pl && BX_CPU_THIS_PTR alignment_check) {
if (BX_CPU_THIS_PTR alignment_check) {
if (laddr & 3) {
BX_ERROR(("read_virtual_dword(): misaligned access"));
BX_ERROR(("read_virtual_dword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -896,9 +896,9 @@ accessOK:
BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 8, BX_READ);
pl = (CPL==3);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (pl && BX_CPU_THIS_PTR alignment_check) {
if (BX_CPU_THIS_PTR alignment_check) {
if (laddr & 7) {
BX_ERROR(("read_virtual_qword(): misaligned access"));
BX_ERROR(("read_virtual_qword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -1006,9 +1006,9 @@ accessOK:
BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 2, BX_RW);
pl = (CPL==3);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (pl && BX_CPU_THIS_PTR alignment_check) {
if (BX_CPU_THIS_PTR alignment_check) {
if (laddr & 1) {
BX_ERROR(("read_RMW_virtual_word(): misaligned access"));
BX_ERROR(("read_RMW_virtual_word(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -1065,9 +1065,9 @@ accessOK:
BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 4, BX_RW);
pl = (CPL==3);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (pl && BX_CPU_THIS_PTR alignment_check) {
if (BX_CPU_THIS_PTR alignment_check) {
if (laddr & 3) {
BX_ERROR(("read_RMW_virtual_dword(): misaligned access"));
BX_ERROR(("read_RMW_virtual_dword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -1124,9 +1124,9 @@ accessOK:
BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 8, BX_RW);
pl = (CPL==3);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (pl && BX_CPU_THIS_PTR alignment_check) {
if (BX_CPU_THIS_PTR alignment_check) {
if (laddr & 7) {
BX_ERROR(("read_RMW_virtual_qword(): misaligned access"));
BX_ERROR(("read_RMW_virtual_qword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -1393,7 +1393,7 @@ accessOK:
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (user && BX_CPU_THIS_PTR alignment_check) {
if (laddr & 1) {
BX_ERROR(("write_new_stack_word(): misaligned access"));
BX_ERROR(("write_new_stack_word(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -1428,7 +1428,7 @@ accessOK:
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (user && BX_CPU_THIS_PTR alignment_check) {
if (laddr & 3) {
BX_ERROR(("write_new_stack_dword(): misaligned access"));
BX_ERROR(("write_new_stack_dword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}
@ -1459,7 +1459,7 @@ void BX_CPU_C::write_new_stack_qword(bx_address offset, bx_bool user, Bit64u dat
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (user && BX_CPU_THIS_PTR alignment_check) {
if (laddr & 7) {
BX_ERROR(("write_new_stack_qword(): misaligned access"));
BX_ERROR(("write_new_stack_qword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
}
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.369 2007-11-20 17:15:33 sshwarts Exp $
// $Id: cpu.h,v 1.370 2007-11-20 21:22:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -3113,6 +3113,9 @@ public: // for now...
BX_SMF void reset(unsigned source);
BX_SMF void shutdown(void);
BX_SMF void handleCpuModeChange(void);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
BX_SMF void handleAlignmentCheck(void);
#endif
BX_SMF void jump_protected(bxInstruction_c *, Bit16u cs, bx_address disp) BX_CPP_AttrRegparmN(3);
BX_SMF void jmp_task_gate(bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(1);

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer_pro.cc,v 1.61 2007-11-17 18:08:46 sshwarts Exp $
// $Id: ctrl_xfer_pro.cc,v 1.62 2007-11-20 21:22:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -25,7 +25,6 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////
#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#include "cpu.h"
@ -36,7 +35,6 @@
#define RIP EIP
#endif
/* pass zero in check_rpl if no needed selector RPL checking for
non-conforming segments */
void BX_CPU_C::check_cs(bx_descriptor_t *descriptor, Bit16u cs_raw, Bit8u check_rpl, Bit8u check_cpl)
@ -124,6 +122,10 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck(); // CPL was modified
#endif
// Loading CS will invalidate the EIP fetch window.
invalidate_prefetch_q();
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: flag_ctrl_pro.cc,v 1.28 2007-11-19 19:55:09 sshwarts Exp $
// $Id: flag_ctrl_pro.cc,v 1.29 2007-11-20 21:22:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -42,10 +42,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::setEFlags(Bit32u val)
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (BX_CPU_THIS_PTR get_AC() && BX_CPU_THIS_PTR cr0.get_AM())
BX_CPU_THIS_PTR alignment_check = 1;
else
BX_CPU_THIS_PTR alignment_check = 0;
handleAlignmentCheck();
#endif
BX_CPU_THIS_PTR eflags.val32 = val;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.181 2007-11-18 18:40:38 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.182 2007-11-20 21:22:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1235,6 +1235,19 @@ void BX_CPU_C::handleCpuModeChange(void)
}
}
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
void BX_CPU_C::handleAlignmentCheck(void)
{
if (CPL == 3 && BX_CPU_THIS_PTR cr0.get_AM() && BX_CPU_THIS_PTR get_AC()) {
BX_CPU_THIS_PTR alignment_check = 1;
BX_INFO(("Enable alignment check (#AC exception)"));
}
else {
BX_CPU_THIS_PTR alignment_check = 0;
}
}
#endif
void BX_CPU_C::SetCR0(Bit32u val_32)
{
bx_bool pe = val_32 & 0x01;
@ -1260,7 +1273,33 @@ void BX_CPU_C::SetCR0(Bit32u val_32)
#if BX_SUPPORT_X86_64
bx_bool prev_pg = BX_CPU_THIS_PTR cr0.get_PG();
#endif
if (prev_pg==0 && pg) {
if (BX_CPU_THIS_PTR efer.lme) {
if (!BX_CPU_THIS_PTR cr4.get_PAE()) {
BX_ERROR(("SetCR0: attempt to enter x86-64 long mode without enabling CR4.PAE !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l) {
BX_ERROR(("SetCR0: attempt to enter x86-64 long mode with CS.L !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
BX_CPU_THIS_PTR efer.lma = 1;
}
}
else if (prev_pg==1 && ! pg) {
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
BX_ERROR(("SetCR0: attempt to leave 64 bit mode directly to legacy mode !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
if (BX_CPU_THIS_PTR efer.lma) {
if (BX_CPU_THIS_PTR eip_reg.dword.rip_upper != 0) {
BX_PANIC(("SetCR0: attempt to leave x86-64 LONG mode with RIP upper != 0 !!!"));
}
BX_CPU_THIS_PTR efer.lma = 0;
}
}
#endif // #if BX_SUPPORT_X86_64
// handle reserved bits behaviour
#if BX_CPU_LEVEL == 3
@ -1277,40 +1316,9 @@ void BX_CPU_C::SetCR0(Bit32u val_32)
BX_CPU_THIS_PTR cr0.val32 = val_32;
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (BX_CPU_THIS_PTR cr0.get_AM() && BX_CPU_THIS_PTR get_AC())
BX_CPU_THIS_PTR alignment_check = 1;
else
BX_CPU_THIS_PTR alignment_check = 0;
handleAlignmentCheck();
#endif
#if BX_SUPPORT_X86_64
if (prev_pg==0 && BX_CPU_THIS_PTR cr0.get_PG()) {
if (BX_CPU_THIS_PTR efer.lme) {
if (!BX_CPU_THIS_PTR cr4.get_PAE()) {
BX_ERROR(("SetCR0: attempt to enter x86-64 long mode without enabling CR4.PAE !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l) {
BX_ERROR(("SetCR0: attempt to enter x86-64 long mode with CS.L !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
BX_CPU_THIS_PTR efer.lma = 1;
}
}
else if (prev_pg==1 && ! BX_CPU_THIS_PTR cr0.get_PG()) {
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
BX_ERROR(("SetCR0: attempt to leave 64 bit mode directly to legacy mode !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
if (BX_CPU_THIS_PTR efer.lma) {
if (BX_CPU_THIS_PTR eip_reg.dword.rip_upper != 0) {
BX_PANIC(("SetCR0: attempt to leave x86-64 LONG mode with RIP upper != 0 !!!"));
}
BX_CPU_THIS_PTR efer.lma = 0;
}
}
#endif // #if BX_SUPPORT_X86_64
handleCpuModeChange();
// Give the paging unit a chance to look for changes in bits
@ -2042,6 +2050,10 @@ void BX_CPU_C::SYSENTER(bxInstruction_c *i)
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
BX_CPU_THIS_PTR alignment_check = 0; // CPL=0
#endif
parse_selector((BX_CPU_THIS_PTR msr.sysenter_cs_msr + 8) & BX_SELECTOR_RPL_MASK,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector);
@ -2102,6 +2114,10 @@ void BX_CPU_C::SYSEXIT(bxInstruction_c *i)
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck(); // CPL was modified
#endif
parse_selector((BX_CPU_THIS_PTR msr.sysenter_cs_msr + 24) | 3,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector);
@ -2171,6 +2187,10 @@ void BX_CPU_C::SYSCALL(bxInstruction_c *i)
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
BX_CPU_THIS_PTR alignment_check = 0; // CPL=0
#endif
// set up SS segment, flat, 64-bit DPL=0
parse_selector(((MSR_STAR >> 32) + 8) & BX_SELECTOR_RPL_MASK,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector);
@ -2219,6 +2239,10 @@ void BX_CPU_C::SYSCALL(bxInstruction_c *i)
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
BX_CPU_THIS_PTR alignment_check = 0; // CPL=0
#endif
// set up SS segment, flat, 32-bit DPL=0
parse_selector(((MSR_STAR >> 32) + 8) & BX_SELECTOR_RPL_MASK,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector);
@ -2307,6 +2331,10 @@ void BX_CPU_C::SYSRET(bxInstruction_c *i)
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck(); // CPL was modified
#endif
// SS base, limit, attributes unchanged
parse_selector((MSR_STAR >> 48) + 8,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector);
@ -2343,6 +2371,10 @@ void BX_CPU_C::SYSRET(bxInstruction_c *i)
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck(); // CPL was modified
#endif
// SS base, limit, attributes unchanged
parse_selector((MSR_STAR >> 48) + 8,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: segment_ctrl_pro.cc,v 1.74 2007-11-17 23:28:32 sshwarts Exp $
// $Id: segment_ctrl_pro.cc,v 1.75 2007-11-20 21:22:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -223,6 +223,9 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
seg->cache.type = BX_CODE_EXEC_READ_ACCESSED;
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck(); // CPL was modified
#endif
invalidate_prefetch_q();
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: smm.cc,v 1.27 2007-09-20 17:33:35 sshwarts Exp $
// $Id: smm.cc,v 1.28 2007-11-20 21:22:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006 Stanislav Shwartsman
@ -171,6 +171,10 @@ void BX_CPU_C::enter_system_management_mode(void)
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
BX_CPU_THIS_PTR alignment_check = 0;
#endif
/* DS (Data Segment) and descriptor cache */
parse_selector(0x0000,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: tasking.cc,v 1.40 2007-11-17 23:28:33 sshwarts Exp $
// $Id: tasking.cc,v 1.41 2007-11-20 21:22:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -602,6 +602,10 @@ void BX_CPU_C::task_switch(bx_selector_t *tss_selector,
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck(); // task switch, CPL was modified
#endif
// SS
if ( (raw_ss_selector & 0xfffc) != 0 )
{

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: vm8086.cc,v 1.30 2007-11-17 23:28:33 sshwarts Exp $
// $Id: vm8086.cc,v 1.31 2007-11-20 21:22:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -256,6 +256,11 @@ void BX_CPU_C::init_v8086_mode(void)
BX_CPU_THIS_PTR updateFetchModeMask();
#endif
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck(); // CPL was modified
#endif
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = 1;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = 3;