|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 3/3] x86: prefer shadow stack for producing call traces
On 08.04.2026 19:53, Andrew Cooper wrote: > On 08/04/2026 1:23 pm, Jan Beulich wrote: >> Shadow stacks contain little more than return addresses, and they in >> particular allow precise call traces also without FRAME_POINTER. > > Do you have an example of what such a backtrace now looks like ? I don't have one to hand, but I'll add an example for v3. >> --- >> While the 'E' for exception frames is probably okay, I'm not overly >> happy with the 'C' (for CET). I would have preferred 'S' (for shadow), >> but we use that character already. >> >> As an alternative to suppressing output for the top level exception >> frame, adding the new code ahead of the 'R' output line (and then also >> ahead of the stack top read) could be considered. >> >> Perhaps having a printk() for the PV entry case is meaningless, for >> - no frame being pushed when entered from CPL=3 (64-bit PV), >> - no entry possible from CPL<3 (32-bit PV disabled when CET is active)? >> In which case the comment probably should just be "Bogus." and the code >> merely be "break;". > > Yes, PV32 doesn't exist when CET-SS is active, and PV64 doesn't push a > frame. regs->ssp will point to the supervisor token (IDT delivery) or > on the boundary with the regular stack (FRED). Okay, I'll change that then as indicated. >> Quite likely a number of other uses of is_active_kernel_text() also want >> amending with in_stub(). > > There are very few things which can exist on a shadow stack. > > 1) Tokens (supervisor, restore or prev) > 2) Return address > 3) Old-SSP > 4) Old-CS > > Intel recommend not allowing code or stacks to be in the bottom 64k of > the address space to prevent type confusion between Old-CS and the other > values. Xen matches this expectation, but it might be wise to check for > it explicitly. What exactly do you mean here? Neither is_active_kernel_text() nor in_stub() nor the further "!((val ^ *ptr) >> (PAGE_SHIFT + STACK_ORDER))" (which I only now notice can't be quite right, as val was read from *ptr; I think (unsigned long)ptr is meant instead) would yield true there. If, as per above, in the remaining else we'll have just "break", what would such a separate check be good for? Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |