linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says
@ 2021-09-24 13:48 Christophe Leroy
  2021-09-24 13:48 ` [PATCH 2/3] powerpc: Use generic version of arch_is_kernel_initmem_freed() Christophe Leroy
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Christophe Leroy @ 2021-09-24 13:48 UTC (permalink / raw)
  To: Andrew Morton, arnd
  Cc: Christophe Leroy, linux-kernel, linux-mm, linux-s390,
	linuxppc-dev, linux-arch, Gerald Schaefer

Commit 7a5da02de8d6 ("locking/lockdep: check for freed initmem in
static_obj()") added arch_is_kernel_initmem_freed() which is supposed
to report whether an object is part of already freed init memory.

For the time being, the generic version of arch_is_kernel_initmem_freed()
always reports 'false', allthough free_initmem() is generically called
on all architectures.

Therefore, change the generic version of arch_is_kernel_initmem_freed()
to check whether free_initmem() has been called. If so, then check
if a given address falls into init memory.

In order to use function init_section_contains(), the fonction is
moved at the end of asm-generic/section.h

Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 include/asm-generic/sections.h | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index d16302d3eb59..d1e5bb2c6b72 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -80,20 +80,6 @@ static inline int arch_is_kernel_data(unsigned long addr)
 }
 #endif
 
-/*
- * Check if an address is part of freed initmem. This is needed on architectures
- * with virt == phys kernel mapping, for code that wants to check if an address
- * is part of a static object within [_stext, _end]. After initmem is freed,
- * memory can be allocated from it, and such allocations would then have
- * addresses within the range [_stext, _end].
- */
-#ifndef arch_is_kernel_initmem_freed
-static inline int arch_is_kernel_initmem_freed(unsigned long addr)
-{
-	return 0;
-}
-#endif
-
 /**
  * memory_contains - checks if an object is contained within a memory region
  * @begin: virtual address of the beginning of the memory region
@@ -172,4 +158,21 @@ static inline bool is_kernel_rodata(unsigned long addr)
 	       addr < (unsigned long)__end_rodata;
 }
 
+/*
+ * Check if an address is part of freed initmem. This is needed on architectures
+ * with virt == phys kernel mapping, for code that wants to check if an address
+ * is part of a static object within [_stext, _end]. After initmem is freed,
+ * memory can be allocated from it, and such allocations would then have
+ * addresses within the range [_stext, _end].
+ */
+#ifndef arch_is_kernel_initmem_freed
+static inline int arch_is_kernel_initmem_freed(unsigned long addr)
+{
+	if (system_state < SYSTEM_RUNNING)
+		return 0;
+
+	return init_section_contains((void *)addr, 1);
+}
+#endif
+
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] powerpc: Use generic version of arch_is_kernel_initmem_freed()
  2021-09-24 13:48 [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says Christophe Leroy
@ 2021-09-24 13:48 ` Christophe Leroy
  2021-09-24 13:48 ` [PATCH 3/3] s390: " Christophe Leroy
  2021-09-27 13:11 ` [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says Michael Ellerman
  2 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2021-09-24 13:48 UTC (permalink / raw)
  To: Andrew Morton, arnd
  Cc: Christophe Leroy, linux-kernel, linux-mm, linux-s390,
	linuxppc-dev, linux-arch

Generic version of arch_is_kernel_initmem_freed() now does the same
as powerpc version.

Remove the powerpc version.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/asm/sections.h | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index 6e4af4492a14..79cb7a25a5fb 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -6,21 +6,8 @@
 #include <linux/elf.h>
 #include <linux/uaccess.h>
 
-#define arch_is_kernel_initmem_freed arch_is_kernel_initmem_freed
-
 #include <asm-generic/sections.h>
 
-extern bool init_mem_is_free;
-
-static inline int arch_is_kernel_initmem_freed(unsigned long addr)
-{
-	if (!init_mem_is_free)
-		return 0;
-
-	return addr >= (unsigned long)__init_begin &&
-		addr < (unsigned long)__init_end;
-}
-
 extern char __head_end[];
 
 #ifdef __powerpc64__
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] s390: Use generic version of arch_is_kernel_initmem_freed()
  2021-09-24 13:48 [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says Christophe Leroy
  2021-09-24 13:48 ` [PATCH 2/3] powerpc: Use generic version of arch_is_kernel_initmem_freed() Christophe Leroy
@ 2021-09-24 13:48 ` Christophe Leroy
  2021-09-27 13:11 ` [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says Michael Ellerman
  2 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2021-09-24 13:48 UTC (permalink / raw)
  To: Andrew Morton, arnd
  Cc: Christophe Leroy, linux-kernel, linux-mm, linux-s390,
	linuxppc-dev, linux-arch, Gerald Schaefer

Generic version of arch_is_kernel_initmem_freed() now does the same
as s390 version.

Remove the s390 version.

Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/s390/include/asm/sections.h | 12 ------------
 arch/s390/mm/init.c              |  3 ---
 2 files changed, 15 deletions(-)

diff --git a/arch/s390/include/asm/sections.h b/arch/s390/include/asm/sections.h
index 85881dd48022..3fecaa4e8b74 100644
--- a/arch/s390/include/asm/sections.h
+++ b/arch/s390/include/asm/sections.h
@@ -2,20 +2,8 @@
 #ifndef _S390_SECTIONS_H
 #define _S390_SECTIONS_H
 
-#define arch_is_kernel_initmem_freed arch_is_kernel_initmem_freed
-
 #include <asm-generic/sections.h>
 
-extern bool initmem_freed;
-
-static inline int arch_is_kernel_initmem_freed(unsigned long addr)
-{
-	if (!initmem_freed)
-		return 0;
-	return addr >= (unsigned long)__init_begin &&
-	       addr < (unsigned long)__init_end;
-}
-
 /*
  * .boot.data section contains variables "shared" between the decompressor and
  * the decompressed kernel. The decompressor will store values in them, and
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index a04faf49001a..8c6f258a6183 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -58,8 +58,6 @@ unsigned long empty_zero_page, zero_page_mask;
 EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(zero_page_mask);
 
-bool initmem_freed;
-
 static void __init setup_zero_pages(void)
 {
 	unsigned int order;
@@ -214,7 +212,6 @@ void __init mem_init(void)
 
 void free_initmem(void)
 {
-	initmem_freed = true;
 	__set_memory((unsigned long)_sinittext,
 		     (unsigned long)(_einittext - _sinittext) >> PAGE_SHIFT,
 		     SET_MEMORY_RW | SET_MEMORY_NX);
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says
  2021-09-24 13:48 [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says Christophe Leroy
  2021-09-24 13:48 ` [PATCH 2/3] powerpc: Use generic version of arch_is_kernel_initmem_freed() Christophe Leroy
  2021-09-24 13:48 ` [PATCH 3/3] s390: " Christophe Leroy
@ 2021-09-27 13:11 ` Michael Ellerman
  2021-09-27 13:51   ` Christophe Leroy
  2 siblings, 1 reply; 5+ messages in thread
From: Michael Ellerman @ 2021-09-27 13:11 UTC (permalink / raw)
  To: Christophe Leroy, Andrew Morton, arnd
  Cc: Christophe Leroy, linux-kernel, linux-mm, linux-s390,
	linuxppc-dev, linux-arch, Gerald Schaefer

Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> Commit 7a5da02de8d6 ("locking/lockdep: check for freed initmem in
> static_obj()") added arch_is_kernel_initmem_freed() which is supposed
> to report whether an object is part of already freed init memory.
>
> For the time being, the generic version of arch_is_kernel_initmem_freed()
> always reports 'false', allthough free_initmem() is generically called
> on all architectures.
>
> Therefore, change the generic version of arch_is_kernel_initmem_freed()
> to check whether free_initmem() has been called. If so, then check
> if a given address falls into init memory.
>
> In order to use function init_section_contains(), the fonction is
> moved at the end of asm-generic/section.h
>
> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  include/asm-generic/sections.h | 31 +++++++++++++++++--------------
>  1 file changed, 17 insertions(+), 14 deletions(-)
>
> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
> index d16302d3eb59..d1e5bb2c6b72 100644
> --- a/include/asm-generic/sections.h
> +++ b/include/asm-generic/sections.h
> @@ -172,4 +158,21 @@ static inline bool is_kernel_rodata(unsigned long addr)
>  	       addr < (unsigned long)__end_rodata;
>  }
>  
> +/*
> + * Check if an address is part of freed initmem. This is needed on architectures
> + * with virt == phys kernel mapping, for code that wants to check if an address
> + * is part of a static object within [_stext, _end]. After initmem is freed,
> + * memory can be allocated from it, and such allocations would then have
> + * addresses within the range [_stext, _end].
> + */
> +#ifndef arch_is_kernel_initmem_freed
> +static inline int arch_is_kernel_initmem_freed(unsigned long addr)
> +{
> +	if (system_state < SYSTEM_RUNNING)
> +		return 0;
> +
> +	return init_section_contains((void *)addr, 1);
> +}
> +#endif

This will return an incorrect result for a short period during boot
won't it?

See init/main.c:

static int __ref kernel_init(void *unused)
{
	...
	free_initmem();			<- memory is freed here
	mark_readonly();

	/*
	 * Kernel mappings are now finalized - update the userspace page-table
	 * to finalize PTI.
	 */
	pti_finalize();

	system_state = SYSTEM_RUNNING;


After free_initmem() we have address ranges that are now freed initmem,
but arch_is_kernel_initmem_freed() continues to return 0 (false) for all
addresses, until we update system_state.

Possibly that doesn't matter for any of the current callers, but it
seems pretty dicey to me.

cheers


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says
  2021-09-27 13:11 ` [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says Michael Ellerman
@ 2021-09-27 13:51   ` Christophe Leroy
  0 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2021-09-27 13:51 UTC (permalink / raw)
  To: Michael Ellerman, Andrew Morton, arnd
  Cc: linux-kernel, linux-mm, linux-s390, linuxppc-dev, linux-arch,
	Gerald Schaefer



Le 27/09/2021 à 15:11, Michael Ellerman a écrit :
> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>> Commit 7a5da02de8d6 ("locking/lockdep: check for freed initmem in
>> static_obj()") added arch_is_kernel_initmem_freed() which is supposed
>> to report whether an object is part of already freed init memory.
>>
>> For the time being, the generic version of arch_is_kernel_initmem_freed()
>> always reports 'false', allthough free_initmem() is generically called
>> on all architectures.
>>
>> Therefore, change the generic version of arch_is_kernel_initmem_freed()
>> to check whether free_initmem() has been called. If so, then check
>> if a given address falls into init memory.
>>
>> In order to use function init_section_contains(), the fonction is
>> moved at the end of asm-generic/section.h
>>
>> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>> ---
>>   include/asm-generic/sections.h | 31 +++++++++++++++++--------------
>>   1 file changed, 17 insertions(+), 14 deletions(-)
>>
>> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
>> index d16302d3eb59..d1e5bb2c6b72 100644
>> --- a/include/asm-generic/sections.h
>> +++ b/include/asm-generic/sections.h
>> @@ -172,4 +158,21 @@ static inline bool is_kernel_rodata(unsigned long addr)
>>   	       addr < (unsigned long)__end_rodata;
>>   }
>>   
>> +/*
>> + * Check if an address is part of freed initmem. This is needed on architectures
>> + * with virt == phys kernel mapping, for code that wants to check if an address
>> + * is part of a static object within [_stext, _end]. After initmem is freed,
>> + * memory can be allocated from it, and such allocations would then have
>> + * addresses within the range [_stext, _end].
>> + */
>> +#ifndef arch_is_kernel_initmem_freed
>> +static inline int arch_is_kernel_initmem_freed(unsigned long addr)
>> +{
>> +	if (system_state < SYSTEM_RUNNING)
>> +		return 0;
>> +
>> +	return init_section_contains((void *)addr, 1);
>> +}
>> +#endif
> 
> This will return an incorrect result for a short period during boot
> won't it?
> 
> See init/main.c:
> 
> static int __ref kernel_init(void *unused)
> {
> 	...
> 	free_initmem();			<- memory is freed here
> 	mark_readonly();
> 
> 	/*
> 	 * Kernel mappings are now finalized - update the userspace page-table
> 	 * to finalize PTI.
> 	 */
> 	pti_finalize();
> 
> 	system_state = SYSTEM_RUNNING;
> 
> 
> After free_initmem() we have address ranges that are now freed initmem,
> but arch_is_kernel_initmem_freed() continues to return 0 (false) for all
> addresses, until we update system_state.
> 
> Possibly that doesn't matter for any of the current callers, but it
> seems pretty dicey to me.
> 

Yes I saw it but as function core_kernel_text() uses that criteria for 
deciding whether a given init text address is valid or not, I thought it 
was just ok.

Should we add an intermediate state called for exemple 
SYSTEM_FREEING_INIT just before SYSTEM_RUNNING ?

Christophe


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-09-27 13:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-24 13:48 [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says Christophe Leroy
2021-09-24 13:48 ` [PATCH 2/3] powerpc: Use generic version of arch_is_kernel_initmem_freed() Christophe Leroy
2021-09-24 13:48 ` [PATCH 3/3] s390: " Christophe Leroy
2021-09-27 13:11 ` [PATCH 1/3] mm: Make generic arch_is_kernel_initmem_freed() do what it says Michael Ellerman
2021-09-27 13:51   ` Christophe Leroy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).