RE: [PATCH v6 27/33] x86/fred: fixup fault on ERETU by jumping to fred_entrypoint_user

From: Li, Xin3
Date: Sat Apr 01 2023 - 04:13:02 EST


> > + /* Copy error code to uregs and adjust stack pointer accordingly */
> > + uregs->orig_ax = error_code;
>
> The address of uregs->orig_ax is below regs->sp, so I think some comments are
> needed here to state why it is safe to write to uregs->orig_ax (a.k.a it is not
> verlapped with regs).

Good point, because it's one of the nice FRED features.

The RSP used by FRED to push a stack frame is not the value in %rsp, it is
calculated from %rsp with the following 2 steps:
1) RSP = %rsp - (IA32_FRED_CONFIG & 0x1c0) // REDZONE of (N * 64) bytes
2) RSP = RSP & ~0x3f // Clearing RSP[5:0] to align to a 64-byte cache line
when the event delivery doesn't trigger a stack level change.

Thus the FRED stack frame error code, i.e., orig_ax, is _always_ on a 64-byte
cache line boundary, and a new stack frame is guaranteed to start below the
error code (An extra REDZONE of (N * 64) bytes may be pushed between), and
it is safe to write to uregs->orig_ax.

Here is an example with a N=1 REDZONE:

64-byte cache line ==> ______________
|___Reserved___|
|__Event_data__|
|_____SS_______|
|_____RSP______|
|_____FLAGS____|
|_____CS_______|
|_____IP_______| <== ERETU stack frame
64-byte cache line ==> |__Error_code__|
|______________|
|______________|
|______________|
|______________|
|______________|
|______________|
|______________| <== RSP after step 1)
64-byte cache line ==> |______________| <== RSP after step 2)
|___Reserved___|
|__Event_data__|
|_____SS_______|
|_____RSP______|
|_____FLAGS____|
|_____CS_______|
|_____IP_______| <== ERETS stack frame
64-byte cache line ==> |__Error_code__|

Xin