|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 21/23] x86/pv: ERETU error handling
On 28.08.2025 17:04, Andrew Cooper wrote:
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -2345,6 +2345,113 @@ void asmlinkage entry_from_pv(struct cpu_user_regs
> *regs)
> fatal_trap(regs, false);
> }
>
> +void nocall eretu_error_dom_crash(void);
> +
> +/*
> + * Classify an event at the ERETU instruction, and handle if possible.
> + * Returns @true if handled, @false if the event should continue down the
> + * normal handlers.
> + */
> +static bool handle_eretu_event(struct cpu_user_regs *regs)
> +{
> + unsigned long recover;
> +
> + /*
> + * WARNING: The GPRs in gregs overlaps with regs. Only gregs->error_code
> + * and later are legitimate to access.
> + */
> + struct cpu_user_regs *gregs =
> + _p(regs->rsp - offsetof(struct cpu_user_regs, error_code));
> +
> + /*
> + * The asynchronous or fatal events (INTR, NMI, #MC, #DF) have been dealt
> + * with, meaning we only have syncrhonous ones to consider. Anything
> + * which isn't a hardware exception wants handling normally.
> + */
> + if ( regs->fred_ss.type != X86_ET_HW_EXC )
> + return false;
> +
> + /*
> + * Guests are permitted to write non-present GDT/LDT entries. Therefore
> + * #NP[sel] (%cs) and #SS[sel] (%ss) must be handled as guest errors.
> The
> + * only other source of #SS is for a bad %ss-relative memory access in
> + * Xen, and if the stack is that bad, we'll have escalated to #DF.
> + *
> + * #PF can happen from ERETU accessing the GDT/LDT. Xen may translate
> + * these into #GP for the guest, so must be handled as guest errors. In
> + * theory we can get #PF for a bad instruction fetch or bad stack access,
> + * but either of these will be fatal and not end up here.
> + */
> + switch ( regs->fred_ss.vector )
> + {
> + case X86_EXC_GP:
> + /*
> + * #GP[0] can occur because of a NULL %cs or %ss (which are a guest
> + * error), but some #GP[0]'s are errors in Xen (ERETU at SL != 0), or
> + * errors of Xen handling guest state (bad metadata). These magic
> + * numbers came from the FRED Spec; they check that ERETU is trying
> to
> + * return to Ring 3, and that reserved or inapplicable bits are 0.
> + */
> + if ( regs->error_code == 0 && (gregs->cs & ~3) && (gregs->ss & ~3) &&
> + (regs->fred_cs.sl != 0 ||
> + (gregs->csx & 0xffffffffffff0003UL) != 3 ||
> + (gregs->rflags & 0xffffffffffc2b02aUL) != 2 ||
> + (gregs->ssx & 0xfff80003UL) != 3) )
I understand that for ->csx and ->ssx sensible alternatives to using such magic
constants don't really exist. For ->rflags, though, I think it would be nice if
we could use constants we have.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |