* [PATCH 0/3] kfence: fix pool allocation failure handling
@ 2026-10-26 12:23 ` Jackie Liu
0 siblings, 0 replies; 15+ messages in thread
From: Jackie Liu @ 2026-10-26 12:23 UTC (permalink / raw)
To: glider
Cc: dvyukov, elver, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song, liu.yun
From: Jackie Liu <liuyun01@kylinos.cn>
Fix the cleanup address and page reuse window in failed late KFENCE
initialization. Also let RISC-V boot if the early pool reservation fails.
Patch 2 depends on patch 1. Patch 3 can be applied independently.
Validation: source review, git diff --check, and checkpatch.pl --strict.
OpenAI Codex assisted with review, adaptation, and commit wording.
Jackie Liu (3):
kfence: fix pool cleanup on metadata allocation failure
kfence: clear the pool pointer before freeing pages
riscv: keep booting if KFENCE pool reservation fails
arch/riscv/include/asm/kfence.h | 4 +++-
arch/riscv/mm/init.c | 19 +++++++++++++++----
mm/kfence/core.c | 6 ++++--
3 files changed, 22 insertions(+), 7 deletions(-)
base-commit: 7be4bc52fd9e0e55dc9a2e0232b89427d2c4b614
--
2.56.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 0/3] kfence: fix pool allocation failure handling
@ 2026-10-26 12:23 ` Jackie Liu
0 siblings, 0 replies; 15+ messages in thread
From: Jackie Liu @ 2026-10-26 12:23 UTC (permalink / raw)
To: glider
Cc: dvyukov, elver, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song, liu.yun
From: Jackie Liu <liuyun01@kylinos.cn>
Fix the cleanup address and page reuse window in failed late KFENCE
initialization. Also let RISC-V boot if the early pool reservation fails.
Patch 2 depends on patch 1. Patch 3 can be applied independently.
Validation: source review, git diff --check, and checkpatch.pl --strict.
OpenAI Codex assisted with review, adaptation, and commit wording.
Jackie Liu (3):
kfence: fix pool cleanup on metadata allocation failure
kfence: clear the pool pointer before freeing pages
riscv: keep booting if KFENCE pool reservation fails
arch/riscv/include/asm/kfence.h | 4 +++-
arch/riscv/mm/init.c | 19 +++++++++++++++----
mm/kfence/core.c | 6 ++++--
3 files changed, 22 insertions(+), 7 deletions(-)
base-commit: 7be4bc52fd9e0e55dc9a2e0232b89427d2c4b614
--
2.56.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 1/3] kfence: fix pool cleanup on metadata allocation failure
2026-10-26 12:23 ` Jackie Liu
@ 2026-10-26 12:23 ` Jackie Liu
-1 siblings, 0 replies; 15+ messages in thread
From: Jackie Liu @ 2026-10-26 12:23 UTC (permalink / raw)
To: glider
Cc: dvyukov, elver, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song, liu.yun
From: Jackie Liu <liuyun01@kylinos.cn>
kfence_init_late() saves __kfence_pool in addr before allocating the pool,
so addr is still NULL if metadata allocation fails. The error path then
tries to free pages using that address.
Set addr after pool allocation so cleanup frees the allocated pool.
Fixes: cabdf74e6b31 ("mm: kfence: allocate kfence_metadata at runtime")
Cc: stable@vger.kernel.org
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
---
mm/kfence/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 90925c646c4c..6e3d01bccdf1 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -999,7 +999,7 @@ static int kfence_init_late(void)
{
const unsigned long nr_pages_pool = KFENCE_POOL_SIZE / PAGE_SIZE;
const unsigned long nr_pages_meta = KFENCE_METADATA_SIZE / PAGE_SIZE;
- unsigned long addr = (unsigned long)__kfence_pool;
+ unsigned long addr;
unsigned long free_size = KFENCE_POOL_SIZE;
int err = -ENOMEM;
@@ -1032,6 +1032,7 @@ static int kfence_init_late(void)
GFP_KERNEL | __GFP_SKIP_KASAN);
#endif
+ addr = (unsigned long)__kfence_pool;
if (!kfence_metadata_init)
goto free_pool;
--
2.56.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 1/3] kfence: fix pool cleanup on metadata allocation failure
@ 2026-10-26 12:23 ` Jackie Liu
0 siblings, 0 replies; 15+ messages in thread
From: Jackie Liu @ 2026-10-26 12:23 UTC (permalink / raw)
To: glider
Cc: dvyukov, elver, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song, liu.yun
From: Jackie Liu <liuyun01@kylinos.cn>
kfence_init_late() saves __kfence_pool in addr before allocating the pool,
so addr is still NULL if metadata allocation fails. The error path then
tries to free pages using that address.
Set addr after pool allocation so cleanup frees the allocated pool.
Fixes: cabdf74e6b31 ("mm: kfence: allocate kfence_metadata at runtime")
Cc: stable@vger.kernel.org
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
---
mm/kfence/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 90925c646c4c..6e3d01bccdf1 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -999,7 +999,7 @@ static int kfence_init_late(void)
{
const unsigned long nr_pages_pool = KFENCE_POOL_SIZE / PAGE_SIZE;
const unsigned long nr_pages_meta = KFENCE_METADATA_SIZE / PAGE_SIZE;
- unsigned long addr = (unsigned long)__kfence_pool;
+ unsigned long addr;
unsigned long free_size = KFENCE_POOL_SIZE;
int err = -ENOMEM;
@@ -1032,6 +1032,7 @@ static int kfence_init_late(void)
GFP_KERNEL | __GFP_SKIP_KASAN);
#endif
+ addr = (unsigned long)__kfence_pool;
if (!kfence_metadata_init)
goto free_pool;
--
2.56.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/3] kfence: clear the pool pointer before freeing pages
2026-10-26 12:23 ` Jackie Liu
@ 2026-10-26 12:23 ` Jackie Liu
-1 siblings, 0 replies; 15+ messages in thread
From: Jackie Liu @ 2026-10-26 12:23 UTC (permalink / raw)
To: glider
Cc: dvyukov, elver, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song, liu.yun
From: Jackie Liu <liuyun01@kylinos.cn>
Late initialization frees a failed pool before clearing __kfence_pool.
Slab allocations can reuse those pages in between and be mistaken for
KFENCE objects by is_kfence_address(), even though KFENCE is not enabled.
Clear __kfence_pool before freeing the pages, and use the saved address
for cleanup.
Fixes: b33f778bba5e ("kfence: alloc kfence_pool after system startup")
Cc: stable@vger.kernel.org
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
---
mm/kfence/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 6e3d01bccdf1..434df6cef7f2 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -1052,16 +1052,17 @@ static int kfence_init_late(void)
free_contig_range(page_to_pfn(virt_to_page((void *)kfence_metadata_init)),
nr_pages_meta);
free_pool:
+ WRITE_ONCE(__kfence_pool, NULL);
free_contig_range(page_to_pfn(virt_to_page((void *)addr)),
free_size / PAGE_SIZE);
#else
free_pages_exact((void *)kfence_metadata_init, KFENCE_METADATA_SIZE);
free_pool:
+ WRITE_ONCE(__kfence_pool, NULL);
free_pages_exact((void *)addr, free_size);
#endif
kfence_metadata_init = NULL;
- __kfence_pool = NULL;
return err;
}
--
2.56.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/3] kfence: clear the pool pointer before freeing pages
@ 2026-10-26 12:23 ` Jackie Liu
0 siblings, 0 replies; 15+ messages in thread
From: Jackie Liu @ 2026-10-26 12:23 UTC (permalink / raw)
To: glider
Cc: dvyukov, elver, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song, liu.yun
From: Jackie Liu <liuyun01@kylinos.cn>
Late initialization frees a failed pool before clearing __kfence_pool.
Slab allocations can reuse those pages in between and be mistaken for
KFENCE objects by is_kfence_address(), even though KFENCE is not enabled.
Clear __kfence_pool before freeing the pages, and use the saved address
for cleanup.
Fixes: b33f778bba5e ("kfence: alloc kfence_pool after system startup")
Cc: stable@vger.kernel.org
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
---
mm/kfence/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 6e3d01bccdf1..434df6cef7f2 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -1052,16 +1052,17 @@ static int kfence_init_late(void)
free_contig_range(page_to_pfn(virt_to_page((void *)kfence_metadata_init)),
nr_pages_meta);
free_pool:
+ WRITE_ONCE(__kfence_pool, NULL);
free_contig_range(page_to_pfn(virt_to_page((void *)addr)),
free_size / PAGE_SIZE);
#else
free_pages_exact((void *)kfence_metadata_init, KFENCE_METADATA_SIZE);
free_pool:
+ WRITE_ONCE(__kfence_pool, NULL);
free_pages_exact((void *)addr, free_size);
#endif
kfence_metadata_init = NULL;
- __kfence_pool = NULL;
return err;
}
--
2.56.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/3] riscv: keep booting if KFENCE pool reservation fails
2026-10-26 12:23 ` Jackie Liu
@ 2026-10-26 12:23 ` Jackie Liu
-1 siblings, 0 replies; 15+ messages in thread
From: Jackie Liu @ 2026-10-26 12:23 UTC (permalink / raw)
To: glider
Cc: dvyukov, elver, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song, liu.yun
From: Jackie Liu <liuyun01@kylinos.cn>
A failed KFENCE pool reservation hits BUG_ON() and stops boot. Continue
building the linear map and disable KFENCE if the reservation fails.
Reject later pool initialization as well, since a replacement pool may
have huge-page mappings that kfence_protect_page() cannot handle.
Fixes: 25abe0db9243 ("riscv: Fix kfence now that the linear mapping can be backed by PUD/P4D/PGD")
Cc: stable@vger.kernel.org
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
---
arch/riscv/include/asm/kfence.h | 4 +++-
arch/riscv/mm/init.c | 19 +++++++++++++++----
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/arch/riscv/include/asm/kfence.h b/arch/riscv/include/asm/kfence.h
index 29cb3a6ee113..57e57426a7d6 100644
--- a/arch/riscv/include/asm/kfence.h
+++ b/arch/riscv/include/asm/kfence.h
@@ -9,9 +9,11 @@
#include <asm/cacheflush.h>
#include <asm/pgtable.h>
+extern bool kfence_disabled;
+
static inline bool arch_kfence_init_pool(void)
{
- return true;
+ return !kfence_disabled;
}
static inline bool kfence_protect_page(unsigned long addr, bool protect)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index fb37b0b67efe..393106cd25ba 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -27,6 +27,7 @@
#include <asm/fixmap.h>
#include <asm/io.h>
#include <asm/kasan.h>
+#include <asm/kfence.h>
#include <asm/module.h>
#include <asm/numa.h>
#include <asm/pgtable.h>
@@ -44,6 +45,10 @@ DECLARE_BITMAP(new_valid_map_cpus, NR_CPUS);
struct kernel_mapping kernel_map __ro_after_init;
EXPORT_SYMBOL(kernel_map);
+#ifdef CONFIG_KFENCE
+bool kfence_disabled __ro_after_init;
+#endif
+
#ifdef CONFIG_64BIT
u64 satp_mode __ro_after_init = SATP_MODE_57;
#else
@@ -1229,10 +1234,13 @@ static void __init create_linear_mapping_page_table(void)
* for this region.
*/
kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE);
- BUG_ON(!kfence_pool);
-
- memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE);
- __kfence_pool = __va(kfence_pool);
+ if (kfence_pool) {
+ memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE);
+ __kfence_pool = __va(kfence_pool);
+ } else {
+ pr_err("failed to allocate kfence pool\n");
+ kfence_disabled = true;
+ }
#endif
/* Map all memory banks in the linear mapping */
@@ -1253,6 +1261,9 @@ static void __init create_linear_mapping_page_table(void)
#endif
#ifdef CONFIG_KFENCE
+ if (!kfence_pool)
+ return;
+
create_linear_mapping_range(kfence_pool, kfence_pool + KFENCE_POOL_SIZE, PAGE_SIZE, NULL);
memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
--
2.56.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/3] riscv: keep booting if KFENCE pool reservation fails
@ 2026-10-26 12:23 ` Jackie Liu
0 siblings, 0 replies; 15+ messages in thread
From: Jackie Liu @ 2026-10-26 12:23 UTC (permalink / raw)
To: glider
Cc: dvyukov, elver, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song, liu.yun
From: Jackie Liu <liuyun01@kylinos.cn>
A failed KFENCE pool reservation hits BUG_ON() and stops boot. Continue
building the linear map and disable KFENCE if the reservation fails.
Reject later pool initialization as well, since a replacement pool may
have huge-page mappings that kfence_protect_page() cannot handle.
Fixes: 25abe0db9243 ("riscv: Fix kfence now that the linear mapping can be backed by PUD/P4D/PGD")
Cc: stable@vger.kernel.org
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
---
arch/riscv/include/asm/kfence.h | 4 +++-
arch/riscv/mm/init.c | 19 +++++++++++++++----
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/arch/riscv/include/asm/kfence.h b/arch/riscv/include/asm/kfence.h
index 29cb3a6ee113..57e57426a7d6 100644
--- a/arch/riscv/include/asm/kfence.h
+++ b/arch/riscv/include/asm/kfence.h
@@ -9,9 +9,11 @@
#include <asm/cacheflush.h>
#include <asm/pgtable.h>
+extern bool kfence_disabled;
+
static inline bool arch_kfence_init_pool(void)
{
- return true;
+ return !kfence_disabled;
}
static inline bool kfence_protect_page(unsigned long addr, bool protect)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index fb37b0b67efe..393106cd25ba 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -27,6 +27,7 @@
#include <asm/fixmap.h>
#include <asm/io.h>
#include <asm/kasan.h>
+#include <asm/kfence.h>
#include <asm/module.h>
#include <asm/numa.h>
#include <asm/pgtable.h>
@@ -44,6 +45,10 @@ DECLARE_BITMAP(new_valid_map_cpus, NR_CPUS);
struct kernel_mapping kernel_map __ro_after_init;
EXPORT_SYMBOL(kernel_map);
+#ifdef CONFIG_KFENCE
+bool kfence_disabled __ro_after_init;
+#endif
+
#ifdef CONFIG_64BIT
u64 satp_mode __ro_after_init = SATP_MODE_57;
#else
@@ -1229,10 +1234,13 @@ static void __init create_linear_mapping_page_table(void)
* for this region.
*/
kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE);
- BUG_ON(!kfence_pool);
-
- memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE);
- __kfence_pool = __va(kfence_pool);
+ if (kfence_pool) {
+ memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE);
+ __kfence_pool = __va(kfence_pool);
+ } else {
+ pr_err("failed to allocate kfence pool\n");
+ kfence_disabled = true;
+ }
#endif
/* Map all memory banks in the linear mapping */
@@ -1253,6 +1261,9 @@ static void __init create_linear_mapping_page_table(void)
#endif
#ifdef CONFIG_KFENCE
+ if (!kfence_pool)
+ return;
+
create_linear_mapping_range(kfence_pool, kfence_pool + KFENCE_POOL_SIZE, PAGE_SIZE, NULL);
memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
--
2.56.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 1/3] kfence: fix pool cleanup on metadata allocation failure
2026-10-26 12:23 ` Jackie Liu
@ 2026-10-26 13:08 ` Marco Elver
-1 siblings, 0 replies; 15+ messages in thread
From: Marco Elver @ 2026-10-26 13:08 UTC (permalink / raw)
To: Jackie Liu
Cc: glider, dvyukov, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song
On Mon, 26 Oct 2026 at 13:23, Jackie Liu <liu.yun@linux.dev> wrote:
>
> From: Jackie Liu <liuyun01@kylinos.cn>
>
> kfence_init_late() saves __kfence_pool in addr before allocating the pool,
> so addr is still NULL if metadata allocation fails. The error path then
> tries to free pages using that address.
>
> Set addr after pool allocation so cleanup frees the allocated pool.
>
> Fixes: cabdf74e6b31 ("mm: kfence: allocate kfence_metadata at runtime")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
Reviewed-by: Marco Elver <elver@google.com>
> ---
> mm/kfence/core.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/mm/kfence/core.c b/mm/kfence/core.c
> index 90925c646c4c..6e3d01bccdf1 100644
> --- a/mm/kfence/core.c
> +++ b/mm/kfence/core.c
> @@ -999,7 +999,7 @@ static int kfence_init_late(void)
> {
> const unsigned long nr_pages_pool = KFENCE_POOL_SIZE / PAGE_SIZE;
> const unsigned long nr_pages_meta = KFENCE_METADATA_SIZE / PAGE_SIZE;
> - unsigned long addr = (unsigned long)__kfence_pool;
> + unsigned long addr;
> unsigned long free_size = KFENCE_POOL_SIZE;
> int err = -ENOMEM;
>
> @@ -1032,6 +1032,7 @@ static int kfence_init_late(void)
> GFP_KERNEL | __GFP_SKIP_KASAN);
> #endif
>
> + addr = (unsigned long)__kfence_pool;
> if (!kfence_metadata_init)
> goto free_pool;
>
> --
> 2.56.0
>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 1/3] kfence: fix pool cleanup on metadata allocation failure
@ 2026-10-26 13:08 ` Marco Elver
0 siblings, 0 replies; 15+ messages in thread
From: Marco Elver @ 2026-10-26 13:08 UTC (permalink / raw)
To: Jackie Liu
Cc: glider, dvyukov, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song
On Mon, 26 Oct 2026 at 13:23, Jackie Liu <liu.yun@linux.dev> wrote:
>
> From: Jackie Liu <liuyun01@kylinos.cn>
>
> kfence_init_late() saves __kfence_pool in addr before allocating the pool,
> so addr is still NULL if metadata allocation fails. The error path then
> tries to free pages using that address.
>
> Set addr after pool allocation so cleanup frees the allocated pool.
>
> Fixes: cabdf74e6b31 ("mm: kfence: allocate kfence_metadata at runtime")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
Reviewed-by: Marco Elver <elver@google.com>
> ---
> mm/kfence/core.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/mm/kfence/core.c b/mm/kfence/core.c
> index 90925c646c4c..6e3d01bccdf1 100644
> --- a/mm/kfence/core.c
> +++ b/mm/kfence/core.c
> @@ -999,7 +999,7 @@ static int kfence_init_late(void)
> {
> const unsigned long nr_pages_pool = KFENCE_POOL_SIZE / PAGE_SIZE;
> const unsigned long nr_pages_meta = KFENCE_METADATA_SIZE / PAGE_SIZE;
> - unsigned long addr = (unsigned long)__kfence_pool;
> + unsigned long addr;
> unsigned long free_size = KFENCE_POOL_SIZE;
> int err = -ENOMEM;
>
> @@ -1032,6 +1032,7 @@ static int kfence_init_late(void)
> GFP_KERNEL | __GFP_SKIP_KASAN);
> #endif
>
> + addr = (unsigned long)__kfence_pool;
> if (!kfence_metadata_init)
> goto free_pool;
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/3] kfence: clear the pool pointer before freeing pages
2026-10-26 12:23 ` Jackie Liu
@ 2026-10-26 13:10 ` Marco Elver
-1 siblings, 0 replies; 15+ messages in thread
From: Marco Elver @ 2026-10-26 13:10 UTC (permalink / raw)
To: Jackie Liu
Cc: glider, dvyukov, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song
On Mon, 26 Oct 2026 at 13:23, Jackie Liu <liu.yun@linux.dev> wrote:
>
> From: Jackie Liu <liuyun01@kylinos.cn>
>
> Late initialization frees a failed pool before clearing __kfence_pool.
> Slab allocations can reuse those pages in between and be mistaken for
> KFENCE objects by is_kfence_address(), even though KFENCE is not enabled.
>
> Clear __kfence_pool before freeing the pages, and use the saved address
> for cleanup.
>
> Fixes: b33f778bba5e ("kfence: alloc kfence_pool after system startup")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
Reviewed-by: Marco Elver <elver@google.com>
> ---
> mm/kfence/core.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/mm/kfence/core.c b/mm/kfence/core.c
> index 6e3d01bccdf1..434df6cef7f2 100644
> --- a/mm/kfence/core.c
> +++ b/mm/kfence/core.c
> @@ -1052,16 +1052,17 @@ static int kfence_init_late(void)
> free_contig_range(page_to_pfn(virt_to_page((void *)kfence_metadata_init)),
> nr_pages_meta);
> free_pool:
> + WRITE_ONCE(__kfence_pool, NULL);
> free_contig_range(page_to_pfn(virt_to_page((void *)addr)),
> free_size / PAGE_SIZE);
> #else
> free_pages_exact((void *)kfence_metadata_init, KFENCE_METADATA_SIZE);
> free_pool:
> + WRITE_ONCE(__kfence_pool, NULL);
> free_pages_exact((void *)addr, free_size);
> #endif
>
> kfence_metadata_init = NULL;
> - __kfence_pool = NULL;
> return err;
> }
>
> --
> 2.56.0
>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/3] kfence: clear the pool pointer before freeing pages
@ 2026-10-26 13:10 ` Marco Elver
0 siblings, 0 replies; 15+ messages in thread
From: Marco Elver @ 2026-10-26 13:10 UTC (permalink / raw)
To: Jackie Liu
Cc: glider, dvyukov, pjw, alex, aou, linux-riscv, linux-mm, kasan-dev,
muchun.song
On Mon, 26 Oct 2026 at 13:23, Jackie Liu <liu.yun@linux.dev> wrote:
>
> From: Jackie Liu <liuyun01@kylinos.cn>
>
> Late initialization frees a failed pool before clearing __kfence_pool.
> Slab allocations can reuse those pages in between and be mistaken for
> KFENCE objects by is_kfence_address(), even though KFENCE is not enabled.
>
> Clear __kfence_pool before freeing the pages, and use the saved address
> for cleanup.
>
> Fixes: b33f778bba5e ("kfence: alloc kfence_pool after system startup")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
Reviewed-by: Marco Elver <elver@google.com>
> ---
> mm/kfence/core.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/mm/kfence/core.c b/mm/kfence/core.c
> index 6e3d01bccdf1..434df6cef7f2 100644
> --- a/mm/kfence/core.c
> +++ b/mm/kfence/core.c
> @@ -1052,16 +1052,17 @@ static int kfence_init_late(void)
> free_contig_range(page_to_pfn(virt_to_page((void *)kfence_metadata_init)),
> nr_pages_meta);
> free_pool:
> + WRITE_ONCE(__kfence_pool, NULL);
> free_contig_range(page_to_pfn(virt_to_page((void *)addr)),
> free_size / PAGE_SIZE);
> #else
> free_pages_exact((void *)kfence_metadata_init, KFENCE_METADATA_SIZE);
> free_pool:
> + WRITE_ONCE(__kfence_pool, NULL);
> free_pages_exact((void *)addr, free_size);
> #endif
>
> kfence_metadata_init = NULL;
> - __kfence_pool = NULL;
> return err;
> }
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/3] riscv: keep booting if KFENCE pool reservation fails
2026-10-26 12:23 ` Jackie Liu
(?)
@ 2026-10-27 12:23 ` sashiko-bot
-1 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-10-27 12:23 UTC (permalink / raw)
To: Jackie Liu, glider
Cc: dvyukov, elver, pjw, alex, aou, linux-mm, kasan-dev, muchun.song
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] riscv: build failure on 32-bit and NOMMU from including asm/kfence.h
--
commit d964a4c4107a3db6e2c99928c0888060598196ba
Author: Jackie Liu <liuyun01@kylinos.cn>
riscv: keep booting if KFENCE pool reservation fails
This commit avoids hitting BUG_ON() when the early KFENCE pool reservation
fails in create_linear_mapping_page_table(), disabling KFENCE instead so the
kernel can continue booting.
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index fb37b0b67efec..393106cd25ba0 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -27,6 +27,7 @@
> #include <asm/fixmap.h>
> #include <asm/io.h>
> #include <asm/kasan.h>
> +#include <asm/kfence.h>
[Severity: Low]
Does including asm/kfence.h unconditionally in arch/riscv/mm/init.c break
32-bit (CONFIG_32BIT=y) and NOMMU (CONFIG_MMU=n) RISC-V builds?
arch/riscv/mm/init.c is built unconditionally for all RISC-V configurations,
whereas HAVE_ARCH_KFENCE is only selected when MMU && 64BIT. In
arch/riscv/include/asm/kfence.h, kfence_protect_page() is defined outside of
any CONFIG_KFENCE guard:
arch/riscv/include/asm/kfence.h:
static inline bool kfence_protect_page(unsigned long addr, bool protect)
{
pte_t *pte = virt_to_kpte(addr);
if (protect) {
set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
} else {
set_pte(pte, __pte(pte_val(ptep_get(pte)) | _PAGE_PRESENT));
mark_new_valid_map();
}
preempt_disable();
local_flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
preempt_enable();
return true;
}
On 32-bit builds, mark_new_valid_map() is not declared because
arch/riscv/include/asm/cacheflush.h guards it under
#if defined(CONFIG_64BIT) && defined(CONFIG_MMU) with no fallback stub.
On NOMMU builds, virt_to_kpte() in include/linux/pgtable.h,
set_pte() / __pte() / pte_val() / ptep_get() in
arch/riscv/include/asm/pgtable.h, mark_new_valid_map() in
arch/riscv/include/asm/cacheflush.h, and local_flush_tlb_kernel_range() in
arch/riscv/include/asm/tlbflush.h are all guarded by #ifdef CONFIG_MMU and
are undeclared when compiling kfence_protect_page().
Should the include in arch/riscv/mm/init.c or the contents of
arch/riscv/include/asm/kfence.h be guarded by #ifdef CONFIG_KFENCE?
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1793017073.git.liuyun01@kylinos.cn?part=3
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/3] riscv: keep booting if KFENCE pool reservation fails
2026-10-26 12:23 ` Jackie Liu
@ 2026-10-29 2:28 ` kernel test robot
-1 siblings, 0 replies; 15+ messages in thread
From: kernel test robot @ 2026-10-29 2:28 UTC (permalink / raw)
To: Jackie Liu, glider
Cc: oe-kbuild-all, dvyukov, elver, pjw, alex, aou, linux-riscv,
linux-mm, kasan-dev, muchun.song, liu.yun
Hi Jackie,
kernel test robot noticed the following build errors:
[auto build test ERROR on 7be4bc52fd9e0e55dc9a2e0232b89427d2c4b614]
url: https://github.com/intel-lab-lkp/linux/commits/Jackie-Liu/kfence-fix-pool-cleanup-on-metadata-allocation-failure/20261026-202302
base: 7be4bc52fd9e0e55dc9a2e0232b89427d2c4b614
patch link: https://lore.kernel.org/r/58e3baebbf4e454725e6bde8b7a267fb71cfdaae.1793017074.git.liuyun01%40kylinos.cn
patch subject: [PATCH 3/3] riscv: keep booting if KFENCE pool reservation fails
config: riscv-randconfig-1001-20261029 (https://download.01.org/0day-ci/archive/20261029/202610290904.wbrEL97y-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 15.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261029/202610290904.wbrEL97y-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610290904.wbrEL97y-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from arch/riscv/mm/init.c:30:
arch/riscv/include/asm/kfence.h: In function 'kfence_protect_page':
>> arch/riscv/include/asm/kfence.h:21:22: error: implicit declaration of function 'virt_to_kpte'; did you mean 'virt_to_page'? [-Wimplicit-function-declaration]
21 | pte_t *pte = virt_to_kpte(addr);
| ^~~~~~~~~~~~
| virt_to_page
>> arch/riscv/include/asm/kfence.h:21:22: error: initialization of 'pte_t *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
>> arch/riscv/include/asm/kfence.h:24:17: error: implicit declaration of function 'set_pte'; did you mean 'set_pgd'? [-Wimplicit-function-declaration]
24 | set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
| ^~~~~~~
| set_pgd
In file included from arch/riscv/include/asm/thread_info.h:11,
from include/linux/thread_info.h:62,
from include/asm-generic/preempt.h:5,
from ./arch/riscv/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:107,
from include/linux/spinlock.h:56,
from include/linux/mmzone.h:8,
from include/linux/gfp.h:7,
from include/linux/mm.h:8,
from arch/riscv/mm/init.c:10:
>> arch/riscv/include/asm/kfence.h:24:44: error: implicit declaration of function 'ptep_get' [-Wimplicit-function-declaration]
24 | set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
| ^~~~~~~~
arch/riscv/include/asm/page.h:75:37: note: in definition of macro '__pte'
75 | #define __pte(x) ((pte_t) { (x) })
| ^
arch/riscv/include/asm/kfence.h:24:36: note: in expansion of macro 'pte_val'
24 | set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
| ^~~~~~~
>> arch/riscv/include/asm/page.h:71:29: error: request for member 'pte' in something not a structure or union
71 | #define pte_val(x) ((x).pte)
| ^
arch/riscv/include/asm/page.h:75:37: note: in definition of macro '__pte'
75 | #define __pte(x) ((pte_t) { (x) })
| ^
arch/riscv/include/asm/kfence.h:24:36: note: in expansion of macro 'pte_val'
24 | set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
| ^~~~~~~
>> arch/riscv/include/asm/page.h:71:29: error: request for member 'pte' in something not a structure or union
71 | #define pte_val(x) ((x).pte)
| ^
arch/riscv/include/asm/page.h:75:37: note: in definition of macro '__pte'
75 | #define __pte(x) ((pte_t) { (x) })
| ^
arch/riscv/include/asm/kfence.h:26:36: note: in expansion of macro 'pte_val'
26 | set_pte(pte, __pte(pte_val(ptep_get(pte)) | _PAGE_PRESENT));
| ^~~~~~~
>> arch/riscv/include/asm/kfence.h:27:17: error: implicit declaration of function 'mark_new_valid_map' [-Wimplicit-function-declaration]
27 | mark_new_valid_map();
| ^~~~~~~~~~~~~~~~~~
>> arch/riscv/include/asm/kfence.h:31:9: error: implicit declaration of function 'local_flush_tlb_kernel_range'; did you mean 'local_flush_icache_range'? [-Wimplicit-function-declaration]
31 | local_flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| local_flush_icache_range
vim +21 arch/riscv/include/asm/kfence.h
47513f243b452a Liu Shixin 2021-06-15 18
47513f243b452a Liu Shixin 2021-06-15 19 static inline bool kfence_protect_page(unsigned long addr, bool protect)
47513f243b452a Liu Shixin 2021-06-15 20 {
47513f243b452a Liu Shixin 2021-06-15 @21 pte_t *pte = virt_to_kpte(addr);
47513f243b452a Liu Shixin 2021-06-15 22
8d6c8c40e733b3 Vivian Wang 2026-03-03 23 if (protect) {
edf95564726942 Alexandre Ghiti 2023-12-13 @24 set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
8d6c8c40e733b3 Vivian Wang 2026-03-03 25 } else {
edf95564726942 Alexandre Ghiti 2023-12-13 26 set_pte(pte, __pte(pte_val(ptep_get(pte)) | _PAGE_PRESENT));
8d6c8c40e733b3 Vivian Wang 2026-03-03 @27 mark_new_valid_map();
8d6c8c40e733b3 Vivian Wang 2026-03-03 28 }
47513f243b452a Liu Shixin 2021-06-15 29
b3431a8bb336ce Alexandre Ghiti 2024-12-09 30 preempt_disable();
b3431a8bb336ce Alexandre Ghiti 2024-12-09 @31 local_flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
b3431a8bb336ce Alexandre Ghiti 2024-12-09 32 preempt_enable();
47513f243b452a Liu Shixin 2021-06-15 33
47513f243b452a Liu Shixin 2021-06-15 34 return true;
47513f243b452a Liu Shixin 2021-06-15 35 }
47513f243b452a Liu Shixin 2021-06-15 36
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/3] riscv: keep booting if KFENCE pool reservation fails
@ 2026-10-29 2:28 ` kernel test robot
0 siblings, 0 replies; 15+ messages in thread
From: kernel test robot @ 2026-10-29 2:28 UTC (permalink / raw)
To: Jackie Liu, glider
Cc: oe-kbuild-all, dvyukov, elver, pjw, alex, aou, linux-riscv,
linux-mm, kasan-dev, muchun.song, liu.yun
Hi Jackie,
kernel test robot noticed the following build errors:
[auto build test ERROR on 7be4bc52fd9e0e55dc9a2e0232b89427d2c4b614]
url: https://github.com/intel-lab-lkp/linux/commits/Jackie-Liu/kfence-fix-pool-cleanup-on-metadata-allocation-failure/20261026-202302
base: 7be4bc52fd9e0e55dc9a2e0232b89427d2c4b614
patch link: https://lore.kernel.org/r/58e3baebbf4e454725e6bde8b7a267fb71cfdaae.1793017074.git.liuyun01%40kylinos.cn
patch subject: [PATCH 3/3] riscv: keep booting if KFENCE pool reservation fails
config: riscv-randconfig-1001-20261029 (https://download.01.org/0day-ci/archive/20261029/202610290904.wbrEL97y-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 15.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261029/202610290904.wbrEL97y-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610290904.wbrEL97y-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from arch/riscv/mm/init.c:30:
arch/riscv/include/asm/kfence.h: In function 'kfence_protect_page':
>> arch/riscv/include/asm/kfence.h:21:22: error: implicit declaration of function 'virt_to_kpte'; did you mean 'virt_to_page'? [-Wimplicit-function-declaration]
21 | pte_t *pte = virt_to_kpte(addr);
| ^~~~~~~~~~~~
| virt_to_page
>> arch/riscv/include/asm/kfence.h:21:22: error: initialization of 'pte_t *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
>> arch/riscv/include/asm/kfence.h:24:17: error: implicit declaration of function 'set_pte'; did you mean 'set_pgd'? [-Wimplicit-function-declaration]
24 | set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
| ^~~~~~~
| set_pgd
In file included from arch/riscv/include/asm/thread_info.h:11,
from include/linux/thread_info.h:62,
from include/asm-generic/preempt.h:5,
from ./arch/riscv/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:107,
from include/linux/spinlock.h:56,
from include/linux/mmzone.h:8,
from include/linux/gfp.h:7,
from include/linux/mm.h:8,
from arch/riscv/mm/init.c:10:
>> arch/riscv/include/asm/kfence.h:24:44: error: implicit declaration of function 'ptep_get' [-Wimplicit-function-declaration]
24 | set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
| ^~~~~~~~
arch/riscv/include/asm/page.h:75:37: note: in definition of macro '__pte'
75 | #define __pte(x) ((pte_t) { (x) })
| ^
arch/riscv/include/asm/kfence.h:24:36: note: in expansion of macro 'pte_val'
24 | set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
| ^~~~~~~
>> arch/riscv/include/asm/page.h:71:29: error: request for member 'pte' in something not a structure or union
71 | #define pte_val(x) ((x).pte)
| ^
arch/riscv/include/asm/page.h:75:37: note: in definition of macro '__pte'
75 | #define __pte(x) ((pte_t) { (x) })
| ^
arch/riscv/include/asm/kfence.h:24:36: note: in expansion of macro 'pte_val'
24 | set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
| ^~~~~~~
>> arch/riscv/include/asm/page.h:71:29: error: request for member 'pte' in something not a structure or union
71 | #define pte_val(x) ((x).pte)
| ^
arch/riscv/include/asm/page.h:75:37: note: in definition of macro '__pte'
75 | #define __pte(x) ((pte_t) { (x) })
| ^
arch/riscv/include/asm/kfence.h:26:36: note: in expansion of macro 'pte_val'
26 | set_pte(pte, __pte(pte_val(ptep_get(pte)) | _PAGE_PRESENT));
| ^~~~~~~
>> arch/riscv/include/asm/kfence.h:27:17: error: implicit declaration of function 'mark_new_valid_map' [-Wimplicit-function-declaration]
27 | mark_new_valid_map();
| ^~~~~~~~~~~~~~~~~~
>> arch/riscv/include/asm/kfence.h:31:9: error: implicit declaration of function 'local_flush_tlb_kernel_range'; did you mean 'local_flush_icache_range'? [-Wimplicit-function-declaration]
31 | local_flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| local_flush_icache_range
vim +21 arch/riscv/include/asm/kfence.h
47513f243b452a Liu Shixin 2021-06-15 18
47513f243b452a Liu Shixin 2021-06-15 19 static inline bool kfence_protect_page(unsigned long addr, bool protect)
47513f243b452a Liu Shixin 2021-06-15 20 {
47513f243b452a Liu Shixin 2021-06-15 @21 pte_t *pte = virt_to_kpte(addr);
47513f243b452a Liu Shixin 2021-06-15 22
8d6c8c40e733b3 Vivian Wang 2026-03-03 23 if (protect) {
edf95564726942 Alexandre Ghiti 2023-12-13 @24 set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
8d6c8c40e733b3 Vivian Wang 2026-03-03 25 } else {
edf95564726942 Alexandre Ghiti 2023-12-13 26 set_pte(pte, __pte(pte_val(ptep_get(pte)) | _PAGE_PRESENT));
8d6c8c40e733b3 Vivian Wang 2026-03-03 @27 mark_new_valid_map();
8d6c8c40e733b3 Vivian Wang 2026-03-03 28 }
47513f243b452a Liu Shixin 2021-06-15 29
b3431a8bb336ce Alexandre Ghiti 2024-12-09 30 preempt_disable();
b3431a8bb336ce Alexandre Ghiti 2024-12-09 @31 local_flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
b3431a8bb336ce Alexandre Ghiti 2024-12-09 32 preempt_enable();
47513f243b452a Liu Shixin 2021-06-15 33
47513f243b452a Liu Shixin 2021-06-15 34 return true;
47513f243b452a Liu Shixin 2021-06-15 35 }
47513f243b452a Liu Shixin 2021-06-15 36
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-10-29 2:29 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-26 12:23 [PATCH 0/3] kfence: fix pool allocation failure handling Jackie Liu
2026-10-26 12:23 ` Jackie Liu
2026-10-26 12:23 ` [PATCH 1/3] kfence: fix pool cleanup on metadata allocation failure Jackie Liu
2026-10-26 12:23 ` Jackie Liu
2026-10-26 13:08 ` Marco Elver
2026-10-26 13:08 ` Marco Elver
2026-10-26 12:23 ` [PATCH 2/3] kfence: clear the pool pointer before freeing pages Jackie Liu
2026-10-26 12:23 ` Jackie Liu
2026-10-26 13:10 ` Marco Elver
2026-10-26 13:10 ` Marco Elver
2026-10-26 12:23 ` [PATCH 3/3] riscv: keep booting if KFENCE pool reservation fails Jackie Liu
2026-10-26 12:23 ` Jackie Liu
2026-10-27 12:23 ` sashiko-bot
2026-10-29 2:28 ` kernel test robot
2026-10-29 2:28 ` kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.