All of lore.kernel.org
 help / color / mirror / Atom feed
From: Borislav Petkov <bp@alien8.de>
To: Lai Jiangshan <jiangshanlai@gmail.com>,
	Andy Lutomirski <luto@kernel.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Thomas Gleixner <tglx@linutronix.de>, X86 ML <x86@kernel.org>,
	Lai Jiangshan <jiangshan.ljs@antgroup.com>,
	Ingo Molnar <mingo@redhat.com>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Fenghua Yu <fenghua.yu@intel.com>,
	Thomas Tai <thomas.tai@oracle.com>,
	"Chang S. Bae" <chang.seok.bae@intel.com>,
	Masami Hiramatsu <mhiramat@kernel.org>
Subject: Re: [PATCH V4 1/7] x86/traps: Move pt_regs only in fixup_bad_iret()
Date: Thu, 7 Apr 2022 15:18:59 +0200	[thread overview]
Message-ID: <Yk7kwzIv2YA+aO7y@zn.tnic> (raw)
In-Reply-To: <Yk6fQfgo975pW3t0@zn.tnic>

On Thu, Apr 07, 2022 at 10:22:25AM +0200, Borislav Petkov wrote:
> Maybe there was a reason it was done this way:

Ok, I went and singlestepped this code so that I can see what's going
on.

The second memcpy in fixup_bad_iret() copies the remainder of pt_regs
from the current stack. The result in tmp looks like this:

(gdb) p/x tmp
$10 = {error_entry_ret = 0xffffffff81a00998, regs = {r15 = 0x0, r14 = 0x0, r13 = 0x7fffffffea30, r12 = 0x40002b, bp = 0x40, 
    bx = 0xa, r11 = 0x246, r10 = 0x8, r9 = 0x7fffffffe860, r8 = 0x0, ax = 0x0, cx = 0x0, dx = 0x0, si = 0x7fffffffe860, 
    di = 0x2, orig_ax = 0x30, ip = 0x403000, cs = 0x33, flags = 0x246, sp = 0x8badf00d5aadc0de, ss = 0x33}}

note error_entry_ret which is:

(gdb) x/10i 0xffffffff81a00998
   0xffffffff81a00998 <asm_exc_general_protection+8>:   mov    %rsp,%rdi
   0xffffffff81a0099b <asm_exc_general_protection+11>:  mov    0x78(%rsp),%rsi
   0xffffffff81a009a0 <asm_exc_general_protection+16>:  movq   $0xffffffffffffffff,0x78(%rsp)
   0xffffffff81a009a9 <asm_exc_general_protection+25>:  call   0xffffffff818c8960 <exc_general_protection>
   0xffffffff81a009ae <asm_exc_general_protection+30>:  jmp    0xffffffff81a01030 <error_return>
   0xffffffff81a009b3:  data16 nopw %cs:0x0(%rax,%rax,1)

i.e., the return address to the #GP handler that has been pushed on
the stack when the IRET fault has happened and former has called
error_entry().

fixup_bad_iret() then ends up returning this in new_stack:

(gdb) p/x *new_stack
$12 = {error_entry_ret = 0xffffffff81a00998, regs = {r15 = 0x0, r14 = 0x0, r13 = 0x7fffffffea30, r12 = 0x40002b, bp = 0x40, 
    bx = 0xa, r11 = 0x246, r10 = 0x8, r9 = 0x7fffffffe860, r8 = 0x0, ax = 0x0, cx = 0x0, dx = 0x0, si = 0x7fffffffe860, 
    di = 0x2, orig_ax = 0x30, ip = 0x403000, cs = 0x33, flags = 0x246, sp = 0x8badf00d5aadc0de, ss = 0x33}}

and when error_entry() does:

        mov     %rax, %rsp

The stack has:

=> 0xffffffff81a0102d <error_entry+173>:        jmp    0xffffffff81a00fd2 <error_entry+82>
0xfffffe0000250f50:     0xffffffff81a00998      0x0000000000000000
0xfffffe0000250f60:     0x0000000000000000      0x00007fffffffea30
0xfffffe0000250f70:     0x000000000040002b      0x0000000000000040
0xfffffe0000250f80:     0x000000000000000a      0x0000000000000246
0xfffffe0000250f90:     0x0000000000000008      0x00007fffffffe860

and you can recognize new_stack there.

Then it does:

        jmp     error_entry_from_usermode_after_swapgs

where it does:

error_entry_from_usermode_after_swapgs:
        /* Put us onto the real thread stack. */
        popq    %r12                            /* save return addr in %12 */
        movq    %rsp, %rdi                      /* arg0 = pt_regs pointer */
        call    sync_regs
        movq    %rax, %rsp                      /* switch stack */
        ENCODE_FRAME_POINTER
        pushq   %r12
        RET

and in here it uses %r12 to stash the return address 0xffffffff81a00998
while sync_regs() runs.

So yeah, all your patch does is get rid of void *error_entry_ret in

struct bad_iret_stack {
        void *error_entry_ret;
        struct pt_regs regs;
};

So your commit message should have been as simple as:

"Always stash the address error_entry() is going to return to, in %r12
and get rid of the void *error_entry_ret; slot in struct bad_iret_stack
which was supposed to account for it and pt_regs pushed on the stack.

After this, both functions can work on a struct pt_regs pointer
directly."

In any case, I don't see why amluto would do this so this looks like a
sensible cleanup to do.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

  reply	other threads:[~2022-04-07 13:19 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-18 14:30 [PATCH V4 0/7] x86/entry: Clean up entry code Lai Jiangshan
2022-03-18 14:30 ` [PATCH V4 1/7] x86/traps: Move pt_regs only in fixup_bad_iret() Lai Jiangshan
2022-04-06 19:00   ` Borislav Petkov
2022-04-07  7:03     ` Lai Jiangshan
2022-04-07  8:22       ` Borislav Petkov
2022-04-07 13:18         ` Borislav Petkov [this message]
2022-04-08  1:56           ` Lai Jiangshan
2022-04-11  9:36   ` Borislav Petkov
2022-03-18 14:30 ` [PATCH V4 2/7] x86/entry: Switch the stack after error_entry() returns Lai Jiangshan
2022-04-11  9:35   ` Borislav Petkov
2022-04-11 11:48     ` Lai Jiangshan
2022-03-18 14:30 ` [PATCH V4 3/7] x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry Lai Jiangshan
2022-03-18 14:30 ` [PATCH V4 4/7] x86/entry: Move cld to the start of idtentry Lai Jiangshan
2022-03-18 14:30 ` [PATCH V4 5/7] x86/entry: Don't call error_entry for XENPV Lai Jiangshan
2022-03-18 14:30 ` [PATCH V4 6/7] x86/entry: Convert SWAPGS to swapgs and remove the definition of SWAPGS Lai Jiangshan
2022-03-18 14:30 ` [PATCH V4 7/7] x86/entry: Use idtentry macro for entry_INT80_compat Lai Jiangshan
2022-04-06 15:57 ` [PATCH V4 0/7] x86/entry: Clean up entry code Lai Jiangshan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Yk7kwzIv2YA+aO7y@zn.tnic \
    --to=bp@alien8.de \
    --cc=chang.seok.bae@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=fenghua.yu@intel.com \
    --cc=hpa@zytor.com \
    --cc=jiangshan.ljs@antgroup.com \
    --cc=jiangshanlai@gmail.com \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=thomas.tai@oracle.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.