static inline void dup_lam(struct mm_struct *oldmm, struct mm_struct *mm)
 {
        mm->context.lam_cr3_mask = oldmm->context.lam_cr3_mask;
+       mm->context.untag_mask = oldmm->context.untag_mask;
+}
+
+static inline void mm_reset_untag_mask(struct mm_struct *mm)
+{
+       mm->context.untag_mask = -1UL;
 }
 
 #else
 static inline void dup_lam(struct mm_struct *oldmm, struct mm_struct *mm)
 {
 }
+
+static inline void mm_reset_untag_mask(struct mm_struct *mm)
+{
+}
 #endif
 
 #define enter_lazy_tlb enter_lazy_tlb
                mm->context.execute_only_pkey = -1;
        }
 #endif
+       mm_reset_untag_mask(mm);
        init_new_context_ldt(mm);
        return 0;
 }
 
        local_irq_restore(flags);
 }
 
+#ifdef CONFIG_ADDRESS_MASKING
+DECLARE_PER_CPU(u64, tlbstate_untag_mask);
+
+static inline u64 current_untag_mask(void)
+{
+       return this_cpu_read(tlbstate_untag_mask);
+}
+#endif
+
 #ifndef MODULE
 /*
  * 6 because 6 should be plenty and struct tlb_state will fit in two cache
 {
        this_cpu_write(cpu_tlbstate.lam,
                       mm->context.lam_cr3_mask >> X86_CR3_LAM_U57_BIT);
+       this_cpu_write(tlbstate_untag_mask, mm->context.untag_mask);
 }
 
 #else
 
 #include <linux/compiler.h>
 #include <linux/instrumented.h>
 #include <linux/kasan-checks.h>
+#include <linux/mm_types.h>
 #include <linux/string.h>
 #include <asm/asm.h>
 #include <asm/page.h>
 #include <asm/smap.h>
 #include <asm/extable.h>
+#include <asm/tlbflush.h>
 
 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
 static inline bool pagefault_disabled(void);
 # define WARN_ON_IN_IRQ()
 #endif
 
+#ifdef CONFIG_ADDRESS_MASKING
+/*
+ * Mask out tag bits from the address.
+ *
+ * Magic with the 'sign' allows to untag userspace pointer without any branches
+ * while leaving kernel addresses intact.
+ */
+static inline unsigned long __untagged_addr(unsigned long addr,
+                                           unsigned long mask)
+{
+       long sign = addr >> 63;
+
+       addr &= mask | sign;
+       return addr;
+}
+
+#define untagged_addr(addr)    ({                                      \
+       u64 __addr = (__force u64)(addr);                               \
+       __addr = __untagged_addr(__addr, current_untag_mask());         \
+       (__force __typeof__(addr))__addr;                               \
+})
+
+#define untagged_addr_remote(mm, addr) ({                              \
+       u64 __addr = (__force u64)(addr);                               \
+       mmap_assert_locked(mm);                                         \
+       __addr = __untagged_addr(__addr, (mm)->context.untag_mask);     \
+       (__force __typeof__(addr))__addr;                               \
+})
+
+#else
+#define untagged_addr(addr)    (addr)
+#endif
+
 /**
  * access_ok - Checks if a user space pointer is valid
  * @addr: User space pointer to start of block to check
  * Return: true (nonzero) if the memory block may be valid, false (zero)
  * if it is definitely invalid.
  */
-#define access_ok(addr, size)                                  \
+#define access_ok(addr, size)                                          \
 ({                                                                     \
        WARN_ON_IN_IRQ();                                               \
-       likely(__access_ok(addr, size));                                \
+       likely(__access_ok(untagged_addr(addr), size));                 \
 })
 
 #include <asm-generic/access_ok.h>
 
        .cr4 = ~0UL,    /* fail hard if we screw up cr4 shadow initialization */
 };
 
+#ifdef CONFIG_ADDRESS_MASKING
+DEFINE_PER_CPU(u64, tlbstate_untag_mask);
+EXPORT_PER_CPU_SYMBOL(tlbstate_untag_mask);
+#endif
+
 void update_cache_mode_entry(unsigned entry, enum page_cache_mode cache)
 {
        /* entry 0 MUST be WB (hardwired to speed up translations) */