memtype_reserve() and memtype_free() pass their physical addresses through sanitize_phys(). Both take an exclusive end address, but sanitize_phys() expects an inclusive one. So this has the effect that for a range that ends exactly at the top of the physical address space, the mask turns the end into 0. As a result the ISA range check succeeds and memtype_free() returns 0 without removing the reservation. A new reservation that overlaps existing entries takes on their memory type, so the stale entry goes on choosing the cache mode for that range. Let's fix this by doing some annoying off by one twiddling. Fixes: aeef8b5089b7 ("x86/pat: Pass valid address to sanitize_phys()") Cc: Signed-off-by: Chris Down --- arch/x86/mm/pat/memtype.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c index cf94fb561310..007d833b4c00 100644 --- a/arch/x86/mm/pat/memtype.c +++ b/arch/x86/mm/pat/memtype.c @@ -613,7 +613,7 @@ int memtype_free(u64 start, u64 end) return 0; start = sanitize_phys(start); - end = sanitize_phys(end); + end = sanitize_phys(end - 1) + 1; /* Low ISA region is always mapped WB. No need to track */ if (x86_platform.is_untracked_pat_range(start, end)) base-commit: 5cdc3746fa163fb4e8d05fa3cabf46bc6aa7df75