[PATCH v6 06/18] x86/kasan: Add arch specific kasan functions

Maciej Wieczor-Retman posted 18 patches 1 month, 2 weeks ago
There is a newer version of this series
[PATCH v6 06/18] x86/kasan: Add arch specific kasan functions
Posted by Maciej Wieczor-Retman 1 month, 2 weeks ago
From: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>

KASAN's software tag-based mode needs multiple macros/functions to
handle tag and pointer interactions - to set, retrieve and reset tags
from the top bits of a pointer.

Mimic functions currently used by arm64 but change the tag's position to
bits [60:57] in the pointer.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Acked-by: Andrey Konovalov <andreyknvl@gmail.com>
---
Changelog v6:
- Remove empty line after ifdef CONFIG_KASAN_SW_TAGS
- Add ifdef 64 bit to avoid problems in vdso32.
- Add Andrey's Acked-by tag.

Changelog v4:
- Rewrite __tag_set() without pointless casts and make it more readable.

Changelog v3:
- Reorder functions so that __tag_*() etc are above the
  arch_kasan_*() ones.
- Remove CONFIG_KASAN condition from __tag_set()

 arch/x86/include/asm/kasan.h | 42 ++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h
index d7e33c7f096b..396071832d02 100644
--- a/arch/x86/include/asm/kasan.h
+++ b/arch/x86/include/asm/kasan.h
@@ -3,6 +3,8 @@
 #define _ASM_X86_KASAN_H
 
 #include <linux/const.h>
+#include <linux/kasan-tags.h>
+#include <linux/types.h>
 #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
 #define KASAN_SHADOW_SCALE_SHIFT 3
 
@@ -24,8 +26,43 @@
 						  KASAN_SHADOW_SCALE_SHIFT)))
 
 #ifndef __ASSEMBLER__
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+
+#ifdef CONFIG_KASAN_SW_TAGS
+#define __tag_shifted(tag)		FIELD_PREP(GENMASK_ULL(60, 57), tag)
+#define __tag_reset(addr)		(sign_extend64((u64)(addr), 56))
+#define __tag_get(addr)			((u8)FIELD_GET(GENMASK_ULL(60, 57), (u64)addr))
+#else
+#define __tag_shifted(tag)		0UL
+#define __tag_reset(addr)		(addr)
+#define __tag_get(addr)			0
+#endif /* CONFIG_KASAN_SW_TAGS */
+
+#ifdef CONFIG_64BIT
+static inline void *__tag_set(const void *__addr, u8 tag)
+{
+	u64 addr = (u64)__addr;
+
+	addr &= ~__tag_shifted(KASAN_TAG_MASK);
+	addr |= __tag_shifted(tag);
+
+	return (void *)addr;
+}
+#else
+static inline void *__tag_set(void *__addr, u8 tag)
+{
+	return __addr;
+}
+#endif
+
+#define arch_kasan_set_tag(addr, tag)	__tag_set(addr, tag)
+#define arch_kasan_reset_tag(addr)	__tag_reset(addr)
+#define arch_kasan_get_tag(addr)	__tag_get(addr)
 
 #ifdef CONFIG_KASAN
+
 void __init kasan_early_init(void);
 void __init kasan_init(void);
 void __init kasan_populate_shadow_for_vaddr(void *va, size_t size, int nid);
@@ -34,8 +71,9 @@ static inline void kasan_early_init(void) { }
 static inline void kasan_init(void) { }
 static inline void kasan_populate_shadow_for_vaddr(void *va, size_t size,
 						   int nid) { }
-#endif
 
-#endif
+#endif /* CONFIG_KASAN */
+
+#endif /* __ASSEMBLER__ */
 
 #endif
-- 
2.51.0
Re: [PATCH v6 06/18] x86/kasan: Add arch specific kasan functions
Posted by Alexander Potapenko 1 month ago
> +#ifdef CONFIG_64BIT
> +static inline void *__tag_set(const void *__addr, u8 tag)
> +{
> +       u64 addr = (u64)__addr;
> +
> +       addr &= ~__tag_shifted(KASAN_TAG_MASK);

KASAN_TAG_MASK is only defined in Patch 07, does this patch compile?
Re: [PATCH v6 06/18] x86/kasan: Add arch specific kasan functions
Posted by Maciej Wieczór-Retman 3 weeks, 5 days ago
On 2025-11-11 at 10:31:13 +0100, Alexander Potapenko wrote:
>> +#ifdef CONFIG_64BIT
>> +static inline void *__tag_set(const void *__addr, u8 tag)
>> +{
>> +       u64 addr = (u64)__addr;
>> +
>> +       addr &= ~__tag_shifted(KASAN_TAG_MASK);
>
>KASAN_TAG_MASK is only defined in Patch 07, does this patch compile?

Seems I forgot to remove it from patch 7. It's originally defined
in the mmzone.h file and looked cleaner there according to Andrey.

Thanks for noticing it's still in patch 7, I'll get rid of it.
Re: [PATCH v6 06/18] x86/kasan: Add arch specific kasan functions
Posted by Maciej Wieczór-Retman 3 weeks, 4 days ago
On 2025-11-17 at 18:41:35 +0000, Maciej Wieczór-Retman wrote:
>On 2025-11-11 at 10:31:13 +0100, Alexander Potapenko wrote:
>>> +#ifdef CONFIG_64BIT
>>> +static inline void *__tag_set(const void *__addr, u8 tag)
>>> +{
>>> +       u64 addr = (u64)__addr;
>>> +
>>> +       addr &= ~__tag_shifted(KASAN_TAG_MASK);
>>
>>KASAN_TAG_MASK is only defined in Patch 07, does this patch compile?
>
>Seems I forgot to remove it from patch 7. It's originally defined
>in the mmzone.h file and looked cleaner there according to Andrey.
>
>Thanks for noticing it's still in patch 7, I'll get rid of it.

You were right before, after removing that define in patch 7 it doesn't
compile. I think I'll just open code this definition here:

>>> +       addr &= ~__tag_shifted((1UL << KASAN_TAG_WIDTH) - 1);

I don't see a nicer solution here if taking things from mmzone.h is out
of the question. I suppose a #ifndef KASAN_TAG_MASK placed here that
would just shadow the one in mmzone.h could work too?