On 01/09/2025 1:57 pm, Jan Beulich wrote:
> On 28.08.2025 17:04, Andrew Cooper wrote:
>> --- a/xen/arch/x86/traps.c
>> +++ b/xen/arch/x86/traps.c
>> @@ -2265,9 +2265,83 @@ void asmlinkage check_ist_exit(const struct
>> cpu_user_regs *regs, bool ist_exit)
>>
>> void asmlinkage entry_from_pv(struct cpu_user_regs *regs)
>> {
>> + struct fred_info *fi = cpu_regs_fred_info(regs);
>> + uint8_t type = regs->fred_ss.type;
>> + uint8_t vec = regs->fred_ss.vector;
>> +
>> /* Copy fred_ss.vector into entry_vector as IDT delivery would have
>> done. */
>> - regs->entry_vector = regs->fred_ss.vector;
>> + regs->entry_vector = vec;
>> +
>> + if ( !IS_ENABLED(CONFIG_PV) )
>> + goto fatal;
>> +
>> + /*
>> + * First, handle the asynchronous or fatal events. These are either
>> + * unrelated to the interrupted context, or may not have valid context
>> + * recorded, and all have special rules on how/whether to re-enable
>> IRQs.
>> + */
>> + switch ( type )
>> + {
>> + case X86_ET_EXT_INTR:
>> + return do_IRQ(regs);
>>
>> + case X86_ET_NMI:
>> + return do_nmi(regs);
>> +
>> + case X86_ET_HW_EXC:
>> + switch ( vec )
>> + {
>> + case X86_EXC_DF: return do_double_fault(regs);
>> + case X86_EXC_MC: return do_machine_check(regs);
> Looking at patch 21, I came to wonder where it is that we're moving back to
> SL0 in the #MC case (which may not be fatal), for ERETU to not fault.
(Almost) any event taken in Ring3 enters Ring0 at SL0, even those with
custom STK_LVLS configuration.
See 5.1.2 Determining the New Values for Stack Level, RSP, and SSP
Nested exceptions (i.e contributory fault) and #DF can end up at SL > 0
with a Ring 3 frame. In principle you'd need to do recovery based on
regs->fred_ss.nested but Xen doesn't have any contributory exceptions
configured like this.
Under FRED, there are far fewer ways to take a contributory fault.
Pagetable corruption for the entrypoint or stack, or hitting a stack
guard page. Hitting the guard page will #DF; others will triple fault.
~Andrew