From: Linus Torvalds <torvalds@linux-foundation.org>
To: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
Andy Lutomirski <luto@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
x86@kernel.org, Kostya Serebryany <kcc@google.com>,
Andrey Ryabinin <ryabinin.a.a@gmail.com>,
Andrey Konovalov <andreyknvl@gmail.com>,
Alexander Potapenko <glider@google.com>,
Taras Madan <tarasmadan@google.com>,
Dmitry Vyukov <dvyukov@google.com>,
"H . J . Lu" <hjl.tools@gmail.com>,
Andi Kleen <ak@linux.intel.com>,
Rick Edgecombe <rick.p.edgecombe@intel.com>,
Bharata B Rao <bharata@amd.com>,
Jacob Pan <jacob.jun.pan@linux.intel.com>,
Ashok Raj <ashok.raj@intel.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCHv13 05/16] x86/uaccess: Provide untagged_addr() and remove tags before address check
Date: Fri, 30 Dec 2022 16:42:05 -0800 [thread overview]
Message-ID: <CAHk-=wgmGqwDD0kvjZxekU6uYR2x6+QgRHeMKy3snL2XYEzwEw@mail.gmail.com> (raw)
In-Reply-To: <20221231001029.5nckrhtmwahb65jo@box>
On Fri, Dec 30, 2022 at 4:10 PM Kirill A. Shutemov <kirill@shutemov.name> wrote:
>
> I made it a per-cpu variable (outside struct tlb_state to be visible in
> modules). __get/put_user_X() now have a single instruction to untag the
> address and it is gated by X86_FEATURE_LAM.
Yeah, that looks more reasonable to me.
> BTW, am I blind or we have no infrastructure to hookup static branches
> from assembly?
I think you're right.
> I would be a better fit than ALTERNATIVE here. It would allow to defer
> overhead until the first user of the feature.
Well, it would make the overhead worse once people actually start
using it. So it's not obvious that a static branch is really the right
thing to do.
That said, while I think that UNTAG_ADDR is quite reasonable now, the
more I look at getuser.S and putuser.S, the more I'm thinking that
getting rid of the TASK_SIZE comparison entirely is the right thing to
do on x86-64.
It's really rather nasty, with not just that whole LA57 alternative,
but it's doing a large 64-bit constant too.
Now, on 32-bit, we do indeed have to compare against TASK_SIZE
explicitly, but on 32-bit we could just use an immediate for the cmp
instruction, so even there that whole "load constant" isn't really
optimal.
And on 64-bit, we really only need to check the high bit.
In fact, we don't even want to *check* it, because then we need to do
that disgusting array_index_mask_nospec thing to mask the bits for it,
so it would be even better to use purely arithmetic with no
conditionals anywhere.
And that's exactly what we could do on x86-64:
movq %rdx,%rax
shrq $63,%rax
orq %rax,%rdx
would actually be noticeably better than what we do now for for
TASK_SIZE checking _and_ for the array index masking (for putuser.S,
we'd use %rbx instead of %rax in that sequence).
The above three simple instructions would replace all of the games we
now play with
LOAD_TASK_SIZE_MINUS_N(0)
cmp %_ASM_DX,%_ASM_AX
jae bad_get_user
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
and %_ASM_DX, %_ASM_AX
entirely.
It would just turn all kernel addresses into all ones, which is then
guaranteed to fault. So no need for any conditional that never
triggers in real life anyway.
On 32-bit, we'd still have to do that old sequence, but we'd replace the
LOAD_TASK_SIZE_MINUS_N(0)
cmp %_ASM_DX,%_ASM_AX
with just the simpler
cmp $TASK_SIZE_MAX-(n),%_ASM_AX
since the only reason we do that immediate load is because there si no
64-bit immediate compare instruction.
And once we don't test against TASK_SIZE, the need for UNTAG_ADDR just
goes away, so now LAM is better too.
In other words, we could actually improve on our current code _and_
simplify the LAM situation. Win-win.
Anyway, I do not hate the version of the patch you posted, but I do
think that the win-win of just making LAM not _have_ this issue in the
first place might be the preferable one.
The one thing that that "shift by 63 and bitwise or" trick does
require is that the _ASM_EXTABLE_UA() thing for getuser/putuser would
have to have an extra annotation to shut up the
WARN_ONCE(trapnr == X86_TRAP_GP, "General protection fault in
user access. Non-canonical address?");
in ex_handler_uaccess() for the GP trap that users can now cause by
giving a non-canonical address with the high bit clear. So we'd
probably just want a new EX_TYPE_* for these cases, but that still
looks fairly straightforward.
Hmm?
Linus
next prev parent reply other threads:[~2022-12-31 0:42 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-27 3:08 [PATCHv13 00/16] Linear Address Masking enabling Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 01/16] x86: Allow atomic MM_CONTEXT flags setting Kirill A. Shutemov
2023-01-04 19:07 ` Dave Hansen
2022-12-27 3:08 ` [PATCHv13 02/16] x86: CPUID and CR3/CR4 flags for Linear Address Masking Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 03/16] x86/mm: Handle LAM on context switch Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 04/16] mm: Introduce untagged_addr_remote() Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 05/16] x86/uaccess: Provide untagged_addr() and remove tags before address check Kirill A. Shutemov
2022-12-27 19:10 ` Linus Torvalds
2022-12-31 0:10 ` Kirill A. Shutemov
2022-12-31 0:42 ` Linus Torvalds [this message]
2023-01-02 13:55 ` David Laight
2023-01-02 19:05 ` Linus Torvalds
2023-01-03 8:37 ` David Laight
2023-01-07 9:10 ` Kirill A. Shutemov
2023-01-07 17:28 ` Linus Torvalds
2022-12-27 3:08 ` [PATCHv13 06/16] x86/mm: Provide arch_prctl() interface for LAM Kirill A. Shutemov
2023-01-04 19:55 ` Edgecombe, Rick P
2023-01-10 6:17 ` Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 07/16] x86/mm: Reduce untagged_addr() overhead until the first LAM user Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 08/16] mm: Expose untagging mask in /proc/$PID/status Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 09/16] iommu/sva: Replace pasid_valid() helper with mm_valid_pasid() Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 10/16] x86/mm/iommu/sva: Make LAM and SVA mutually exclusive Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 11/16] selftests/x86/lam: Add malloc and tag-bits test cases for linear-address masking Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 12/16] selftests/x86/lam: Add mmap and SYSCALL " Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 13/16] selftests/x86/lam: Add io_uring " Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 14/16] selftests/x86/lam: Add inherit " Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 15/16] selftests/x86/lam: Add ARCH_FORCE_TAGGED_SVA " Kirill A. Shutemov
2022-12-27 3:08 ` [PATCHv13 16/16] selftests/x86/lam: Add test cases for LAM vs thread creation Kirill A. Shutemov
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='CAHk-=wgmGqwDD0kvjZxekU6uYR2x6+QgRHeMKy3snL2XYEzwEw@mail.gmail.com' \
--to=torvalds@linux-foundation.org \
--cc=ak@linux.intel.com \
--cc=andreyknvl@gmail.com \
--cc=ashok.raj@intel.com \
--cc=bharata@amd.com \
--cc=dave.hansen@linux.intel.com \
--cc=dvyukov@google.com \
--cc=glider@google.com \
--cc=hjl.tools@gmail.com \
--cc=jacob.jun.pan@linux.intel.com \
--cc=kcc@google.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=kirill@shutemov.name \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=luto@kernel.org \
--cc=peterz@infradead.org \
--cc=rick.p.edgecombe@intel.com \
--cc=ryabinin.a.a@gmail.com \
--cc=tarasmadan@google.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox