| From 236e9f1538523d3d380dda1cc99571d587058f37 Mon Sep 17 00:00:00 2001 |
| From: Alexander Potapenko <glider@google.com> |
| Date: Fri, 23 Jul 2021 15:50:14 -0700 |
| Subject: kfence: skip all GFP_ZONEMASK allocations |
| |
| From: Alexander Potapenko <glider@google.com> |
| |
| commit 236e9f1538523d3d380dda1cc99571d587058f37 upstream. |
| |
| Allocation requests outside ZONE_NORMAL (MOVABLE, HIGHMEM or DMA) cannot |
| be fulfilled by KFENCE, because KFENCE memory pool is located in a zone |
| different from the requested one. |
| |
| Because callers of kmem_cache_alloc() may actually rely on the |
| allocation to reside in the requested zone (e.g. memory allocations |
| done with __GFP_DMA must be DMAable), skip all allocations done with |
| GFP_ZONEMASK and/or respective SLAB flags (SLAB_CACHE_DMA and |
| SLAB_CACHE_DMA32). |
| |
| Link: https://lkml.kernel.org/r/20210714092222.1890268-2-glider@google.com |
| Fixes: 0ce20dd84089 ("mm: add Kernel Electric-Fence infrastructure") |
| Signed-off-by: Alexander Potapenko <glider@google.com> |
| Reviewed-by: Marco Elver <elver@google.com> |
| Acked-by: Souptick Joarder <jrdr.linux@gmail.com> |
| Cc: Dmitry Vyukov <dvyukov@google.com> |
| Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Cc: Souptick Joarder <jrdr.linux@gmail.com> |
| Cc: <stable@vger.kernel.org> [5.12+] |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| mm/kfence/core.c | 9 +++++++++ |
| 1 file changed, 9 insertions(+) |
| |
| --- a/mm/kfence/core.c |
| +++ b/mm/kfence/core.c |
| @@ -741,6 +741,15 @@ void *__kfence_alloc(struct kmem_cache * |
| return NULL; |
| |
| /* |
| + * Skip allocations from non-default zones, including DMA. We cannot |
| + * guarantee that pages in the KFENCE pool will have the requested |
| + * properties (e.g. reside in DMAable memory). |
| + */ |
| + if ((flags & GFP_ZONEMASK) || |
| + (s->flags & (SLAB_CACHE_DMA | SLAB_CACHE_DMA32))) |
| + return NULL; |
| + |
| + /* |
| * allocation_gate only needs to become non-zero, so it doesn't make |
| * sense to continue writing to it and pay the associated contention |
| * cost, in case we have a large number of concurrent allocations. |