diff options
Diffstat (limited to 'mm/kmsan/shadow.c')
| -rw-r--r-- | mm/kmsan/shadow.c | 27 | 
1 files changed, 18 insertions, 9 deletions
diff --git a/mm/kmsan/shadow.c b/mm/kmsan/shadow.c index a787c04e9583..b8bb95eea5e3 100644 --- a/mm/kmsan/shadow.c +++ b/mm/kmsan/shadow.c @@ -216,27 +216,29 @@ void kmsan_free_page(struct page *page, unsigned int order)  	kmsan_leave_runtime();  } -void kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end, -				    pgprot_t prot, struct page **pages, -				    unsigned int page_shift) +int kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end, +				   pgprot_t prot, struct page **pages, +				   unsigned int page_shift)  {  	unsigned long shadow_start, origin_start, shadow_end, origin_end;  	struct page **s_pages, **o_pages; -	int nr, mapped; +	int nr, mapped, err = 0;  	if (!kmsan_enabled) -		return; +		return 0;  	shadow_start = vmalloc_meta((void *)start, KMSAN_META_SHADOW);  	shadow_end = vmalloc_meta((void *)end, KMSAN_META_SHADOW);  	if (!shadow_start) -		return; +		return 0;  	nr = (end - start) / PAGE_SIZE;  	s_pages = kcalloc(nr, sizeof(*s_pages), GFP_KERNEL);  	o_pages = kcalloc(nr, sizeof(*o_pages), GFP_KERNEL); -	if (!s_pages || !o_pages) +	if (!s_pages || !o_pages) { +		err = -ENOMEM;  		goto ret; +	}  	for (int i = 0; i < nr; i++) {  		s_pages[i] = shadow_page_for(pages[i]);  		o_pages[i] = origin_page_for(pages[i]); @@ -249,10 +251,16 @@ void kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end,  	kmsan_enter_runtime();  	mapped = __vmap_pages_range_noflush(shadow_start, shadow_end, prot,  					    s_pages, page_shift); -	KMSAN_WARN_ON(mapped); +	if (mapped) { +		err = mapped; +		goto ret; +	}  	mapped = __vmap_pages_range_noflush(origin_start, origin_end, prot,  					    o_pages, page_shift); -	KMSAN_WARN_ON(mapped); +	if (mapped) { +		err = mapped; +		goto ret; +	}  	kmsan_leave_runtime();  	flush_tlb_kernel_range(shadow_start, shadow_end);  	flush_tlb_kernel_range(origin_start, origin_end); @@ -262,6 +270,7 @@ void kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end,  ret:  	kfree(s_pages);  	kfree(o_pages); +	return err;  }  /* Allocate metadata for pages allocated at boot time. */  |