Re: [RFCv2 05/10] x86/mm: Provide untagged_addr() helper

Thomas Gleixner
2022-05-12T13:06:47Z

On Wed, May 11 2022 at 05:27, Kirill A. Shutemov wrote:
> +#define __untagged_addr(addr, n) \
> + ((__force __typeof__(addr))sign_extend64((__force u64)(addr), n))

How is this supposed to be correct? This sign extends based on bit 47
resp. 56, i.e. the topmost bit of the userspace address space for the
LAM mode.

So if that bit _is_ set, then the result has bit 48-63 resp. 57-63 set
as well. Not really what you want, right?

This has to mask out bit 48-62 resp. 57-62 and leave all other bits
alone.

> +#define untagged_addr(addr) ({ \
> + u64 __addr = (__force u64)(addr); \
> + if (__addr >> 63 == 0) { \
> + if (current->thread.features & X86_THREAD_LAM_U57) \
> + __addr &= __untagged_addr(__addr, 56); \
> + else if (current->thread.features & X86_THREAD_LAM_U48) \
> + __addr &= __untagged_addr(__addr, 47); \
> + } \
> + (__force __typeof__(addr))__addr; \
> +})

So this wants something like this:

#define untagged_addr(addr) ({ \
u64 __addr = (__force u64)(addr); \
\
__addr &= current->thread.lam_untag_mask; \
(__force __typeof__(addr))__addr; \
})

No conditionals, fast _and_ correct. Setting this untag mask up once
when LAM is enabled is not rocket science.

Thanks,

tglx