forked from Minki/linux
arm64: mte: Tags-aware aware memcmp_pages() implementation
When the Memory Tagging Extension is enabled, two pages are identical only if both their data and tags are identical. Make the generic memcmp_pages() a __weak function and add an arm64-specific implementation which returns non-zero if any of the two pages contain valid MTE tags (PG_mte_tagged set). There isn't much benefit in comparing the tags of two pages since these are normally used for heap allocations and likely to differ anyway. Co-developed-by: Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will@kernel.org>
This commit is contained in:
parent
738c8780fc
commit
4d1a8a2dc0
@ -5,6 +5,7 @@
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/thread_info.h>
|
||||
|
||||
#include <asm/cpufeature.h>
|
||||
@ -23,6 +24,31 @@ void mte_sync_tags(pte_t *ptep, pte_t pte)
|
||||
}
|
||||
}
|
||||
|
||||
int memcmp_pages(struct page *page1, struct page *page2)
|
||||
{
|
||||
char *addr1, *addr2;
|
||||
int ret;
|
||||
|
||||
addr1 = page_address(page1);
|
||||
addr2 = page_address(page2);
|
||||
ret = memcmp(addr1, addr2, PAGE_SIZE);
|
||||
|
||||
if (!system_supports_mte() || ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If the page content is identical but at least one of the pages is
|
||||
* tagged, return non-zero to avoid KSM merging. If only one of the
|
||||
* pages is tagged, set_pte_at() may zero or change the tags of the
|
||||
* other page via mte_sync_tags().
|
||||
*/
|
||||
if (test_bit(PG_mte_tagged, &page1->flags) ||
|
||||
test_bit(PG_mte_tagged, &page2->flags))
|
||||
return addr1 != addr2;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void flush_mte_state(void)
|
||||
{
|
||||
if (!system_supports_mte())
|
||||
|
Loading…
Reference in New Issue
Block a user