From: Maciej Wieczor-Retman <[email protected]>

With the announcement of ChkTag, it's worth preparing a stable x86
linear address masking (lam) user interface. One important aspect of lam
is the tag width, and aligning it with other industry solutions can
provide a more popular, generalized interface that other technologies
could utilize.

ChkTag will use 4-bit tags and since that's the direction other memory
tagging implementations seem to be taking too (for example Arm's MTE)
it's reasonable to converge lam in linux to the same specification. Even
though x86's LAM supports 6-bit tags it is beneficial to shorten lam to
4 bits as ChkTag will likely be the main user of the interface and such
connection should simplify things in the future.

Present to the user a shrunk tag width from 6 bits to 4 bits. At the
same time the kernel internally keeps using the full 6 bits supported by
current hardware. The user presented value is different in that it can
be relied on to support 4 bit tags even if the underlying mechanism for
address masking changes with newer hardware.

Signed-off-by: Maciej Wieczor-Retman <[email protected]>
---
Changelog v7:
- Redo most of the code around untag_mask and the last paragraph of this
  patch message.

Changelog v6:
- Rename the define constants so they match the arch_prctl() switch case
  names and update the patch message.
- Define LAM most/least significant bits so they fit better into
  GENMASK().
- Remove 'default' from the patch subject.

Changelog v4:
- Ditch the default wording in the patch message.
- Add the imperative last line as Dave suggested.

Changelog v3:
- Remove the variability of the lam width after the debugfs part was
  removed from the patchset.

 arch/x86/kernel/process_64.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 08e72f429870..8b8aaf1d740b 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -797,7 +797,8 @@ static long prctl_map_vdso(const struct vdso_image *image, 
unsigned long addr)
 
 #ifdef CONFIG_ADDRESS_MASKING
 
-#define LAM_U57_BITS 6
+#define LAM_TAG_BITS           4
+#define LAM_UNTAG_MASK         ~GENMASK(60, 57)
 
 static void enable_lam_func(void *__mm)
 {
@@ -850,7 +851,7 @@ static int prctl_enable_tagged_addr(struct mm_struct *mm, 
unsigned long nr_bits)
                return -EBUSY;
        }
 
-       if (!nr_bits || nr_bits > LAM_U57_BITS) {
+       if (!nr_bits || nr_bits > LAM_TAG_BITS) {
                mmap_write_unlock(mm);
                return -EINVAL;
        }
@@ -952,8 +953,9 @@ long do_arch_prctl_64(struct task_struct *task, int option, 
unsigned long arg2)
 #endif
 #ifdef CONFIG_ADDRESS_MASKING
        case ARCH_GET_UNTAG_MASK:
-               return put_user(task->mm->context.untag_mask,
-                               (unsigned long __user *)arg2);
+               if (task->mm->context.lam_cr3_mask)
+                       return put_user(LAM_UNTAG_MASK, (unsigned long __user 
*)arg2);
+               return put_user(task->mm->context.untag_mask, (unsigned long 
__user *)arg2);
        case ARCH_ENABLE_TAGGED_ADDR:
                return prctl_enable_tagged_addr(task->mm, arg2);
        case ARCH_FORCE_TAGGED_SVA:
@@ -965,7 +967,7 @@ long do_arch_prctl_64(struct task_struct *task, int option, 
unsigned long arg2)
                if (!cpu_feature_enabled(X86_FEATURE_LAM))
                        return put_user(0, (unsigned long __user *)arg2);
                else
-                       return put_user(LAM_U57_BITS, (unsigned long __user 
*)arg2);
+                       return put_user(LAM_TAG_BITS, (unsigned long __user 
*)arg2);
 #endif
        case ARCH_SHSTK_ENABLE:
        case ARCH_SHSTK_DISABLE:
-- 
2.53.0



Reply via email to