Skip to content

Implementation of Flexible Return and Delivery (FRED) ISA extensions#701

Merged
stlintel merged 9 commits intomasterfrom
cpu/fred
Feb 11, 2026
Merged

Implementation of Flexible Return and Delivery (FRED) ISA extensions#701
stlintel merged 9 commits intomasterfrom
cpu/fred

Conversation

@stlintel
Copy link
Contributor

Implementation of Flexible Return and Delivery (FRED) ISA extensions

@stlintel
Copy link
Contributor Author

Status:

tested on TinyCorePure64-16.2.iso and Fedora-Workstation-Live-43-1.6.x86_64.iso using
cpu: model=arrow_lake
cpu: count=1, ips=800M, reset_on_triple_fault=1, ignore_bad_msrs=1, add_features="fred"

turned out that both disk images do not really enable FRED and only make use of LKGS instruction.
LKGS works perfectly but the kernel boots without attempt to set CR4.FRED or even read or write any of the FRED MSRs
so need your help to find a kernel which really tries to do FRED to be used for testing
may kernels should be built with some special options ? can someone help ?

@stlintel stlintel force-pushed the cpu/fred branch 2 times, most recently from 7e2268f to bc46203 Compare January 14, 2026 05:29
@stlintel stlintel force-pushed the cpu/fred branch 4 times, most recently from c81cc63 to 4c930aa Compare January 18, 2026 18:26
@stlintel stlintel force-pushed the master branch 2 times, most recently from 876938f to 238b32e Compare January 25, 2026 12:56
@SHU1107
Copy link

SHU1107 commented Jan 27, 2026

Bit64u old_RIP = RIP;
Bit64u new_RIP = BX_CPU_THIS_PTR msr.ia32_fred_cfg & ~0xfff;
if (CPL == 3)
new_RIP += 256;
if (! IsCanonical(new_RIP)) {
BX_ERROR(("FRED Event Delivery: non canonical value in BX_MSR_IA32_FRED_CONFIG !"));
exception(BX_GP_EXCEPTION, 0);

It seems the logic here is reversed. According to the manual:

Specifically, the new RIP value that FRED event delivery establishes is

IA32_FRED_CONFIG & ~FFFH for events that occur in ring 3 and
(IA32_FRED_CONFIG & ~FFFH) + 256 for events that occur in ring 0

@stlintel
Copy link
Contributor Author

Bit64u old_RIP = RIP; Bit64u new_RIP = BX_CPU_THIS_PTR msr.ia32_fred_cfg & ~0xfff; if (CPL == 3) new_RIP += 256; if (! IsCanonical(new_RIP)) { BX_ERROR(("FRED Event Delivery: non canonical value in BX_MSR_IA32_FRED_CONFIG !")); exception(BX_GP_EXCEPTION, 0);

It seems the logic here is reversed. According to the manual:

IA32_FRED_CONFIG & ~FFFH for events that occur in ring 3 and (IA32_FRED_CONFIG & ~FFFH) + 256 for events that occur in ring 0

Thanks, fixed this issue and also another nearby problem related to ~0xfff constant truncation.
~0xfff is be default 32-bit constant, fixed to 64-bit.

@SHU1107
Copy link

SHU1107 commented Jan 27, 2026

// update registers defining context
RIP = new_RIP;
BX_CPU_THIS_PTR eflags = 0x2; // Clear EFLAGS, bit1 is always set
clearEFlagsOSZAPC(); // update lazy flags state
RSP = new_RSP;
set_CSL(new_CSL);

#if BX_SUPPORT_CET
if (ShadowStackEnabled(0)) SSP = new_SSP;
#endif

// save state on stack
// Save return state on new regular stack; memory accesses here have supervisor privilege
write_new_stack_qword(new_RSP - 8, 0, 0); // first 8 bytes pushed are all zeros
write_new_stack_qword(new_RSP - 16, 0, BX_CPU_THIS_PTR fred_event_data);
write_new_stack_qword(new_RSP - 24, 0, old_SS);
write_new_stack_qword(new_RSP - 32, 0, old_RSP);
write_new_stack_qword(new_RSP - 40, 0, old_flags);
write_new_stack_qword(new_RSP - 48, 0, old_CS);
write_new_stack_qword(new_RSP - 56, 0, old_RIP);
write_new_stack_qword(new_RSP - 64, 0, error_code);

It appears that an RSP -= 64 operation is missing here. According to the Intel Manual (Appendix A), the pseudocode for FRED event delivery specifically uses the term push8b to save the return state, and pop8b for the ERETS/ERETU instructions.

@stlintel
Copy link
Contributor Author

It appears that an RSP -= 64 operation is missing here. According to the Intel Manual (Appendix A), the pseudocode for FRED event delivery specifically uses the term push8b to save the return state, and pop8b for the ERETS/ERETU instructions.

Thanks, pushed the fix as well

@SHU1107
Copy link

SHU1107 commented Feb 1, 2026

I have tested the ERETU and ERETS instructions (with CET=0), and the execution results generally align with the manual's specifications. I have also added xchg bx, bx—hope this helps.a.zip

Stanislav Shwartsman and others added 9 commits February 11, 2026 13:50
add fred.cc dummy file
add FRED MSR enums to msr.h

shape of ERETS

add FRED MSR MSRs to msr.cc

FRED Event Delivery initial code

64-bit CR4 support

fred ISA decoding and other random stuff

FRED modifies behavior of existing instructions

added LKGS emulation

continue implementation, mainly VMX support self

use CR4 class in VMX host and guest state structures

CSL is MSR_IA32_FRED_CONFIG[1:0], not extra state

fixed non-printable character in comment, continue implementation

support also CR4_HI print in debug dump

implement loading of CS and SS in ERETU

started VMX support for FRED

other way of handling FredEventDelivery

add (c)

continue implementation

mention FRED in CHANGES

proper way to load CS and SS in ERETU
…n stack faults (but CS/SS setup cannot be undone)
@stlintel
Copy link
Contributor Author

FRED moved to official SDM

@stlintel stlintel merged commit 7a0d34c into master Feb 11, 2026
3 checks passed
@stlintel stlintel deleted the cpu/fred branch February 11, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants