Page MenuHomeFreeBSD

D57990.diff
No OneTemporary

D57990.diff

diff --git a/sys/arm64/arm64/mte.c b/sys/arm64/arm64/mte.c
--- a/sys/arm64/arm64/mte.c
+++ b/sys/arm64/arm64/mte.c
@@ -94,21 +94,20 @@
if (!MTE_HAS_TAG_CHECK)
return;
- /* don't clear the tags on a page that's already setup for mte */
- if ((page->md.pv_flags & PV_MTE_TAGGED) != 0)
+ /* Don't clear the tags when the page is already clean */
+ if ((atomic_load_8(&page->md.pv_flags) & PV_MTE_CLEAN) == PV_MTE_CLEAN)
return;
block_size = mte_block_size();
addr = PHYS_TO_DMAP(page->phys_addr);
+ atomic_set_8(&page->md.pv_flags, PV_MTE_CLEAN);
for (size_t count = 0; count < PAGE_SIZE;
count += block_size, addr += block_size)
asm volatile(
".arch_extension memtag \n"
"stgm xzr, [%0] \n"
".arch_extension nomemtag" : : "r" (addr));
-
- page->md.pv_flags |= PV_MTE_TAGGED;
}
/**
@@ -121,7 +120,14 @@
size_t block_size;
uint64_t tags;
- MPASS((srcpage->md.pv_flags & PV_MTE_TAGGED) != 0);
+ if (!MTE_HAS_TAG_CHECK)
+ return;
+
+ if ((atomic_load_8(&srcpage->md.pv_flags) & PV_MTE_CLEAN) ==
+ PV_MTE_CLEAN) {
+ mte_sync_tags(dstpage);
+ return;
+ }
/*
* Copy the tags from the source page to the destination page,
@@ -133,7 +139,7 @@
tags = load_tags(src);
set_tags(tags, dst);
}
- dstpage->md.pv_flags |= PV_MTE_TAGGED;
+ atomic_clear_8(&dstpage->md.pv_flags, PV_MTE_CLEAN);
}
void
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -5307,7 +5307,7 @@
int psind)
{
pd_entry_t *l0p, *l1p, *l2p, *l3p, newpte, origpte, *tl3p;
- vm_page_t mp;
+ vm_page_t m, mp, mt;
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
KASSERT(psind > 0 && psind < MAXPAGESIZES,
@@ -5353,6 +5353,17 @@
(origpte & ATTR_DESCR_VALID) == 0,
("va %#lx changing 1G phys page l1 %#lx newpte %#lx",
va, origpte, newpte));
+ /*
+ * If creating an MTE entry mark the physical memory as
+ * MTE dirty
+ */
+ if ((newpte & ATTR_S1_IDX_MASK) ==
+ ATTR_S1_IDX(VM_MEMATTR_TAGGED)) {
+ m = PHYS_TO_VM_PAGE(PTE_TO_PHYS(newpte));
+ for (mt = m; mt < &m[L1_SIZE / PAGE_SIZE]; mt++) {
+ atomic_clear_8(&mt->md.pv_flags, PV_MTE_CLEAN);
+ }
+ }
pmap_store(l1p, newpte);
} else if (psind == 2) {
KASSERT(pagesizes[psind] == L2_SIZE,
@@ -5384,6 +5395,17 @@
PTE_TO_PHYS(origpte) == PTE_TO_PHYS(newpte)),
("va %#lx changing 2M phys page l2 %#lx newpte %#lx",
va, origpte, newpte));
+ /*
+ * If creating an MTE entry mark the physical memory as
+ * MTE dirty
+ */
+ if ((newpte & ATTR_S1_IDX_MASK) ==
+ ATTR_S1_IDX(VM_MEMATTR_TAGGED)) {
+ m = PHYS_TO_VM_PAGE(PTE_TO_PHYS(newpte));
+ for (mt = m; mt < &m[L2_SIZE / PAGE_SIZE]; mt++) {
+ atomic_clear_8(&mt->md.pv_flags, PV_MTE_CLEAN);
+ }
+ }
pmap_store(l2p, newpte);
} else /* (psind == 1) */ {
KASSERT(pagesizes[psind] == L3C_SIZE,
@@ -5409,6 +5431,17 @@
mp->ref_count += L3C_ENTRIES;
}
}
+ /*
+ * If creating an MTE entry mark the physical memory as
+ * MTE dirty
+ */
+ if ((newpte & ATTR_S1_IDX_MASK) ==
+ ATTR_S1_IDX(VM_MEMATTR_TAGGED)) {
+ m = PHYS_TO_VM_PAGE(PTE_TO_PHYS(newpte));
+ for (mt = m; mt < &m[L3C_SIZE / PAGE_SIZE]; mt++) {
+ atomic_clear_8(&mt->md.pv_flags, PV_MTE_CLEAN);
+ }
+ }
for (tl3p = l3p; tl3p < &l3p[L3C_ENTRIES]; tl3p++) {
origpte = pmap_load(tl3p);
KASSERT((origpte & ATTR_DESCR_VALID) == 0 ||
@@ -5787,6 +5820,9 @@
}
} else {
/* New mapping */
+ if ((new_l3 & ATTR_S1_IDX_MASK) ==
+ ATTR_S1_IDX(VM_MEMATTR_TAGGED))
+ atomic_clear_8(&m->md.pv_flags, PV_MTE_CLEAN);
pmap_store(l3, new_l3);
dsb(ishst);
}
@@ -6067,6 +6103,13 @@
L2_SIZE);
}
+ /* If creating an MTE entry mark the physical memory as MTE dirty */
+ if ((new_l2 & ATTR_S1_IDX_MASK) == ATTR_S1_IDX(VM_MEMATTR_TAGGED)) {
+ for (mt = m; mt < &m[L2_SIZE / PAGE_SIZE]; mt++) {
+ atomic_clear_8(&mt->md.pv_flags, PV_MTE_CLEAN);
+ }
+ }
+
/*
* Map the superpage.
*/
@@ -6292,6 +6335,13 @@
m->md.pv_memattr == VM_MEMATTR_WRITE_BACK)
cpu_icache_sync_range(PHYS_TO_DMAP(pa), L3C_SIZE);
+ /* If creating an MTE entry mark the physical memory as MTE dirty */
+ if ((l3e & ATTR_S1_IDX_MASK) == ATTR_S1_IDX(VM_MEMATTR_TAGGED)) {
+ for (mt = m; mt < &m[L3C_SIZE / PAGE_SIZE]; mt++) {
+ atomic_clear_8(&mt->md.pv_flags, PV_MTE_CLEAN);
+ }
+ }
+
/*
* Map the superpage.
*/
@@ -6519,6 +6569,9 @@
m->md.pv_memattr == VM_MEMATTR_WRITE_BACK)
cpu_icache_sync_range(PHYS_TO_DMAP(pa), PAGE_SIZE);
+ if ((l3_val & ATTR_S1_IDX_MASK) == ATTR_S1_IDX(VM_MEMATTR_TAGGED))
+ atomic_clear_8(&m->md.pv_flags, PV_MTE_CLEAN);
+
pmap_store(l3, l3_val);
dsb(ishst);
@@ -6965,7 +7018,7 @@
void *va = VM_PAGE_TO_DMAP(m);
pagezero(va);
- m->md.pv_flags &= ~PV_MTE_TAGGED;
+ mte_sync_tags(m);
}
/*
@@ -6997,14 +7050,8 @@
void *src = VM_PAGE_TO_DMAP(msrc);
void *dst = VM_PAGE_TO_DMAP(mdst);
- /*
- * On a page copy, check whether the src page is tagged. If it is,
- * we must copy the tags before copying the contents of the page.
- */
- if ((msrc->md.pv_flags & PV_MTE_TAGGED) != 0)
- mte_copy_tags(msrc, mdst, src, dst);
- else
- mdst->md.pv_flags &= ~PV_MTE_TAGGED;
+ /* Ensure the tags are coppied */
+ mte_copy_tags(msrc, mdst, src, dst);
pagecopy(src, dst);
}
diff --git a/sys/arm64/include/pmap.h b/sys/arm64/include/pmap.h
--- a/sys/arm64/include/pmap.h
+++ b/sys/arm64/include/pmap.h
@@ -75,7 +75,7 @@
};
/* machine page flags */
-#define PV_MTE_TAGGED 0x01 /* page is tagged with MTE */
+#define PV_MTE_CLEAN 0x01 /* MTE tags are clean, i.e. zero'd */
enum pmap_stage {
PM_INVALID,

File Metadata

Mime Type
text/plain
Expires
Tue, Jul 7, 4:09 AM (17 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34747478
Default Alt Text
D57990.diff (5 KB)

Event Timeline