Skip to content

Commit f91cb04

Browse files
author
Stanislav Shwartsman
committed
partially rewrite FredEventDelivery to avoid issues when save state on stack faults (but CS/SS setup cannot be undone)
1 parent b7338f9 commit f91cb04

File tree

1 file changed

+29
-29
lines changed

1 file changed

+29
-29
lines changed

bochs/cpu/fred.cc

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ void BX_CPU_C::FRED_EventDelivery(Bit8u vector, unsigned type, Bit16u error_code
3434
BX_CPU_THIS_PTR in_event = true;
3535
#endif
3636

37-
Bit32u old_CPL = CPL;
3837
Bit32u old_CSL = (CPL == 3) ? 0 : CSL;
3938

4039
Bit32u old_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
@@ -100,7 +99,7 @@ void BX_CPU_C::FRED_EventDelivery(Bit8u vector, unsigned type, Bit16u error_code
10099
else
101100
new_RSP = (RSP - (BX_CPU_THIS_PTR msr.ia32_fred_cfg & 0x1C0)) & ~BX_CONST64(0x3F); // decrement RSP and align to 64-bytes
102101

103-
Bit32u old_flags = read_eflags();
102+
Bit32u old_eflags = read_eflags();
104103

105104
#if BX_SUPPORT_CET
106105
Bit64u old_SSP = SSP;
@@ -119,7 +118,32 @@ void BX_CPU_C::FRED_EventDelivery(Bit8u vector, unsigned type, Bit16u error_code
119118
}
120119
#endif
121120

122-
// ESTABLISH NEW CONTEXT: OLD STATE WILL BE RESTORED IF THERE IS A SUBSEQUENT EXCEPTION -> FIXME: HOW ???
121+
// ESTABLISH NEW CONTEXT
122+
123+
// save state on stacks
124+
// Save return state on new regular stack; memory accesses here have supervisor privilege
125+
write_new_stack_qword(new_RSP - 8, 0, 0); // first 8 bytes pushed are all zeros
126+
write_new_stack_qword(new_RSP - 16, 0, BX_CPU_THIS_PTR fred_event_data);
127+
write_new_stack_qword(new_RSP - 24, 0, old_SS);
128+
write_new_stack_qword(new_RSP - 32, 0, old_RSP);
129+
write_new_stack_qword(new_RSP - 40, 0, old_eflags);
130+
write_new_stack_qword(new_RSP - 48, 0, old_CS);
131+
write_new_stack_qword(new_RSP - 56, 0, old_RIP);
132+
write_new_stack_qword(new_RSP - 64, 0, error_code);
133+
134+
#if BX_SUPPORT_CET
135+
if (ShadowStackEnabled(0)) {
136+
if (CPL == 0) {
137+
shadow_stack_write_dword(new_SSP - 4, CPL, 0); // store 4 bytes of zeros to SSP-4
138+
new_SSP &= ~BX_CONST64(0x7);
139+
shadow_stack_write_qword(new_SSP - 8, CPL, old_CS);
140+
shadow_stack_write_qword(new_SSP - 16, CPL, old_RIP);
141+
shadow_stack_write_qword(new_SSP - 24, CPL, old_SSP);
142+
new_SSP -= 24;
143+
}
144+
SSP = new_SSP;
145+
}
146+
#endif
123147

124148
// update segment registers if event occurred in ring 3
125149
if (CPL == 3) {
@@ -149,36 +173,12 @@ void BX_CPU_C::FRED_EventDelivery(Bit8u vector, unsigned type, Bit16u error_code
149173
RIP = new_RIP;
150174
BX_CPU_THIS_PTR eflags = 0x2; // Clear EFLAGS, bit1 is always set
151175
clearEFlagsOSZAPC(); // update lazy flags state
152-
RSP = new_RSP;
176+
RSP = new_RSP - 64;
153177
set_CSL(new_CSL);
154178

155-
// save state on stack
156-
// Save return state on new regular stack; memory accesses here have supervisor privilege
157-
write_new_stack_qword(new_RSP - 8, 0, 0); // first 8 bytes pushed are all zeros
158-
write_new_stack_qword(new_RSP - 16, 0, BX_CPU_THIS_PTR fred_event_data);
159-
write_new_stack_qword(new_RSP - 24, 0, old_SS);
160-
write_new_stack_qword(new_RSP - 32, 0, old_RSP);
161-
write_new_stack_qword(new_RSP - 40, 0, old_flags);
162-
write_new_stack_qword(new_RSP - 48, 0, old_CS);
163-
write_new_stack_qword(new_RSP - 56, 0, old_RIP);
164-
write_new_stack_qword(new_RSP - 64, 0, error_code);
165-
RSP -= 64;
166-
167179
#if BX_SUPPORT_CET
168180
if (BX_CPU_THIS_PTR cr4.get_CET()) {
169-
if (ShadowStackEnabled(0)) {
170-
if (old_CPL == 0) {
171-
shadow_stack_write_dword(new_SSP - 4, CPL, 0); // store 4 bytes of zeros to SSP-4
172-
new_SSP &= ~BX_CONST64(0x7);
173-
shadow_stack_write_qword(new_SSP - 8, CPL, old_CS);
174-
shadow_stack_write_qword(new_SSP - 16, CPL, old_RIP);
175-
shadow_stack_write_qword(new_SSP - 24, CPL, old_SSP);
176-
new_SSP -= 24;
177-
}
178-
SSP = new_SSP;
179-
}
180-
181-
if (ShadowStackEnabled(3) && old_CPL == 3) {
181+
if (ShadowStackEnabled(3) && CPL == 3) {
182182
BX_CPU_THIS_PTR msr.ia32_pl_ssp[3] = CanonicalizeAddress(BX_CPU_THIS_PTR msr.ia32_pl_ssp[3]);
183183
}
184184

0 commit comments

Comments
 (0)