All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zhenhua Huang <quic_zhenhuah@quicinc.com>
To: <catalin.marinas@arm.com>, <will@kernel.org>, <glider@google.com>,
	<elver@google.com>, <dvyukov@google.com>,
	<akpm@linux-foundation.org>, <robin.murphy@arm.com>,
	<mark.rutland@arm.com>, <jianyong.wu@arm.com>,
	<james.morse@arm.com>
Cc: Zhenhua Huang <quic_zhenhuah@quicinc.com>,
	<linux-arm-kernel@lists.infradead.org>,
	<kasan-dev@googlegroups.com>, <linux-mm@kvack.org>,
	<quic_pkondeti@quicinc.com>, <quic_guptap@quicinc.com>,
	<quic_tingweiz@quicinc.com>
Subject: [PATCH] mm,kfence: decouple kfence from page granularity mapping judgement
Date: Thu, 9 Mar 2023 16:05:22 +0800	[thread overview]
Message-ID: <1678349122-19279-1-git-send-email-quic_zhenhuah@quicinc.com> (raw)

Kfence only needs its pool to be mapped as page granularity, previous
judgement was a bit over protected. Decouple it from judgement and do
page granularity mapping for kfence pool only [1].

To implement this, also relocate the kfence pool allocation before the
linear mapping setting up, kfence_alloc_pool is to allocate phys addr,
__kfence_pool is to be set after linear mapping set up.

LINK: [1] https://lore.kernel.org/linux-arm-kernel/1675750519-1064-1-git-send-email-quic_zhenhuah@quicinc.com/T/
Suggested-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
---
 arch/arm64/mm/mmu.c      | 24 ++++++++++++++++++++++++
 arch/arm64/mm/pageattr.c |  5 ++---
 include/linux/kfence.h   | 10 ++++++++--
 init/main.c              |  1 -
 mm/kfence/core.c         | 18 ++++++++++++++----
 5 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 6f9d889..bd79691 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -24,6 +24,7 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/set_memory.h>
+#include <linux/kfence.h>
 
 #include <asm/barrier.h>
 #include <asm/cputype.h>
@@ -532,6 +533,9 @@ static void __init map_mem(pgd_t *pgdp)
 	phys_addr_t kernel_end = __pa_symbol(__init_begin);
 	phys_addr_t start, end;
 	int flags = NO_EXEC_MAPPINGS;
+#ifdef CONFIG_KFENCE
+	phys_addr_t kfence_pool = 0;
+#endif
 	u64 i;
 
 	/*
@@ -564,6 +568,12 @@ static void __init map_mem(pgd_t *pgdp)
 	}
 #endif
 
+#ifdef CONFIG_KFENCE
+	kfence_pool = kfence_alloc_pool();
+	if (kfence_pool)
+		memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE);
+#endif
+
 	/* map all the memory banks */
 	for_each_mem_range(i, &start, &end) {
 		if (start >= end)
@@ -608,6 +618,20 @@ static void __init map_mem(pgd_t *pgdp)
 		}
 	}
 #endif
+
+	/* Kfence pool needs page-level mapping */
+#ifdef CONFIG_KFENCE
+	if (kfence_pool) {
+		__map_memblock(pgdp, kfence_pool,
+			kfence_pool + KFENCE_POOL_SIZE,
+			pgprot_tagged(PAGE_KERNEL),
+			NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
+		memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
+		/* kfence_pool really mapped now */
+		kfence_set_pool(kfence_pool);
+	}
+#endif
+
 }
 
 void mark_rodata_ro(void)
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 79dd201..61156d0 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -22,12 +22,11 @@ bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED
 bool can_set_direct_map(void)
 {
 	/*
-	 * rodata_full, DEBUG_PAGEALLOC and KFENCE require linear map to be
+	 * rodata_full and DEBUG_PAGEALLOC require linear map to be
 	 * mapped at page granularity, so that it is possible to
 	 * protect/unprotect single pages.
 	 */
-	return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() ||
-		IS_ENABLED(CONFIG_KFENCE);
+	return (rodata_enabled && rodata_full) || debug_pagealloc_enabled();
 }
 
 static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
diff --git a/include/linux/kfence.h b/include/linux/kfence.h
index 726857a..0252e74 100644
--- a/include/linux/kfence.h
+++ b/include/linux/kfence.h
@@ -61,7 +61,12 @@ static __always_inline bool is_kfence_address(const void *addr)
 /**
  * kfence_alloc_pool() - allocate the KFENCE pool via memblock
  */
-void __init kfence_alloc_pool(void);
+phys_addr_t __init kfence_alloc_pool(void);
+
+/**
+ * kfence_set_pool() - KFENCE pool mapped and can be used
+ */
+void __init kfence_set_pool(phys_addr_t addr);
 
 /**
  * kfence_init() - perform KFENCE initialization at boot time
@@ -223,7 +228,8 @@ bool __kfence_obj_info(struct kmem_obj_info *kpp, void *object, struct slab *sla
 #else /* CONFIG_KFENCE */
 
 static inline bool is_kfence_address(const void *addr) { return false; }
