Skip to content

Commit 3f8fd02

Browse files
joergroedelKAGA-KOKO
authored andcommitted
mm/vmalloc: Sync unmappings in __purge_vmap_area_lazy()
On x86-32 with PTI enabled, parts of the kernel page-tables are not shared between processes. This can cause mappings in the vmalloc/ioremap area to persist in some page-tables after the region is unmapped and released. When the region is re-used the processes with the old mappings do not fault in the new mappings but still access the old ones. This causes undefined behavior, in reality often data corruption, kernel oopses and panics and even spontaneous reboots. Fix this problem by activly syncing unmaps in the vmalloc/ioremap area to all page-tables in the system before the regions can be re-used. References: https://bugzilla.suse.com/show_bug.cgi?id=1118689 Fixes: 5d72b4f ('x86, mm: support huge I/O mapping capability I/F') Signed-off-by: Joerg Roedel <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Dave Hansen <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 8e998fc commit 3f8fd02

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

mm/vmalloc.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,12 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end)
12581258
if (unlikely(valist == NULL))
12591259
return false;
12601260

1261+
/*
1262+
* First make sure the mappings are removed from all page-tables
1263+
* before they are freed.
1264+
*/
1265+
vmalloc_sync_all();
1266+
12611267
/*
12621268
* TODO: to calculate a flush range without looping.
12631269
* The list can be up to lazy_max_pages() elements.
@@ -3038,6 +3044,9 @@ EXPORT_SYMBOL(remap_vmalloc_range);
30383044
/*
30393045
* Implement a stub for vmalloc_sync_all() if the architecture chose not to
30403046
* have one.
3047+
*
3048+
* The purpose of this function is to make sure the vmalloc area
3049+
* mappings are identical in all page-tables in the system.
30413050
*/
30423051
void __weak vmalloc_sync_all(void)
30433052
{

0 commit comments

Comments
 (0)