Similarly to kmsan_vmap_pages_range_noflush(), kmsan_ioremap_page_range() must also properly handle allocation/mapping failures. In the case of such, it must clean up the already created metadata mappings and return an error code, so that the error can be propagated to ioremap_page_range(). Without doing so, KMSAN may silently fail to bring the metadata for the page range into a consistent state, which will result in user-visible crashes when trying to access them.
Showing the changes to include (1 of 3 files). Show all
Unified · Split
| @@ -160,11 +160,12 @@ void kmsan_vunmap_range_noflush(unsigned long start, unsigned long end); · 159 unmodified lines | |||
| 160 | * @page_shift: page_shift argument passed to vmap_range_noflush(). | 160 | * @page_shift: page_shift argument passed to vmap_range_noflush(). |
| 161 | * | 161 | * |
| 162 | * KMSAN creates new metadata pages for the physical pages mapped into the | 162 | * KMSAN creates new metadata pages for the physical pages mapped into the |
| 163 | * virtual memory. | 163 | * virtual memory. Returns 0 on success, callers must check for non-zero return |
| 164 | * value. | ||
| 164 | */ | 165 | */ |
| 165 | void kmsan_ioremap_page_range(unsigned long addr, unsigned long end, | 166 | int kmsan_ioremap_page_range(unsigned long addr, unsigned long end, |
| 166 | phys_addr_t phys_addr, pgprot_t prot, | 167 | phys_addr_t phys_addr, pgprot_t prot, |
| 167 | unsigned int page_shift); | 168 | unsigned int page_shift); |
| 168 | 169 | ||
| 169 | /** | 170 | /** |
| 170 | * kmsan_iounmap_page_range() - Notify KMSAN about a iounmap_page_range() call. | 171 | * kmsan_iounmap_page_range() - Notify KMSAN about a iounmap_page_range() call. |
| @@ -296,12 +297,12 @@ static inline void kmsan_vunmap_range_noflush(unsigned long start, · 125 unmodified lines | |||
| 296 | { | 297 | { |
| 297 | } | 298 | } |
| 298 | 299 | ||
| 299 | static inline void kmsan_ioremap_page_range(unsigned long start, | 300 | static inline int kmsan_ioremap_page_range(unsigned long start, |
| 300 | unsigned long end, | 301 | unsigned long end, |
| 301 | phys_addr_t phys_addr, | 302 | phys_addr_t phys_addr, pgprot_t prot, |
| 302 | pgprot_t prot, | 303 | unsigned int page_shift) |
| 303 | unsigned int page_shift) | ||
| 304 | { | 304 | { |
| 305 | return 0; | ||
| 305 | } | 306 | } |
| 306 | 307 | ||
| 307 | static inline void kmsan_iounmap_page_range(unsigned long start, | 308 | static inline void kmsan_iounmap_page_range(unsigned long start, |