On January 25, 2023 3:37:23 AM PST, Ammar Faizi <ammarfaizi2@xxxxxxxxxxx> wrote: >On Wed, Jan 25, 2023 at 02:17:41AM -0800, H. Peter Anvin wrote: >> I guess it would depend on what they "normally" are. My #1 impulse would be to leave them both unchanged. > >Ah okay... I think I understand now. My confusion came from a comment >in that code. > >The current SIGUSR1 handler has a comment: > > /* Set IP and CX to match so that SYSRET can happen. */ > ctx->uc_mcontext.gregs[REG_RIP] = rip; > ctx->uc_mcontext.gregs[REG_RCX] = rip; > >So I thought if we leave them both unchanged, then SYSRET can happen >too, because IP and CX match. My initial confusion about that was: > > Where do we actually exercise IRET if the SIGUSR2 handler > exercises SYSRET then? > >I realized my assumption was wrong. The current SIGUSR1 handler >actually forces the kernel to use IRET, not SYSRET. Because the %rip >is set to a non-canonical address. So that's the place where it >exercises IRET. > >IOW, my understanding now: > >The current SIGUSR1 handler exercises the SYSRET-appropriate condition >detector in the kernel. It doesn't actually go to the SYSRET path >despite the comment saying "SYSRET can happen". That detector must take >us to the IRET path or we will #GP in kernel space on Intel CPUs. > >In short, the SIGUSR1 handler asserts that "SYSRET must *not* happen". > >The expected SIGUSR2 handler addition exercises the SYSRET path by >leaving REG_IP and REG_CX unchanged. > >Am I correct? > That's the idea.