Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163470415
D55949.id173919.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D55949.id173919.diff
View Options
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
@@ -351,6 +351,7 @@
vm_paddr_t dmap_phys_base; /* The start of the dmap region */
vm_paddr_t dmap_phys_max; /* The limit of the dmap region */
vm_offset_t dmap_max_addr; /* The virtual address limit of the dmap */
+static int dmap_attr = VM_MEMATTR_WRITE_BACK;
extern pt_entry_t pagetable_l0_ttbr1[];
@@ -476,7 +477,7 @@
static bool pmap_activate_int(struct thread *td, pmap_t pmap);
static void pmap_alloc_asid(pmap_t pmap);
static int pmap_change_props_locked(vm_offset_t va, vm_size_t size,
- vm_prot_t prot, int mode, bool skip_unmapped);
+ vm_prot_t prot, int mode, int old_mode, bool skip_unmapped);
static bool pmap_copy_l3c(pmap_t pmap, pt_entry_t *l3p, vm_offset_t va,
pt_entry_t l3e, vm_page_t ml3, struct rwlock **lockp);
static pt_entry_t *pmap_demote_l1(pmap_t pmap, pt_entry_t *l1, vm_offset_t va);
@@ -8090,7 +8091,7 @@
/* Ensure the attributes are as expected for the DMAP region */
PMAP_LOCK(kernel_pmap);
error = pmap_change_props_locked(va, size,
- PROT_READ | PROT_WRITE, VM_MEMATTR_DEFAULT, false);
+ PROT_READ | PROT_WRITE, VM_MEMATTR_DEFAULT, -1, false);
PMAP_UNLOCK(kernel_pmap);
KASSERT(error == 0, ("%s: Failed to reset DMAP attributes: %d",
__func__, error));
@@ -8195,7 +8196,25 @@
int error;
PMAP_LOCK(kernel_pmap);
- error = pmap_change_props_locked(va, size, PROT_NONE, mode, false);
+ error = pmap_change_props_locked(va, size, PROT_NONE, mode, -1, false);
+ PMAP_UNLOCK(kernel_pmap);
+ return (error);
+}
+
+int
+pmap_change_dmap_attr(int mode)
+{
+ int error;
+
+ KASSERT(mode == VM_MEMATTR_WRITE_BACK ||
+ mode == VM_MEMATTR_TAGGED,
+ ("%s: mode %d must be compatible with write-back", __func__, mode));
+
+ PMAP_LOCK(kernel_pmap);
+ error = pmap_change_props_locked(DMAP_MIN_ADDRESS,
+ dmap_max_addr - DMAP_MIN_ADDRESS, PROT_NONE, mode, dmap_attr, true);
+ if (error == 0)
+ dmap_attr = mode;
PMAP_UNLOCK(kernel_pmap);
return (error);
}
@@ -8217,20 +8236,20 @@
return (EINVAL);
PMAP_LOCK(kernel_pmap);
- error = pmap_change_props_locked(va, size, prot, -1, false);
+ error = pmap_change_props_locked(va, size, prot, -1, -1, false);
PMAP_UNLOCK(kernel_pmap);
return (error);
}
static int
pmap_change_props_locked(vm_offset_t va, vm_size_t size, vm_prot_t prot,
- int mode, bool skip_unmapped)
+ int mode, int old_mode, bool skip_unmapped)
{
vm_offset_t base, offset, tmpva, tmpptep;
vm_size_t pte_size;
vm_paddr_t pa;
pt_entry_t pte, *ptep, *newpte;
- pt_entry_t bits, mask;
+ pt_entry_t bits, mask, old_mode_bits, old_mode_mask;
int lvl, rv;
PMAP_LOCK_ASSERT(kernel_pmap, MA_OWNED);
@@ -8242,8 +8261,8 @@
!(base >= VM_MIN_KERNEL_ADDRESS && base < VM_MAX_KERNEL_ADDRESS))
return (EINVAL);
- bits = 0;
- mask = 0;
+ bits = old_mode_bits = 0;
+ mask = old_mode_mask = 0;
if (mode != -1) {
bits = ATTR_S1_IDX(mode);
mask = ATTR_S1_IDX_MASK;
@@ -8252,6 +8271,10 @@
bits |= ATTR_S1_XN;
}
}
+ if (old_mode != -1) {
+ old_mode_bits = ATTR_S1_IDX(old_mode);
+ old_mode_mask = ATTR_S1_IDX_MASK;
+ }
if (prot != VM_PROT_NONE) {
/* Don't mark the DMAP as executable. It never is on arm64. */
if (VIRT_IN_DMAP(base)) {
@@ -8279,7 +8302,8 @@
if (ptep == NULL && !skip_unmapped) {
return (EINVAL);
} else if ((ptep == NULL && skip_unmapped) ||
- (pmap_load(ptep) & mask) == bits) {
+ (pmap_load(ptep) & mask) == bits ||
+ (pmap_load(ptep) & old_mode_mask) != old_mode_bits) {
/*
* We already have the correct attribute or there
* is no memory mapped at this address and we are
@@ -8407,12 +8431,23 @@
pa = PTE_TO_PHYS(pte);
if (!VIRT_IN_DMAP(tmpva) && PHYS_IN_DMAP(pa)) {
+ int dmap_mode;
+
+ /*
+ * When booting on HW with MTE enabled we may
+ * need to swap to a tagged type for the DMAP
+ */
+ if (mode == VM_MEMATTR_WRITE_BACK)
+ dmap_mode = dmap_attr;
+ else
+ dmap_mode = mode;
+
/*
* Keep the DMAP memory in sync.
*/
rv = pmap_change_props_locked(
PHYS_TO_DMAP(pa), pte_size,
- prot, mode, true);
+ prot, dmap_mode, old_mode, true);
if (rv != 0)
return (rv);
}
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
@@ -145,6 +145,7 @@
void pmap_bootstrap_dmap(vm_size_t);
void pmap_bootstrap(void);
int pmap_change_attr(vm_offset_t va, vm_size_t size, int mode);
+int pmap_change_dmap_attr(int);
int pmap_change_prot(vm_offset_t va, vm_size_t size, vm_prot_t prot);
void pmap_kenter(vm_offset_t sva, vm_size_t size, vm_paddr_t pa, int mode);
void pmap_kenter_device(vm_offset_t, vm_size_t, vm_paddr_t);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jul 24, 11:44 AM (9 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35444559
Default Alt Text
D55949.id173919.diff (4 KB)
Attached To
Mode
D55949: arm64: Support changing the DMAP memory type
Attached
Detach File
Event Timeline
Log In to Comment