-static inline void kfence_alloc_pool(void) { }
+static inline phys_addr_t kfence_alloc_pool(void) { return (phys_addr_t)NULL; }
+static inline void kfence_set_pool(phys_addr_t addr) { }
 static inline void kfence_init(void) { }
 static inline void kfence_shutdown_cache(struct kmem_cache *s) { }
 static inline void *kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) { return NULL; }
diff --git a/init/main.c b/init/main.c
index 4425d17..9aaf217 100644
--- a/init/main.c
+++ b/init/main.c
@@ -839,7 +839,6 @@ static void __init mm_init(void)
 	 */
 	page_ext_init_flatmem();
 	init_mem_debugging_and_hardening();
-	kfence_alloc_pool();
 	report_meminit();
 	kmsan_init_shadow();
 	stack_depot_early_init();
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 5349c37..dd5cdd5 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -809,15 +809,25 @@ static void toggle_allocation_gate(struct work_struct *work)
 
 /* === Public interface ===================================================== */
 
-void __init kfence_alloc_pool(void)
+phys_addr_t __init kfence_alloc_pool(void)
 {
+	phys_addr_t kfence_pool;
 	if (!kfence_sample_interval)
-		return;
+		return 0;
 
-	__kfence_pool = memblock_alloc(KFENCE_POOL_SIZE, PAGE_SIZE);
+	kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE);
 
-	if (!__kfence_pool)
+	if (!kfence_pool) {
 		pr_err("failed to allocate pool\n");
+		return 0;
+	}
+
+	return kfence_pool;
+}
+
+void __init kfence_set_pool(phys_addr_t addr)
+{
+	__kfence_pool = phys_to_virt(addr);
 }
 
 static void kfence_init_enable(void)
-- 
2.7.4



WARNING: multiple messages have this Message-ID (diff)
From: Zhenhua Huang <quic_zhenhuah@quicinc.com>
To: <catalin.marinas@arm.com>, <will@kernel.org>, <glider@google.com>,
	<elver@google.com>, <dvyukov@google.com>,
	<akpm@linux-foundation.org>, <robin.murphy@arm.com>,
	<mark.rutland@arm.com>, <jianyong.wu@arm.com>,
	<james.morse@arm.com>
Cc: Zhenhua Huang <quic_zhenhuah@quicinc.com>,
	<linux-arm-kernel@lists.infradead.org>,
	<kasan-dev@googlegroups.com>, <linux-mm@kvack.org>,
	<quic_pkondeti@quicinc.com>, <quic_guptap@quicinc.com>,
	<quic_tingweiz@quicinc.com>
Subject: [PATCH] mm,kfence: decouple kfence from page granularity mapping judgement
Date: Thu, 9 Mar 2023 16:05:22 +0800	[thread overview]
Message-ID: <1678349122-19279-1-git-send-email-quic_zhenhuah@quicinc.com> (raw)

Kfence only needs its pool to be mapped as page granularity, previous
judgement was a bit over protected. Decouple it from judgement and do
page granularity mapping for kfence pool only [1].

To implement this, also relocate the kfence pool allocation before the
linear mapping setting up, kfence_alloc_pool is to allocate phys addr,
__kfence_pool is to be set after linear mapping set up.

LINK: [1] https://lore.kernel.org/linux-arm-kernel/1675750519-1064-1-git-send-email-quic_zhenhuah@quicinc.com/T/
Suggested-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
---
 arch/arm64/mm/mmu.c      | 24 ++++++++++++++++++++++++
 arch/arm64/mm/pageattr.c |  5 ++---
 include/linux/kfence.h   | 10 ++++++++--
 init/main.c              |  1 -
 mm/kfence/core.c         | 18 ++++++++++++++----
 5 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 6f9d889..bd79691 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -24,6 +24,7 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/set_memory.h>
+#include <linux/kfence.h>
 
 #include <asm/barrier.h>
 #include <asm/cputype.h>
@@ -532,6 +533,9 @@ static void __init map_mem(pgd_t *pgdp)
 	phys_addr_t kernel_end = __pa_symbol(__init_begin);
 	phys_addr_t start, end;
 	int flags = NO_EXEC_MAPPINGS;
+#ifdef CONFIG_KFENCE
+	phys_addr_t kfence_pool = 0;
+#endif
 	u64 i;
 
 	/*
@@ -564,6 +568,12 @@ static void __init map_mem(pgd_t *pgdp)
 	}
 #endif
 
+#ifdef CONFIG_KFENCE
+	kfence_pool = kfence_alloc_pool();
+	if (kfence_pool)
+		memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE);
+#endif
+
 	/* map all the memory banks */
 	for_each_mem_range(i, &start, &end) {
 		if (start >= end)
@@ -608,6 +618,20 @@ static void __init map_mem(pgd_t *pgdp)
 		}
 	}
 #endif
