Skip to content

Commit

Permalink
Reduce page fault related logging (#389)
Browse files Browse the repository at this point in the history
Simplify page fault rewinding code
  • Loading branch information
schellingb committed Apr 10, 2023
1 parent 035e01e commit 9708155
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 147 deletions.
60 changes: 60 additions & 0 deletions include/paging.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,10 +379,70 @@ static INLINE bool mem_writed_checked(PhysPt address,Bit32u val) {
}

extern bool paging_prevent_exception_jump;

#if 1 // use C++ exceptions
#include <exception>
struct GuestPageFaultException : std::exception {
GuestPageFaultException(Bitu n_faultcode) : faultcode(n_faultcode) {}
Bitu faultcode;
};

#define THROW_PAGE_FAULT(CODE) throw GuestPageFaultException(CODE)

#define PAGE_FAULT_TRY \
restartloop2: \
try \
{

#define PAGE_FAULT_CATCH \
} \
catch (GuestPageFaultException& pf) { \
paging_prevent_exception_jump = true; \
CPU_Exception(EXCEPTION_PF,pf.faultcode); \
paging_prevent_exception_jump = false; \
goto restartloop2; \
}

#define REWIND_ESP_ON_PAEGFAULT_START \
{ \
Bitu old_esp = reg_esp; \
try {

#define REWIND_ESP_ON_PAGEFAULT_END \
} \
catch (GuestPageFaultException&) { \
reg_esp = old_esp; \
throw; \
} \
}
#else // use C longjmp (incomplete)
#include <csetjmp>
extern Bitu pagefault_faultcode;
extern std::jmp_buf pagefault_jmp_buf;
extern Bit32u pagefault_old_esp;
#define THROW_PAGE_FAULT(CODE) \
pagefault_faultcode = (CODE); \
std::longjmp(pagefault_jmp_buf, 1)
#define PAGE_FAULT_TRY \
if (looprecursion == 1 && setjmp(pagefault_jmp_buf)) \
{ \
if (pagefault_old_esp) { reg_esp = pagefault_old_esp; pagefault_old_esp = 0; } \
paging_prevent_exception_jump = true; \
CPU_Exception(EXCEPTION_PF,pagefault_faultcode); \
paging_prevent_exception_jump = false; \
}
#define PAGE_FAULT_CATCH
#define REWIND_ESP_ON_PAEGFAULT_START \
{ \
pagefault_old_esp = reg_esp;
#define REWIND_ESP_ON_PAGEFAULT_END \
pagefault_old_esp = 0; \
}
#endif

#endif
89 changes: 30 additions & 59 deletions src/cpu/core_normal/prefix_66.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,31 +147,19 @@
CASE_D(0x5f) /* POP EDI */
reg_edi=Pop_32();break;
CASE_D(0x60) /* PUSHAD */
{
Bitu tmpesp = reg_esp;
try {
Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
Push_32(tmpesp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
}
catch (GuestPageFaultException&) {
reg_esp = tmpesp;
throw;
}
break;
}
{
REWIND_ESP_ON_PAEGFAULT_START
Bitu tmpesp = reg_esp;
Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
Push_32(tmpesp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
REWIND_ESP_ON_PAGEFAULT_END
}; break;
CASE_D(0x61) /* POPAD */
{
Bitu old_esp = reg_esp;
try {
reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
}
catch (GuestPageFaultException&) {
reg_esp = old_esp;
throw;
}
break;
}
REWIND_ESP_ON_PAEGFAULT_START
reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
REWIND_ESP_ON_PAGEFAULT_END
break;
CASE_D(0x62) /* BOUND Ed */
{
GetRMrd;
Expand Down Expand Up @@ -369,17 +357,12 @@
}
CASE_D(0x8f) /* POP Ed */
{
Bit32u old_esp = reg_esp;
try {
Bit32u val=Pop_32();
GetRM;
if (rm >= 0xc0 ) {GetEArd;*eard=val;}
else {GetEAa;SaveMd(eaa,val);}
}
catch (GuestPageFaultException&) {
reg_esp = old_esp;
throw;
}
REWIND_ESP_ON_PAEGFAULT_START
Bit32u val=Pop_32();
GetRM;
if (rm >= 0xc0 ) {GetEArd;*eard=val;}
else {GetEAa;SaveMd(eaa,val);}
REWIND_ESP_ON_PAGEFAULT_END
break;
}
CASE_D(0x91) /* XCHG ECX,EAX */
Expand Down Expand Up @@ -480,17 +463,12 @@
GRP2D(Fetchb());break;
CASE_D(0xc2) /* RETN Iw */
{
Bit32u old_esp = reg_esp;
try {
/* this is structured either to complete RET or leave registers unmodified if interrupted by page fault */
Bit32u new_eip=Pop_32();
reg_esp+=Fetchw();
reg_eip=new_eip;
}
catch (GuestPageFaultException&) {
reg_esp = old_esp; /* restore stack pointer */
throw;
}
REWIND_ESP_ON_PAEGFAULT_START
/* this is structured either to complete RET or leave registers unmodified if interrupted by page fault */
Bit32u new_eip=Pop_32();
reg_esp+=Fetchw();
reg_eip=new_eip;
REWIND_ESP_ON_PAGEFAULT_END
continue;
}
CASE_D(0xc3) /* RETN */
Expand Down Expand Up @@ -529,19 +507,12 @@
}
break;
CASE_D(0xc9) /* LEAVE */
{
Bit32u old_esp = reg_esp;
reg_esp&=cpu.stack.notmask;
reg_esp|=(reg_ebp&cpu.stack.mask);
try {
reg_ebp=Pop_32();
}
catch (GuestPageFaultException&) {
reg_esp = old_esp;
throw;
}
break;
}
REWIND_ESP_ON_PAEGFAULT_START
reg_esp&=cpu.stack.notmask;
reg_esp|=(reg_ebp&cpu.stack.mask);
reg_ebp=Pop_32();
REWIND_ESP_ON_PAGEFAULT_END
break;
CASE_D(0xca) /* RETF Iw */
{
Bitu words=Fetchw();
Expand Down
83 changes: 27 additions & 56 deletions src/cpu/core_normal/prefix_none.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,30 +216,18 @@
reg_di=Pop_16();break;
CASE_W(0x60) /* PUSHA */
{
Bitu old_esp = reg_esp;
try {
Bit16u old_sp=reg_sp;
Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx);
Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di);
}
catch (GuestPageFaultException&) {
reg_esp = old_esp;
throw;
}
REWIND_ESP_ON_PAEGFAULT_START
Bit16u old_sp=reg_sp;
Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx);
Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di);
REWIND_ESP_ON_PAGEFAULT_END
}
break;
CASE_W(0x61) /* POPA */
{
Bitu old_esp = reg_esp;
try {
reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP
reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16();
}
catch (GuestPageFaultException&) {
reg_esp = old_esp;
throw;
}
}
REWIND_ESP_ON_PAEGFAULT_START
reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP
reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16();
REWIND_ESP_ON_PAGEFAULT_END
break;
CASE_W(0x62) /* BOUND */
{
Expand Down Expand Up @@ -541,17 +529,12 @@
}
CASE_W(0x8f) /* POP Ew */
{
Bit32u old_esp = reg_esp;
try {
Bit16u val=Pop_16();
GetRM;
if (rm >= 0xc0 ) {GetEArw;*earw=val;}
else {GetEAa;SaveMw(eaa,val);}
}
catch (GuestPageFaultException&) {
reg_esp = old_esp;
throw;
}
REWIND_ESP_ON_PAEGFAULT_START
Bit16u val=Pop_16();
GetRM;
if (rm >= 0xc0 ) {GetEArw;*earw=val;}
else {GetEAa;SaveMw(eaa,val);}
REWIND_ESP_ON_PAGEFAULT_END
break;
}
CASE_B(0x90) /* NOP */
Expand Down Expand Up @@ -705,17 +688,12 @@
GRP2W(Fetchb());break;
CASE_W(0xc2) /* RETN Iw */
{
Bit32u old_esp = reg_esp;
try {
/* this is structured either to complete RET or leave registers unmodified if interrupted by page fault */
Bit32u new_eip = Pop_16();
reg_esp+=Fetchw();
reg_eip=new_eip;
}
catch (GuestPageFaultException&) {
reg_esp = old_esp; /* restore stack pointer */
throw;
}
REWIND_ESP_ON_PAEGFAULT_START
/* this is structured either to complete RET or leave registers unmodified if interrupted by page fault */
Bit32u new_eip = Pop_16();
reg_esp+=Fetchw();
reg_eip=new_eip;
REWIND_ESP_ON_PAGEFAULT_END
}
continue;
CASE_W(0xc3) /* RETN */
Expand Down Expand Up @@ -761,18 +739,11 @@
}
break;
CASE_W(0xc9) /* LEAVE */
{
Bit32u old_esp = reg_esp;
reg_esp&=cpu.stack.notmask;
reg_esp|=(reg_ebp&cpu.stack.mask);
try {
reg_bp=Pop_16();
}
catch (GuestPageFaultException&) {
reg_esp = old_esp;
throw;
}
}
REWIND_ESP_ON_PAEGFAULT_START
reg_esp&=cpu.stack.notmask;
reg_esp|=(reg_ebp&cpu.stack.mask);
reg_bp=Pop_16();
REWIND_ESP_ON_PAGEFAULT_END
break;
CASE_W(0xca) /* RETF Iw */
{
Expand Down Expand Up @@ -1166,7 +1137,7 @@
break;
case 0x02: /* CALL Ev */
{
/* either EIP is set to the call address or EIP does not change if interrupted by PF */
/* either EIP is set to the call address or EIP does not change if interrupted by PF */
Bit16u new_eip;
if (rm >= 0xc0 ) {GetEArw;new_eip=*earw;}
else {GetEAa;new_eip=LoadMw(eaa);}
Expand Down
Loading

0 comments on commit 9708155

Please sign in to comment.