mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	mm/kasan: add support for memory hotplug
KASAN doesn't happen work with memory hotplug because hotplugged memory doesn't have any shadow memory. So any access to hotplugged memory would cause a crash on shadow check. Use memory hotplug notifier to allocate and map shadow memory when the hotplugged memory is going online and free shadow after the memory offlined. Link: http://lkml.kernel.org/r/20170601162338.23540-4-aryabinin@virtuozzo.com Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Alexander Potapenko <glider@google.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Ingo Molnar <mingo@redhat.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Will Deacon <will.deacon@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									3f9ec80f7b
								
							
						
					
					
						commit
						fa69b5989b
					
				
					 2 changed files with 35 additions and 6 deletions
				
			
		|  | @ -161,7 +161,6 @@ config MEMORY_HOTPLUG | |||
| 	bool "Allow for memory hot-add" | ||||
| 	depends on SPARSEMEM || X86_64_ACPI_NUMA | ||||
| 	depends on ARCH_ENABLE_MEMORY_HOTPLUG | ||||
| 	depends on COMPILE_TEST || !KASAN | ||||
| 
 | ||||
| config MEMORY_HOTPLUG_SPARSE | ||||
| 	def_bool y | ||||
|  |  | |||
|  | @ -737,17 +737,47 @@ void __asan_unpoison_stack_memory(const void *addr, size_t size) | |||
| EXPORT_SYMBOL(__asan_unpoison_stack_memory); | ||||
| 
 | ||||
| #ifdef CONFIG_MEMORY_HOTPLUG | ||||
| static int kasan_mem_notifier(struct notifier_block *nb, | ||||
| static int __meminit kasan_mem_notifier(struct notifier_block *nb, | ||||
| 			unsigned long action, void *data) | ||||
| { | ||||
| 	return (action == MEM_GOING_ONLINE) ? NOTIFY_BAD : NOTIFY_OK; | ||||
| 	struct memory_notify *mem_data = data; | ||||
| 	unsigned long nr_shadow_pages, start_kaddr, shadow_start; | ||||
| 	unsigned long shadow_end, shadow_size; | ||||
| 
 | ||||
| 	nr_shadow_pages = mem_data->nr_pages >> KASAN_SHADOW_SCALE_SHIFT; | ||||
| 	start_kaddr = (unsigned long)pfn_to_kaddr(mem_data->start_pfn); | ||||
| 	shadow_start = (unsigned long)kasan_mem_to_shadow((void *)start_kaddr); | ||||
| 	shadow_size = nr_shadow_pages << PAGE_SHIFT; | ||||
| 	shadow_end = shadow_start + shadow_size; | ||||
| 
 | ||||
| 	if (WARN_ON(mem_data->nr_pages % KASAN_SHADOW_SCALE_SIZE) || | ||||
| 		WARN_ON(start_kaddr % (KASAN_SHADOW_SCALE_SIZE << PAGE_SHIFT))) | ||||
| 		return NOTIFY_BAD; | ||||
| 
 | ||||
| 	switch (action) { | ||||
| 	case MEM_GOING_ONLINE: { | ||||
| 		void *ret; | ||||
| 
 | ||||
| 		ret = __vmalloc_node_range(shadow_size, PAGE_SIZE, shadow_start, | ||||
| 					shadow_end, GFP_KERNEL, | ||||
| 					PAGE_KERNEL, VM_NO_GUARD, | ||||
| 					pfn_to_nid(mem_data->start_pfn), | ||||
| 					__builtin_return_address(0)); | ||||
| 		if (!ret) | ||||
| 			return NOTIFY_BAD; | ||||
| 
 | ||||
| 		kmemleak_ignore(ret); | ||||
| 		return NOTIFY_OK; | ||||
| 	} | ||||
| 	case MEM_OFFLINE: | ||||
| 		vfree((void *)shadow_start); | ||||
| 	} | ||||
| 
 | ||||
| 	return NOTIFY_OK; | ||||
| } | ||||
| 
 | ||||
| static int __init kasan_memhotplug_init(void) | ||||
| { | ||||
| 	pr_info("WARNING: KASAN doesn't support memory hot-add\n"); | ||||
| 	pr_info("Memory hot-add will be disabled\n"); | ||||
| 
 | ||||
| 	hotplug_memory_notifier(kasan_mem_notifier, 0); | ||||
| 
 | ||||
| 	return 0; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Andrey Ryabinin
						Andrey Ryabinin