+
+	/* Kfence pool needs page-level mapping */
+#ifdef CONFIG_KFENCE
+	if (kfence_pool) {
+		__map_memblock(pgdp, kfence_pool,
+			kfence_pool + KFENCE_POOL_SIZE,
+			pgprot_tagged(PAGE_KERNEL),
+			NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
+		memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
+		/* kfence_pool really mapped now */
+		kfence_set_pool(kfence_pool);
+	}
+#endif
+
 }
 
 void mark_rodata_ro(void)
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 79dd201..61156d0 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -22,12 +22,11 @@ bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED
 bool can_set_direct_map(void)
 {
 	/*
-	 * rodata_full, DEBUG_PAGEALLOC and KFENCE require linear map to be
+	 * rodata_full and DEBUG_PAGEALLOC require linear map to be
 	 * mapped at page granularity, so that it is possible to
 	 * protect/unprotect single pages.
 	 */
-	return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() ||
-		IS_ENABLED(CONFIG_KFENCE);
+	return (rodata_enabled && rodata_full) || debug_pagealloc_enabled();
 }
 
 static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
diff --git a/include/linux/kfence.h b/include/linux/kfence.h
index 726857a..0252e74 100644
--- a/include/linux/kfence.h
+++ b/include/linux/kfence.h
@@ -61,7 +61,12 @@ static __always_inline bool is_kfence_address(const void *addr)
 /**
  * kfence_alloc_pool() - allocate the KFENCE pool via memblock
  */
-void __init kfence_alloc_pool(void);
+phys_addr_t __init kfence_alloc_pool(void);
+
+/**
+ * kfence_set_pool() - KFENCE pool mapped and can be used
+ */
+void __init kfence_set_pool(phys_addr_t addr);
 
 /**
  * kfence_init() - perform KFENCE initialization at boot time
@@ -223,7 +228,8 @@ bool __kfence_obj_info(struct kmem_obj_info *kpp, void *object, struct slab *sla
 #else /* CONFIG_KFENCE */
 
 static inline bool is_kfence_address(const void *addr) { return false; }
-static inline void kfence_alloc_pool(void) { }
+static inline phys_addr_t kfence_alloc_pool(void) { return (phys_addr_t)NULL; }
+static inline void kfence_set_pool(phys_addr_t addr) { }
 static inline void kfence_init(void) { }
 static inline void kfence_shutdown_cache(struct kmem_cache *s) { }
 static inline void *kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) { return NULL; }
diff --git a/init/main.c b/init/main.c
index 4425d17..9aaf217 100644
--- a/init/main.c
+++ b/init/main.c
@@ -839,7 +839,6 @@ static void __init mm_init(void)
 	 */
 	page_ext_init_flatmem();
 	init_mem_debugging_and_hardening();
-	kfence_alloc_pool();
 	report_meminit();
 	kmsan_init_shadow();
 	stack_depot_early_init();
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 5349c37..dd5cdd5 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -809,15 +809,25 @@ static void toggle_allocation_gate(struct work_struct *work)
 
 /* === Public interface ===================================================== */
 
-void __init kfence_alloc_pool(void)
+phys_addr_t __init kfence_alloc_pool(void)
 {
+	phys_addr_t kfence_pool;
 	if (!kfence_sample_interval)
-		return;
+		return 0;
 
-	__kfence_pool = memblock_alloc(KFENCE_POOL_SIZE, PAGE_SIZE);
+	kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE);
 
-	if (!__kfence_pool)
+	if (!kfence_pool) {
 		pr_err("failed to allocate pool\n");
+		return 0;
+	}
+
+	return kfence_pool;
+}
+
+void __init kfence_set_pool(phys_addr_t addr)
+{
+	__kfence_pool = phys_to_virt(addr);
 }
 
 static void kfence_init_enable(void)
-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

             reply	other threads:[~2023-03-09  8:05 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-09  8:05 Zhenhua Huang [this message]
2023-03-09  8:05 ` [PATCH] mm,kfence: decouple kfence from page granularity mapping judgement Zhenhua Huang
2023-03-09 10:33 ` Marco Elver
2023-03-09 10:33   ` Marco Elver
2023-03-09 11:03   ` Zhenhua Huang
2023-03-09 11:03     ` Zhenhua Huang
2023-03-09 11:09     ` Marco Elver
2023-03-09 11:09       ` Marco Elver
2023-03-09 11:26       ` Zhenhua Huang
2023-03-09 11:26         ` Zhenhua Huang
2023-03-09 11:38         ` Marco Elver
2023-03-09 11:38           ` Marco Elver
2023-03-09 15:38           ` Zhenhua Huang
2023-03-09 15:38             ` Zhenhua Huang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1678349122-19279-1-git-send-email-quic_zhenhuah@quicinc.com \
    --to=quic_zhenhuah@quicinc.com \
    --cc=akpm@linux-foundation.org \
    --cc=catalin.marinas@arm.com \
    --cc=dvyukov@google.com \
    --cc=elver@google.com \
    --cc=glider@google.com \
    --cc=james.morse@arm.com \
    --cc=jianyong.wu@arm.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-mm@kvack.org \
    --cc=mark.rutland@arm.com \
    --cc=quic_guptap@quicinc.com \
    --cc=quic_pkondeti@quicinc.com \
    --cc=quic_tingweiz@quicinc.com \
    --cc=robin.murphy@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.