mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 14:42:08 +02:00
Merge branch 'for-next/mte' into for-next/core
* for-next/mte: arm64: kasan: Revert "arm64: mte: reset the page tag in page->flags" mm: kasan: Skip page unpoisoning only if __GFP_SKIP_KASAN_UNPOISON mm: kasan: Skip unpoisoning of user pages mm: kasan: Ensure the tags are visible before the tag in page->flags
This commit is contained in:
commit
c436500d9f
|
|
@ -300,11 +300,6 @@ static void swsusp_mte_restore_tags(void)
|
|||
unsigned long pfn = xa_state.xa_index;
|
||||
struct page *page = pfn_to_online_page(pfn);
|
||||
|
||||
/*
|
||||
* It is not required to invoke page_kasan_tag_reset(page)
|
||||
* at this point since the tags stored in page->flags are
|
||||
* already restored.
|
||||
*/
|
||||
mte_restore_page_tags(page_address(page), tags);
|
||||
|
||||
mte_free_tag_storage(tags);
|
||||
|
|
|
|||
|
|
@ -48,15 +48,6 @@ static void mte_sync_page_tags(struct page *page, pte_t old_pte,
|
|||
if (!pte_is_tagged)
|
||||
return;
|
||||
|
||||
page_kasan_tag_reset(page);
|
||||
/*
|
||||
* We need smp_wmb() in between setting the flags and clearing the
|
||||
* tags because if another thread reads page->flags and builds a
|
||||
* tagged address out of it, there is an actual dependency to the
|
||||
* memory access, but on the current thread we do not guarantee that
|
||||
* the new page->flags are visible before the tags were updated.
|
||||
*/
|
||||
smp_wmb();
|
||||
mte_clear_page_tags(page_address(page));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,15 +23,6 @@ void copy_highpage(struct page *to, struct page *from)
|
|||
|
||||
if (system_supports_mte() && test_bit(PG_mte_tagged, &from->flags)) {
|
||||
set_bit(PG_mte_tagged, &to->flags);
|
||||
page_kasan_tag_reset(to);
|
||||
/*
|
||||
* We need smp_wmb() in between setting the flags and clearing the
|
||||
* tags because if another thread reads page->flags and builds a
|
||||
* tagged address out of it, there is an actual dependency to the
|
||||
* memory access, but on the current thread we do not guarantee that
|
||||
* the new page->flags are visible before the tags were updated.
|
||||
*/
|
||||
smp_wmb();
|
||||
mte_copy_page_tags(kto, kfrom);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -927,6 +927,5 @@ struct page *alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma,
|
|||
void tag_clear_highpage(struct page *page)
|
||||
{
|
||||
mte_zero_clear_page_tags(page_address(page));
|
||||
page_kasan_tag_reset(page);
|
||||
set_bit(PG_mte_tagged, &page->flags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,15 +53,6 @@ bool mte_restore_tags(swp_entry_t entry, struct page *page)
|
|||
if (!tags)
|
||||
return false;
|
||||
|
||||
page_kasan_tag_reset(page);
|
||||
/*
|
||||
* We need smp_wmb() in between setting the flags and clearing the
|
||||
* tags because if another thread reads page->flags and builds a
|
||||
* tagged address out of it, there is an actual dependency to the
|
||||
* memory access, but on the current thread we do not guarantee that
|
||||
* the new page->flags are visible before the tags were updated.
|
||||
*/
|
||||
smp_wmb();
|
||||
mte_restore_page_tags(page_address(page), tags);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ struct vm_area_struct;
|
|||
#define GFP_DMA32 __GFP_DMA32
|
||||
#define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM)
|
||||
#define GFP_HIGHUSER_MOVABLE (GFP_HIGHUSER | __GFP_MOVABLE | \
|
||||
__GFP_SKIP_KASAN_POISON)
|
||||
__GFP_SKIP_KASAN_POISON | __GFP_SKIP_KASAN_UNPOISON)
|
||||
#define GFP_TRANSHUGE_LIGHT ((GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
|
||||
__GFP_NOMEMALLOC | __GFP_NOWARN) & ~__GFP_RECLAIM)
|
||||
#define GFP_TRANSHUGE (GFP_TRANSHUGE_LIGHT | __GFP_DIRECT_RECLAIM)
|
||||
|
|
|
|||
|
|
@ -108,9 +108,10 @@ void __kasan_unpoison_pages(struct page *page, unsigned int order, bool init)
|
|||
return;
|
||||
|
||||
tag = kasan_random_tag();
|
||||
kasan_unpoison(set_tag(page_address(page), tag),
|
||||
PAGE_SIZE << order, init);
|
||||
for (i = 0; i < (1 << order); i++)
|
||||
page_kasan_tag_set(page + i, tag);
|
||||
kasan_unpoison(page_address(page), PAGE_SIZE << order, init);
|
||||
}
|
||||
|
||||
void __kasan_poison_pages(struct page *page, unsigned int order, bool init)
|
||||
|
|
|
|||
|
|
@ -2361,7 +2361,7 @@ static inline bool check_new_pcp(struct page *page, unsigned int order)
|
|||
}
|
||||
#endif /* CONFIG_DEBUG_VM */
|
||||
|
||||
static inline bool should_skip_kasan_unpoison(gfp_t flags, bool init_tags)
|
||||
static inline bool should_skip_kasan_unpoison(gfp_t flags)
|
||||
{
|
||||
/* Don't skip if a software KASAN mode is enabled. */
|
||||
if (IS_ENABLED(CONFIG_KASAN_GENERIC) ||
|
||||
|
|
@ -2373,12 +2373,10 @@ static inline bool should_skip_kasan_unpoison(gfp_t flags, bool init_tags)
|
|||
return true;
|
||||
|
||||
/*
|
||||
* With hardware tag-based KASAN enabled, skip if either:
|
||||
*
|
||||
* 1. Memory tags have already been cleared via tag_clear_highpage().
|
||||
* 2. Skipping has been requested via __GFP_SKIP_KASAN_UNPOISON.
|
||||
* With hardware tag-based KASAN enabled, skip if this has been
|
||||
* requested via __GFP_SKIP_KASAN_UNPOISON.
|
||||
*/
|
||||
return init_tags || (flags & __GFP_SKIP_KASAN_UNPOISON);
|
||||
return flags & __GFP_SKIP_KASAN_UNPOISON;
|
||||
}
|
||||
|
||||
static inline bool should_skip_init(gfp_t flags)
|
||||
|
|
@ -2397,6 +2395,7 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
|
|||
bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags) &&
|
||||
!should_skip_init(gfp_flags);
|
||||
bool init_tags = init && (gfp_flags & __GFP_ZEROTAGS);
|
||||
int i;
|
||||
|
||||
set_page_private(page, 0);
|
||||
set_page_refcounted(page);
|
||||
|
|
@ -2422,8 +2421,6 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
|
|||
* should be initialized as well).
|
||||
*/
|
||||
if (init_tags) {
|
||||
int i;
|
||||
|
||||
/* Initialize both memory and tags. */
|
||||
for (i = 0; i != 1 << order; ++i)
|
||||
tag_clear_highpage(page + i);
|
||||
|
|
@ -2431,13 +2428,17 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
|
|||
/* Note that memory is already initialized by the loop above. */
|
||||
init = false;
|
||||
}
|
||||
if (!should_skip_kasan_unpoison(gfp_flags, init_tags)) {
|
||||
if (!should_skip_kasan_unpoison(gfp_flags)) {
|
||||
/* Unpoison shadow memory or set memory tags. */
|
||||
kasan_unpoison_pages(page, order, init);
|
||||
|
||||
/* Note that memory is already initialized by KASAN. */
|
||||
if (kasan_has_integrated_init())
|
||||
init = false;
|
||||
} else {
|
||||
/* Ensure page_address() dereferencing does not fault. */
|
||||
for (i = 0; i != 1 << order; ++i)
|
||||
page_kasan_tag_reset(page + i);
|
||||
}
|
||||
/* If memory is still not initialized, do it now. */
|
||||
if (init)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user