x86/arch_vm: Allow arch_vm_set_memory_type to override type.

We allow requesting an explicit memory type when calling
map_physical_memory but default to the uncached B_MTR_UC when not given.

When called without an explicitly requested memory type, allow
arch_vm_set_memory_type to modify and return an effective memory type.
When an overlapping range already exists, the effective memory type is
set to the one of the existing mapping. If there is an explicit memory
type request that conflicts with an existing range, or if multiple
overlaps with conflicting types would be produced, the mapping is
disallow (and a panic is triggered under KDEBUG).

This effectively detects and panics when conflicting aliases of physical
memory would be created. This is also useful on an MTRR based setup,
as such overlaps cannot be properly represented.

When using the page attribute table (PAT) to set the memory type on a
per page virtual memory mapping basis, this is needed to prevent
aliasing of the same physical memory with different types. As per the
specs, such aliasing is unsupported and may result in undefined
operations that lead to system failure.

The mechanism is extended to the general arch_vm_set_memory_type as such
aliasing prevention also seems to apply to other architectures (at least
on ARM, aliasing is also strongly discouraged).

Change-Id: I7aaf6ea8415e92e74cd1643b67793a6857619eea
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8339
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Michael Lotz
2024-09-17 20:45:28 +00:00
committed by waddlesplash
parent 5a8a2b5066
commit 8271b4a8bf
9 changed files with 85 additions and 46 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ void arch_vm_aspace_swap(struct VMAddressSpace *from,
bool arch_vm_supports_protection(uint32 protection);
status_t arch_vm_set_memory_type(struct VMArea *area, phys_addr_t physicalBase,
uint32 type);
uint32 type, uint32 *effectiveType);
void arch_vm_unset_memory_type(struct VMArea *area);
#ifdef __cplusplus