move canonical check of high part of page split access to another function to fix code duplication
This commit is contained in:
parent
543b6c8254
commit
776cabf4fe
@ -314,13 +314,15 @@ BX_CPU_C::system_read_word(bx_address laddr)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (! IsCanonical(laddr) || ! IsCanonical(laddr+1)) {
|
||||
if (! IsCanonical(laddr)) {
|
||||
BX_ERROR(("system_read_word(): canonical failure"));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
access_read_linear(laddr, 2, 0, BX_READ, (void *) &data);
|
||||
if (access_read_linear(laddr, 2, 0, BX_READ, (void *) &data) < 0)
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -346,13 +348,15 @@ BX_CPU_C::system_read_dword(bx_address laddr)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (! IsCanonical(laddr) || ! IsCanonical(laddr+3)) {
|
||||
if (! IsCanonical(laddr)) {
|
||||
BX_ERROR(("system_read_dword(): canonical failure"));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
access_read_linear(laddr, 4, 0, BX_READ, (void *) &data);
|
||||
if (access_read_linear(laddr, 4, 0, BX_READ, (void *) &data) < 0)
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -378,13 +382,15 @@ BX_CPU_C::system_read_qword(bx_address laddr)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (! IsCanonical(laddr) || ! IsCanonical(laddr+7)) {
|
||||
if (! IsCanonical(laddr)) {
|
||||
BX_ERROR(("system_read_qword(): canonical failure"));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
access_read_linear(laddr, 8, 0, BX_READ, (void *) &data);
|
||||
if (access_read_linear(laddr, 8, 0, BX_READ, (void *) &data) < 0)
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -441,13 +447,14 @@ BX_CPU_C::system_write_word(bx_address laddr, Bit16u data)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (! IsCanonical(laddr) || ! IsCanonical(laddr+1)) {
|
||||
if (! IsCanonical(laddr)) {
|
||||
BX_ERROR(("system_write_word(): canonical failure"));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
access_write_linear(laddr, 2, 0, (void *) &data);
|
||||
if (access_write_linear(laddr, 2, 0, (void *) &data) < 0)
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
@ -472,13 +479,14 @@ BX_CPU_C::system_write_dword(bx_address laddr, Bit32u data)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (! IsCanonical(laddr) || ! IsCanonical(laddr+3)) {
|
||||
if (! IsCanonical(laddr)) {
|
||||
BX_ERROR(("system_write_dword(): canonical failure"));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
access_write_linear(laddr, 4, 0, (void *) &data);
|
||||
if (access_write_linear(laddr, 4, 0, (void *) &data) < 0)
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
Bit8u* BX_CPP_AttrRegparmN(2)
|
||||
|
@ -102,12 +102,8 @@ BX_CPU_C::write_virtual_word_64(unsigned s, Bit64u offset, Bit16u data)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+1)) {
|
||||
BX_ERROR(("write_virtual_word_64(): canonical failure"));
|
||||
if (access_write_linear(laddr, 2, CPL, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_write_linear(laddr, 2, CPL, (void *) &data);
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
@ -152,12 +148,8 @@ BX_CPU_C::write_virtual_dword_64(unsigned s, Bit64u offset, Bit32u data)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+3)) {
|
||||
BX_ERROR(("write_virtual_dword_64(): canonical failure"));
|
||||
if (access_write_linear(laddr, 4, CPL, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_write_linear(laddr, 4, CPL, (void *) &data);
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
@ -202,12 +194,8 @@ BX_CPU_C::write_virtual_qword_64(unsigned s, Bit64u offset, Bit64u data)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+7)) {
|
||||
BX_ERROR(("write_virtual_qword_64(): canonical failure"));
|
||||
if (access_write_linear(laddr, 8, CPL, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_write_linear(laddr, 8, CPL, (void *) &data);
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
@ -235,12 +223,13 @@ BX_CPU_C::write_virtual_xmmword_64(unsigned s, Bit64u offset, const BxPackedXmmR
|
||||
}
|
||||
}
|
||||
|
||||
if (! IsCanonical(laddr) || ! IsCanonical(laddr+15)) {
|
||||
if (! IsCanonical(laddr)) {
|
||||
BX_ERROR(("write_virtual_xmmword_64(): canonical failure"));
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_write_linear(laddr, 16, CPL, (void *) data);
|
||||
if (access_write_linear(laddr, 16, CPL, (void *) data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
@ -308,12 +297,13 @@ void BX_CPU_C::write_virtual_ymmword_64(unsigned s, Bit64u offset, const BxPacke
|
||||
}
|
||||
}
|
||||
|
||||
if (! IsCanonical(laddr) || ! IsCanonical(laddr+31)) {
|
||||
if (! IsCanonical(laddr)) {
|
||||
BX_ERROR(("write_virtual_ymmword_64(): canonical failure"));
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_write_linear(laddr, 32, CPL, (void *) data);
|
||||
if (access_write_linear(laddr, 32, CPL, (void *) data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
void BX_CPU_C::write_virtual_ymmword_aligned_64(unsigned s, Bit64u offset, const BxPackedYmmRegister *data)
|
||||
@ -388,7 +378,8 @@ void BX_CPU_C::write_virtual_zmmword_64(unsigned s, Bit64u offset, const BxPacke
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_write_linear(laddr, 64, CPL, (void *) data);
|
||||
if (access_write_linear(laddr, 64, CPL, (void *) data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
void BX_CPU_C::write_virtual_zmmword_aligned_64(unsigned s, Bit64u offset, const BxPackedZmmRegister *data)
|
||||
@ -504,12 +495,9 @@ BX_CPU_C::read_virtual_word_64(unsigned s, Bit64u offset)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+1)) {
|
||||
BX_ERROR(("read_virtual_word_64(): canonical failure"));
|
||||
if (access_read_linear(laddr, 2, CPL, BX_READ, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_read_linear(laddr, 2, CPL, BX_READ, (void *) &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -554,12 +542,9 @@ BX_CPU_C::read_virtual_dword_64(unsigned s, Bit64u offset)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+3)) {
|
||||
BX_ERROR(("read_virtual_dword_64(): canonical failure"));
|
||||
if (access_read_linear(laddr, 4, CPL, BX_READ, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_read_linear(laddr, 4, CPL, BX_READ, (void *) &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -604,12 +589,9 @@ BX_CPU_C::read_virtual_qword_64(unsigned s, Bit64u offset)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+7)) {
|
||||
BX_ERROR(("read_virtual_qword_64(): canonical failure"));
|
||||
if (access_read_linear(laddr, 8, CPL, BX_READ, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_read_linear(laddr, 8, CPL, BX_READ, (void *) &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -636,12 +618,13 @@ BX_CPU_C::read_virtual_xmmword_64(unsigned s, Bit64u offset, BxPackedXmmRegister
|
||||
}
|
||||
}
|
||||
|
||||
if (! IsCanonical(laddr) || ! IsCanonical(laddr+15)) {
|
||||
if (! IsCanonical(laddr)) {
|
||||
BX_ERROR(("read_virtual_xmmword_64(): canonical failure"));
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_read_linear(laddr, 16, CPL, BX_READ, (void *) data);
|
||||
if (access_read_linear(laddr, 16, CPL, BX_READ, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
@ -705,12 +688,13 @@ void BX_CPU_C::read_virtual_ymmword_64(unsigned s, Bit64u offset, BxPackedYmmReg
|
||||
}
|
||||
}
|
||||
|
||||
if (! IsCanonical(laddr) || ! IsCanonical(laddr+31)) {
|
||||
if (! IsCanonical(laddr)) {
|
||||
BX_ERROR(("read_virtual_ymmword_64(): canonical failure"));
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_read_linear(laddr, 32, CPL, BX_READ, (void *) data);
|
||||
if (access_read_linear(laddr, 32, CPL, BX_READ, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
void BX_CPU_C::read_virtual_ymmword_aligned_64(unsigned s, Bit64u offset, BxPackedYmmRegister *data)
|
||||
@ -776,12 +760,13 @@ void BX_CPU_C::read_virtual_zmmword_64(unsigned s, Bit64u offset, BxPackedZmmReg
|
||||
}
|
||||
}
|
||||
|
||||
if (! IsCanonical(laddr) || ! IsCanonical(laddr+63)) {
|
||||
if (! IsCanonical(laddr)) {
|
||||
BX_ERROR(("read_virtual_ymmword_64(): canonical failure"));
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_read_linear(laddr, 64, CPL, BX_READ, (void *) data);
|
||||
if (access_read_linear(laddr, 64, CPL, BX_READ, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
void BX_CPU_C::read_virtual_zmmword_aligned_64(unsigned s, Bit64u offset, BxPackedZmmRegister *data)
|
||||
@ -908,12 +893,9 @@ BX_CPU_C::read_RMW_virtual_word_64(unsigned s, Bit64u offset)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+1)) {
|
||||
BX_ERROR(("read_RMW_virtual_word_64(): canonical failure"));
|
||||
if (access_read_linear(laddr, 2, CPL, BX_RW, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_read_linear(laddr, 2, CPL, BX_RW, (void *) &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -962,12 +944,9 @@ BX_CPU_C::read_RMW_virtual_dword_64(unsigned s, Bit64u offset)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+3)) {
|
||||
BX_ERROR(("read_RMW_virtual_dword_64(): canonical failure"));
|
||||
if (access_read_linear(laddr, 4, CPL, BX_RW, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_read_linear(laddr, 4, CPL, BX_RW, (void *) &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -1016,12 +995,9 @@ BX_CPU_C::read_RMW_virtual_qword_64(unsigned s, Bit64u offset)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+7)) {
|
||||
BX_ERROR(("read_RMW_virtual_qword_64(): canonical failure"));
|
||||
if (access_read_linear(laddr, 8, CPL, BX_RW, (void *) &data) < 0)
|
||||
exception(int_number(s), 0);
|
||||
}
|
||||
|
||||
access_read_linear(laddr, 8, CPL, BX_RW, (void *) &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -1121,12 +1097,8 @@ void BX_CPU_C::write_new_stack_word_64(Bit64u laddr, unsigned curr_pl, Bit16u da
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+1)) {
|
||||
BX_ERROR(("write_new_stack_word_64(): canonical failure"));
|
||||
if (access_write_linear(laddr, 2, curr_pl, (void *) &data) < 0)
|
||||
exception(BX_SS_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
access_write_linear(laddr, 2, curr_pl, (void *) &data);
|
||||
}
|
||||
|
||||
void BX_CPU_C::write_new_stack_dword_64(Bit64u laddr, unsigned curr_pl, Bit32u data)
|
||||
@ -1168,12 +1140,8 @@ void BX_CPU_C::write_new_stack_dword_64(Bit64u laddr, unsigned curr_pl, Bit32u d
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+3)) {
|
||||
BX_ERROR(("write_new_stack_dword_64(): canonical failure"));
|
||||
if (access_write_linear(laddr, 4, curr_pl, (void *) &data) < 0)
|
||||
exception(BX_SS_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
access_write_linear(laddr, 4, curr_pl, (void *) &data);
|
||||
}
|
||||
|
||||
void BX_CPU_C::write_new_stack_qword_64(Bit64u laddr, unsigned curr_pl, Bit64u data)
|
||||
@ -1215,12 +1183,8 @@ void BX_CPU_C::write_new_stack_qword_64(Bit64u laddr, unsigned curr_pl, Bit64u d
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! IsCanonical(laddr+7)) {
|
||||
BX_ERROR(("write_new_stack_qword_64(): canonical failure"));
|
||||
if (access_write_linear(laddr, 8, curr_pl, (void *) &data) < 0)
|
||||
exception(BX_SS_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
access_write_linear(laddr, 8, curr_pl, (void *) &data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -4352,9 +4352,9 @@ public: // for now...
|
||||
BX_SMF void repeat_ZF(bxInstruction_c *i, BxRepIterationPtr_tR execute) BX_CPP_AttrRegparmN(2);
|
||||
|
||||
// linear address for access_linear expected to be canonical !
|
||||
BX_SMF void access_read_linear(bx_address laddr, unsigned len, unsigned curr_pl,
|
||||
BX_SMF int access_read_linear(bx_address laddr, unsigned len, unsigned curr_pl,
|
||||
unsigned rw, void *data);
|
||||
BX_SMF void access_write_linear(bx_address laddr, unsigned len, unsigned curr_pl,
|
||||
BX_SMF int access_write_linear(bx_address laddr, unsigned len, unsigned curr_pl,
|
||||
void *data);
|
||||
BX_SMF void page_fault(unsigned fault, bx_address laddr, unsigned user, unsigned rw);
|
||||
|
||||
|
@ -1901,7 +1901,7 @@ page_fault:
|
||||
}
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::access_write_linear(bx_address laddr, unsigned len, unsigned curr_pl, void *data)
|
||||
int BX_CPU_C::access_write_linear(bx_address laddr, unsigned len, unsigned curr_pl, void *data)
|
||||
{
|
||||
Bit32u pageOffset = PAGE_OFFSET(laddr);
|
||||
|
||||
@ -1924,14 +1924,21 @@ void BX_CPU_C::access_write_linear(bx_address laddr, unsigned len, unsigned curr
|
||||
}
|
||||
else {
|
||||
// access across 2 pages
|
||||
BX_CPU_THIS_PTR address_xlation.paddress1 = translate_linear(tlbEntry, laddr, (curr_pl == 3), BX_WRITE);
|
||||
BX_CPU_THIS_PTR address_xlation.len1 = 4096 - pageOffset;
|
||||
BX_CPU_THIS_PTR address_xlation.len2 = len - BX_CPU_THIS_PTR address_xlation.len1;
|
||||
BX_CPU_THIS_PTR address_xlation.pages = 2;
|
||||
bx_address laddr2 = laddr + BX_CPU_THIS_PTR address_xlation.len1;
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (! long64_mode()) laddr2 &= 0xffffffff; /* handle linear address wrap in legacy mode */
|
||||
else {
|
||||
if (! IsCanonical(laddr2)) {
|
||||
BX_ERROR(("access_write_linear(): canonical failure for second half of page split access"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BX_CPU_THIS_PTR address_xlation.paddress1 = translate_linear(tlbEntry, laddr, (curr_pl == 3), BX_WRITE);
|
||||
BX_CPU_THIS_PTR address_xlation.paddress2 = translate_linear(BX_TLB_ENTRY_OF(laddr2), laddr2, (curr_pl == 3), BX_WRITE);
|
||||
|
||||
#ifdef BX_LITTLE_ENDIAN
|
||||
@ -1965,9 +1972,11 @@ void BX_CPU_C::access_write_linear(bx_address laddr, unsigned len, unsigned curr
|
||||
hwbreakpoint_match(laddr2, BX_CPU_THIS_PTR address_xlation.len2, BX_WRITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BX_CPU_C::access_read_linear(bx_address laddr, unsigned len, unsigned curr_pl, unsigned xlate_rw, void *data)
|
||||
int BX_CPU_C::access_read_linear(bx_address laddr, unsigned len, unsigned curr_pl, unsigned xlate_rw, void *data)
|
||||
{
|
||||
BX_ASSERT(xlate_rw == BX_READ || xlate_rw == BX_RW);
|
||||
|
||||
@ -1989,14 +1998,20 @@ void BX_CPU_C::access_read_linear(bx_address laddr, unsigned len, unsigned curr_
|
||||
}
|
||||
else {
|
||||
// access across 2 pages
|
||||
BX_CPU_THIS_PTR address_xlation.paddress1 = translate_linear(tlbEntry, laddr, (curr_pl == 3), xlate_rw);
|
||||
BX_CPU_THIS_PTR address_xlation.len1 = 4096 - pageOffset;
|
||||
BX_CPU_THIS_PTR address_xlation.len2 = len - BX_CPU_THIS_PTR address_xlation.len1;
|
||||
BX_CPU_THIS_PTR address_xlation.pages = 2;
|
||||
bx_address laddr2 = laddr + BX_CPU_THIS_PTR address_xlation.len1;
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (! long64_mode()) laddr2 &= 0xffffffff; /* handle linear address wrap in legacy mode */
|
||||
else {
|
||||
if (! IsCanonical(laddr2)) {
|
||||
BX_ERROR(("access_read_linear(): canonical failure for second half of page split access"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
BX_CPU_THIS_PTR address_xlation.paddress1 = translate_linear(tlbEntry, laddr, (curr_pl == 3), xlate_rw);
|
||||
BX_CPU_THIS_PTR address_xlation.paddress2 = translate_linear(BX_TLB_ENTRY_OF(laddr2), laddr2, (curr_pl == 3), xlate_rw);
|
||||
|
||||
#ifdef BX_LITTLE_ENDIAN
|
||||
@ -2030,6 +2045,8 @@ void BX_CPU_C::access_read_linear(bx_address laddr, unsigned len, unsigned curr_
|
||||
hwbreakpoint_match(laddr2, BX_CPU_THIS_PTR address_xlation.len2, xlate_rw);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BX_CPU_C::access_write_physical(bx_phy_address paddr, unsigned len, void *data)
|
||||
|
Loading…
Reference in New Issue
Block a user