Re: [PATCH -next v2 1/2] riscv: kdump: Implement crashkernel=X,[high,low]

2023-03-30 Thread Baoquan He
On 03/30/23 at 09:40pm, chenjiahao (C) wrote:
..
> Agreed, I will clean this up later in next version.
> > > + if (ret || !crash_size)
> > > + return;
> > > +
> > > + /*
> > > +  * crashkernel=Y,low is valid only when crashkernel=X,high
> > > +  * is passed and high memory is reserved successful.
> > > +  */
> > > + ret = parse_crashkernel_low(boot_command_line, 0, 
> > > _low_size, _base);
> > > + if (ret == -ENOENT)
> > > + crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
> > > + else if (ret)
> > > + return;
> > > +
> > > + search_start = dma32_phys_limit;
> > > + } else if (ret || !crash_size) {
> > > + /* Invalid argument value specified */
> > >   return;
> > > + }
> > >   crash_size = PAGE_ALIGN(crash_size);
> > > @@ -1201,16 +1246,26 @@ static void __init reserve_crashkernel(void)
> > >*/
> > >   crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE,
> > >  search_start,
> > > -min(search_end, (unsigned long) 
> > > SZ_4G));
> > > +min(search_end, (unsigned 
> > > long)dma32_phys_limit));
> > >   if (crash_base == 0) {
> > The above conditional check isn't right. If crashkernel=size@offset
> > specified, the reservation failure won't trigger retry. This seems to be
> > originally introduced by old commit, while this need be fixed firstly.
> 
> Just a little curious about the rule to cope with this specific case. If
> "crashkernel=size@offset" was passed
> 
> but reserve failed, should try again to allocate in high memory, regardless
> the specified size@offset,
> 
> or just throw a warning and return? Since I noticed the current logic here
> on Arm64 is to check if !fixed_base first

Yeah, we need mark the "crashkernel=size@offset" case and avoid to
retry. Because you won't succeed if  memblock has already failed to
reserve an unavailable memory region, retry is meaningless. This has
been done in x86, arm64.


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v5 2/2] x86/purgatory: Add linker script

2023-03-30 Thread Borislav Petkov
On Thu, Mar 30, 2023 at 11:31:27AM -0400, Steven Rostedt wrote:
> On Thu, 30 Mar 2023 17:18:26 +0200
> Borislav Petkov  wrote:
> 
> > On Thu, Mar 30, 2023 at 11:15:23AM -0400, Steven Rostedt wrote:
> > > > Make sure that the .text section is not divided in multiple overlapping
> > > > sections. This is not supported by kexec_file.  
> > 
> > And?
> > 
> > What is the failure scenario? Why are you fixing it? Why do we care?
> > 
> > This is way too laconic.
> > 
> 
> Yeah, I think the change log in patch 1 needs to be in this patch too,
> which gives better context.

Just read it.

Why did it work with clang version < 16?

+ toolchains ML.

-- 
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v5 2/2] x86/purgatory: Add linker script

2023-03-30 Thread Steven Rostedt
On Thu, 30 Mar 2023 17:18:26 +0200
Borislav Petkov  wrote:

> On Thu, Mar 30, 2023 at 11:15:23AM -0400, Steven Rostedt wrote:
> > > Make sure that the .text section is not divided in multiple overlapping
> > > sections. This is not supported by kexec_file.  
> 
> And?
> 
> What is the failure scenario? Why are you fixing it? Why do we care?
> 
> This is way too laconic.
> 

Yeah, I think the change log in patch 1 needs to be in this patch too,
which gives better context.

-- Steve

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v5 2/2] x86/purgatory: Add linker script

2023-03-30 Thread Borislav Petkov
On Thu, Mar 30, 2023 at 11:15:23AM -0400, Steven Rostedt wrote:
> > Make sure that the .text section is not divided in multiple overlapping
> > sections. This is not supported by kexec_file.

And?

What is the failure scenario? Why are you fixing it? Why do we care?

This is way too laconic.

-- 
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v5 2/2] x86/purgatory: Add linker script

2023-03-30 Thread Steven Rostedt


Hmm, this patch may need some more eyes. At least from the x86 maintainers.

-- Steve


On Thu, 30 Mar 2023 11:44:48 +0200
Ricardo Ribalda  wrote:

> Make sure that the .text section is not divided in multiple overlapping
> sections. This is not supported by kexec_file.
> 
> Signed-off-by: Ricardo Ribalda 
> ---
>  arch/x86/purgatory/.gitignore|  2 ++
>  arch/x86/purgatory/Makefile  | 20 +
>  arch/x86/purgatory/kexec-purgatory.S |  2 +-
>  arch/x86/purgatory/purgatory.lds.S   | 57 
> 
>  4 files changed, 74 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/x86/purgatory/.gitignore b/arch/x86/purgatory/.gitignore
> index d2be1500671d..1fe71fe5945d 100644
> --- a/arch/x86/purgatory/.gitignore
> +++ b/arch/x86/purgatory/.gitignore
> @@ -1 +1,3 @@
>  purgatory.chk
> +purgatory.lds
> +purgatory
> diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
> index 17f09dc26381..4dc96d409bec 100644
> --- a/arch/x86/purgatory/Makefile
> +++ b/arch/x86/purgatory/Makefile
> @@ -16,10 +16,11 @@ CFLAGS_sha256.o := -D__DISABLE_EXPORTS
>  
>  # When linking purgatory.ro with -r unresolved symbols are not checked,
>  # also link a purgatory.chk binary without -r to check for unresolved 
> symbols.
> -PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib
> -LDFLAGS_purgatory.ro := -r $(PURGATORY_LDFLAGS)
> -LDFLAGS_purgatory.chk := $(PURGATORY_LDFLAGS)
> -targets += purgatory.ro purgatory.chk
> +PURGATORY_LDFLAGS := -nostdlib -z nodefaultlib
> +LDFLAGS_purgatory := -r $(PURGATORY_LDFLAGS) -T
> +LDFLAGS_purgatory.chk := -e purgatory_start $(PURGATORY_LDFLAGS)
> +
> +targets += purgatory.lds purgatory.ro purgatory.chk
>  
>  # Sanitizer, etc. runtimes are unavailable and cannot be linked here.
>  GCOV_PROFILE := n
> @@ -72,10 +73,17 @@ CFLAGS_string.o   += $(PURGATORY_CFLAGS)
>  AFLAGS_REMOVE_setup-x86_$(BITS).o+= -Wa,-gdwarf-2
>  AFLAGS_REMOVE_entry64.o  += -Wa,-gdwarf-2
>  
> -$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
> +OBJCOPYFLAGS_purgatory.ro := -O elf64-x86-64
> +OBJCOPYFLAGS_purgatory.ro += --remove-section='*debug*'
> +OBJCOPYFLAGS_purgatory.ro += --remove-section='.comment'
> +OBJCOPYFLAGS_purgatory.ro += --remove-section='.note.*'
> +$(obj)/purgatory.ro: $(obj)/purgatory FORCE
> + $(call if_changed,objcopy)
> +
> +$(obj)/purgatory.chk: $(obj)/purgatory FORCE
>   $(call if_changed,ld)
>  
> -$(obj)/purgatory.chk: $(obj)/purgatory.ro FORCE
> +$(obj)/purgatory: $(obj)/purgatory.lds $(PURGATORY_OBJS) FORCE
>   $(call if_changed,ld)
>  
>  $(obj)/kexec-purgatory.o: $(obj)/purgatory.ro $(obj)/purgatory.chk
> diff --git a/arch/x86/purgatory/kexec-purgatory.S 
> b/arch/x86/purgatory/kexec-purgatory.S
> index 8530fe93b718..54b0d0b4dc42 100644
> --- a/arch/x86/purgatory/kexec-purgatory.S
> +++ b/arch/x86/purgatory/kexec-purgatory.S
> @@ -5,7 +5,7 @@
>   .align  8
>  kexec_purgatory:
>   .globl  kexec_purgatory
> - .incbin "arch/x86/purgatory/purgatory.ro"
> + .incbin "arch/x86/purgatory/purgatory"
>  .Lkexec_purgatory_end:
>  
>   .align  8
> diff --git a/arch/x86/purgatory/purgatory.lds.S 
> b/arch/x86/purgatory/purgatory.lds.S
> new file mode 100644
> index ..610da88aafa0
> --- /dev/null
> +++ b/arch/x86/purgatory/purgatory.lds.S
> @@ -0,0 +1,57 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include 
> +
> +OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT)
> +
> +#undef i386
> +
> +#include 
> +#include 
> +
> +ENTRY(purgatory_start)
> +
> +SECTIONS
> +{
> + . = 0;
> + .head.text : {
> + _head = . ;
> + HEAD_TEXT
> + _ehead = . ;
> + }
> + .rodata : {
> + _rodata = . ;
> + *(.rodata)   /* read-only data */
> + *(.rodata.*)
> + _erodata = . ;
> + }
> + .text : {
> + _text = .;  /* Text */
> + *(.text)
> + *(.text.*)
> + *(.noinstr.text)
> + _etext = . ;
> + }
> + .data : {
> + _data = . ;
> + *(.data)
> + *(.data.*)
> + *(.bss.efistub)
> + _edata = . ;
> + }
> + . = ALIGN(L1_CACHE_BYTES);
> + .bss : {
> + _bss = . ;
> + *(.bss)
> + *(.bss.*)
> + *(COMMON)
> + . = ALIGN(8);   /* For convenience during zeroing */
> + _ebss = .;
> + }
> +
> + /* Sections to be discarded */
> + /DISCARD/ : {
> + *(.eh_frame)
> + *(*__ksymtab*)
> + *(___kcrctab*)
> + }
> +}
> 


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v5 1/2] kexec: Support purgatories with .text.hot sections

2023-03-30 Thread Steven Rostedt
On Thu, 30 Mar 2023 11:44:47 +0200
Ricardo Ribalda  wrote:

> Clang16 links the purgatory text in two sections:
> 
>   [ 1] .text PROGBITS   0040
>11a1    AX   0 0 16
>   [ 2] .rela.textRELA   3498
>0648  0018   I  24 1 8
>   ...
>   [17] .text.hot.PROGBITS   3220
>020b    AX   0 0 1
>   [18] .rela.text.hot.   RELA   4428
>0078  0018   I  2417 8
> 
> And both of them have their range [sh_addr ... sh_addr+sh_size] on the
> area pointed by `e_entry`.
> 
> This causes that image->start is calculated twice, once for .text and
> another time for .text.hot. The second calculation leaves image->start
> in a random location.
> 
> Because of this, the system crashes immediately after:
> 
> kexec_core: Starting new kernel
> 
> Cc: sta...@vger.kernel.org
> Fixes: 930457057abe ("kernel/kexec_file.c: split up __kexec_load_puragory")
> Reviewed-by: Ross Zwisler 
> Signed-off-by: Ricardo Ribalda 
> ---
>  kernel/kexec_file.c | 14 +-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index f1a0e4e3fb5c..c7a0e51a6d87 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -901,10 +901,22 @@ static int kexec_purgatory_setup_sechdrs(struct 
> purgatory_info *pi,
>   }
>  
>   offset = ALIGN(offset, align);
> +
> + /*
> +  * Check if the segment contains the entry point, if so,
> +  * calculate the value of image->start based on it.
> +  * If the compiler has produced more than one .text section
> +  * (Eg: .text.hot), they are generally after the main .text
> +  * section, and they shall not be used to calculate
> +  * image->start. So do not re-calculate image->start if it
> +  * is not set to the initial value, and warn the user so they
> +  * have a chance to fix their purgatory's linker script.
> +  */
>   if (sechdrs[i].sh_flags & SHF_EXECINSTR &&
>   pi->ehdr->e_entry >= sechdrs[i].sh_addr &&
>   pi->ehdr->e_entry < (sechdrs[i].sh_addr
> -  + sechdrs[i].sh_size)) {
> +  + sechdrs[i].sh_size) &&
> + !WARN_ON(kbuf->image->start != pi->ehdr->e_entry)) {
>   kbuf->image->start -= sechdrs[i].sh_addr;
>   kbuf->image->start += kbuf->mem + offset;
>   }
> 

Reviewed-by: Steven Rostedt (Google) 

Thanks Ricardo!

-- Steve

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH -next v2 1/2] riscv: kdump: Implement crashkernel=X,[high,low]

2023-03-30 Thread chenjiahao (C)



On 2023/3/29 19:19, Baoquan He wrote:

On 03/28/23 at 07:51pm, Chen Jiahao wrote:


Thanks for reviewing.


On riscv, the current crash kernel allocation logic is trying to
allocate within 32bit addressible memory region by default, if
failed, try to allocate without 4G restriction.

In need of saving DMA zone memory while allocating a relatively large
crash kernel region, allocating the reserved memory top down in
high memory, without overlapping the DMA zone, is a mature solution.
Here introduce the parameter option crashkernel=X,[high,low].

One can reserve the crash kernel from high memory above DMA zone range
by explicitly passing "crashkernel=X,high"; or reserve a memory range
below 4G with "crashkernel=X,low".

Signed-off-by: Chen Jiahao 
---
  arch/riscv/kernel/setup.c |  5 
  arch/riscv/mm/init.c  | 63 ---
  2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index 5d3184cbf518..ea84e5047c23 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -176,6 +176,11 @@ static void __init init_resources(void)
if (ret < 0)
goto error;
}
+   if (crashk_low_res.start != crashk_low_res.end) {
+   ret = add_resource(_resource, _low_res);
+   if (ret < 0)
+   goto error;
+   }
  #endif
  
  #ifdef CONFIG_CRASH_DUMP

diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 478d6763a01a..b7708cc467fa 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -1152,6 +1152,28 @@ static inline void setup_vm_final(void)
  }
  #endif /* CONFIG_MMU */
  
+/* Reserve 128M low memory by default for swiotlb buffer */

+#define DEFAULT_CRASH_KERNEL_LOW_SIZE  (128UL << 20)
+
+static int __init reserve_crashkernel_low(unsigned long long low_size)
+{
+   unsigned long long low_base;
+
+   low_base = memblock_phys_alloc_range(low_size, PMD_SIZE, 0, 
dma32_phys_limit);
+   if (!low_base) {
+   pr_err("cannot allocate crashkernel low memory 
(size:0x%llx).\n", low_size);
+   return -ENOMEM;
+   }
+
+   pr_info("crashkernel low memory reserved: 0x%016llx - 0x%016llx (%lld 
MB)\n",
+   low_base, low_base + low_size, low_size >> 20);
+
+   crashk_low_res.start = low_base;
+   crashk_low_res.end = low_base + low_size - 1;
+
+   return 0;
+}
+
  /*
   * reserve_crashkernel() - reserves memory for crash kernel
   *
@@ -1163,6 +1185,7 @@ static void __init reserve_crashkernel(void)
  {
unsigned long long crash_base = 0;
unsigned long long crash_size = 0;
+   unsigned long long crash_low_size = 0;
unsigned long search_start = memblock_start_of_DRAM();
unsigned long search_end = memblock_end_of_DRAM();
  
@@ -1182,8 +1205,30 @@ static void __init reserve_crashkernel(void)
  
  	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),

_size, _base);
-   if (ret || !crash_size)
+   if (ret == -ENOENT) {
+   /*
+* crashkernel=X,[high,low] can be specified or not, but
+* invalid value is not allowed.
+*/
+   ret = parse_crashkernel_high(boot_command_line, 0, _size, 
_base);

I would add a local variable to assign boot_command_line to it just like
arm64 does. Then these lines could be shorter.

char *cmdline = boot_command_line;

Agreed, I will clean this up later in next version.

+   if (ret || !crash_size)
+   return;
+
+   /*
+* crashkernel=Y,low is valid only when crashkernel=X,high
+* is passed and high memory is reserved successful.
+*/
+   ret = parse_crashkernel_low(boot_command_line, 0, _low_size, 
_base);
+   if (ret == -ENOENT)
+   crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
+   else if (ret)
+   return;
+
+   search_start = dma32_phys_limit;
+   } else if (ret || !crash_size) {
+   /* Invalid argument value specified */
return;
+   }
  
  	crash_size = PAGE_ALIGN(crash_size);
  
@@ -1201,16 +1246,26 @@ static void __init reserve_crashkernel(void)

 */
crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE,
   search_start,
-  min(search_end, (unsigned long) 
SZ_4G));
+  min(search_end, (unsigned 
long)dma32_phys_limit));
if (crash_base == 0) {

The above conditional check isn't right. If crashkernel=size@offset
specified, the reservation failure won't trigger retry. This seems to be
originally introduced by old commit, while this need be fixed firstly.


Just a little curious about 

Re: [PATCH v4 1/2] kexec: Support purgatories with .text.hot sections

2023-03-30 Thread Ricardo Ribalda
Hi Simon

Thanks for your review!

On Thu, 30 Mar 2023 at 09:49, Simon Horman  wrote:
>
> On Mon, Mar 27, 2023 at 05:06:53PM +0200, Ricardo Ribalda wrote:
> > Clang16 links the purgatory text in two sections:
> >
> >   [ 1] .text PROGBITS   0040
> >11a1    AX   0 0 16
> >   [ 2] .rela.textRELA   3498
> >0648  0018   I  24 1 8
> >   ...
> >   [17] .text.hot.PROGBITS   3220
> >020b    AX   0 0 1
> >   [18] .rela.text.hot.   RELA   4428
> >0078  0018   I  2417 8
> >
> > And both of them have their range [sh_addr ... sh_addr+sh_size] on the
> > area pointed by `e_entry`.
> >
> > This causes that image->start is calculated twice, once for .text and
> > another time for .text.hot. The second calculation leaves image->start
> > in a random location.
> >
> > Because of this, the system crashes inmediatly after:
>
> s/inmediatly/immediately/
>
> >
> > kexec_core: Starting new kernel
> >
> > Cc: sta...@vger.kernel.org
>
> Maybe a fixes tag is warranted here.
>
> > Reviewed-by: Ross Zwisler 
> > Signed-off-by: Ricardo Ribalda 
> > ---
> >  kernel/kexec_file.c | 13 -
> >  1 file changed, 12 insertions(+), 1 deletion(-)
> >
> > diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> > index f1a0e4e3fb5c..25a37d8f113a 100644
> > --- a/kernel/kexec_file.c
> > +++ b/kernel/kexec_file.c
> > @@ -901,10 +901,21 @@ static int kexec_purgatory_setup_sechdrs(struct 
> > purgatory_info *pi,
> >   }
> >
> >   offset = ALIGN(offset, align);
> > +
> > + /*
> > +  * Check if the segment contains the entry point, if so,
> > +  * calculate the value of image->start based on it.
> > +  * If the compiler has produced more than one .text sections
>
> nit: s/sections/section/
>
> > +  * (Eg: .text.hot), they are generally after the main .text
>
> If this is the general case, then are there cases where this doesn't hold?

When looking at this issue, I have only seen .text.hot after .text.
But I cannot warantee that future versions of llvm or gcc decide to
swap the order.

I am going to add a WARN whenever there are two overlapping .text
sections so the user has the chance to update their linker script.

>
> > +  * section, and they shall not be used to calculate
> > +  * image->start. So do not re-calculate image->start if it
> > +  * is not set to the initial value.
> > +  */
> >   if (sechdrs[i].sh_flags & SHF_EXECINSTR &&
> >   pi->ehdr->e_entry >= sechdrs[i].sh_addr &&
> >   pi->ehdr->e_entry < (sechdrs[i].sh_addr
> > -  + sechdrs[i].sh_size)) {
> > +  + sechdrs[i].sh_size) &&
> > + kbuf->image->start == pi->ehdr->e_entry) {
> >   kbuf->image->start -= sechdrs[i].sh_addr;
> >   kbuf->image->start += kbuf->mem + offset;
> >   }
> >
> > --
> > 2.40.0.348.gf938b09366-goog-b4-0.11.0-dev-696ae
> >
> > ___
> > kexec mailing list
> > kexec@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kexec
> >



--
Ricardo Ribalda

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v5 2/2] x86/purgatory: Add linker script

2023-03-30 Thread Ricardo Ribalda
Make sure that the .text section is not divided in multiple overlapping
sections. This is not supported by kexec_file.

Signed-off-by: Ricardo Ribalda 
---
 arch/x86/purgatory/.gitignore|  2 ++
 arch/x86/purgatory/Makefile  | 20 +
 arch/x86/purgatory/kexec-purgatory.S |  2 +-
 arch/x86/purgatory/purgatory.lds.S   | 57 
 4 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/arch/x86/purgatory/.gitignore b/arch/x86/purgatory/.gitignore
index d2be1500671d..1fe71fe5945d 100644
--- a/arch/x86/purgatory/.gitignore
+++ b/arch/x86/purgatory/.gitignore
@@ -1 +1,3 @@
 purgatory.chk
+purgatory.lds
+purgatory
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
index 17f09dc26381..4dc96d409bec 100644
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -16,10 +16,11 @@ CFLAGS_sha256.o := -D__DISABLE_EXPORTS
 
 # When linking purgatory.ro with -r unresolved symbols are not checked,
 # also link a purgatory.chk binary without -r to check for unresolved symbols.
-PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib
-LDFLAGS_purgatory.ro := -r $(PURGATORY_LDFLAGS)
-LDFLAGS_purgatory.chk := $(PURGATORY_LDFLAGS)
-targets += purgatory.ro purgatory.chk
+PURGATORY_LDFLAGS := -nostdlib -z nodefaultlib
+LDFLAGS_purgatory := -r $(PURGATORY_LDFLAGS) -T
+LDFLAGS_purgatory.chk := -e purgatory_start $(PURGATORY_LDFLAGS)
+
+targets += purgatory.lds purgatory.ro purgatory.chk
 
 # Sanitizer, etc. runtimes are unavailable and cannot be linked here.
 GCOV_PROFILE   := n
@@ -72,10 +73,17 @@ CFLAGS_string.o += $(PURGATORY_CFLAGS)
 AFLAGS_REMOVE_setup-x86_$(BITS).o  += -Wa,-gdwarf-2
 AFLAGS_REMOVE_entry64.o+= -Wa,-gdwarf-2
 
-$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
+OBJCOPYFLAGS_purgatory.ro := -O elf64-x86-64
+OBJCOPYFLAGS_purgatory.ro += --remove-section='*debug*'
+OBJCOPYFLAGS_purgatory.ro += --remove-section='.comment'
+OBJCOPYFLAGS_purgatory.ro += --remove-section='.note.*'
+$(obj)/purgatory.ro: $(obj)/purgatory FORCE
+   $(call if_changed,objcopy)
+
+$(obj)/purgatory.chk: $(obj)/purgatory FORCE
$(call if_changed,ld)
 
-$(obj)/purgatory.chk: $(obj)/purgatory.ro FORCE
+$(obj)/purgatory: $(obj)/purgatory.lds $(PURGATORY_OBJS) FORCE
$(call if_changed,ld)
 
 $(obj)/kexec-purgatory.o: $(obj)/purgatory.ro $(obj)/purgatory.chk
diff --git a/arch/x86/purgatory/kexec-purgatory.S 
b/arch/x86/purgatory/kexec-purgatory.S
index 8530fe93b718..54b0d0b4dc42 100644
--- a/arch/x86/purgatory/kexec-purgatory.S
+++ b/arch/x86/purgatory/kexec-purgatory.S
@@ -5,7 +5,7 @@
.align  8
 kexec_purgatory:
.globl  kexec_purgatory
-   .incbin "arch/x86/purgatory/purgatory.ro"
+   .incbin "arch/x86/purgatory/purgatory"
 .Lkexec_purgatory_end:
 
.align  8
diff --git a/arch/x86/purgatory/purgatory.lds.S 
b/arch/x86/purgatory/purgatory.lds.S
new file mode 100644
index ..610da88aafa0
--- /dev/null
+++ b/arch/x86/purgatory/purgatory.lds.S
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include 
+
+OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT)
+
+#undef i386
+
+#include 
+#include 
+
+ENTRY(purgatory_start)
+
+SECTIONS
+{
+   . = 0;
+   .head.text : {
+   _head = . ;
+   HEAD_TEXT
+   _ehead = . ;
+   }
+   .rodata : {
+   _rodata = . ;
+   *(.rodata)   /* read-only data */
+   *(.rodata.*)
+   _erodata = . ;
+   }
+   .text : {
+   _text = .;  /* Text */
+   *(.text)
+   *(.text.*)
+   *(.noinstr.text)
+   _etext = . ;
+   }
+   .data : {
+   _data = . ;
+   *(.data)
+   *(.data.*)
+   *(.bss.efistub)
+   _edata = . ;
+   }
+   . = ALIGN(L1_CACHE_BYTES);
+   .bss : {
+   _bss = . ;
+   *(.bss)
+   *(.bss.*)
+   *(COMMON)
+   . = ALIGN(8);   /* For convenience during zeroing */
+   _ebss = .;
+   }
+
+   /* Sections to be discarded */
+   /DISCARD/ : {
+   *(.eh_frame)
+   *(*__ksymtab*)
+   *(___kcrctab*)
+   }
+}

-- 
2.40.0.348.gf938b09366-goog


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v5 0/2] kexec: Fix kexec_file_load for llvm16

2023-03-30 Thread Ricardo Ribalda
When upreving llvm I realised that kexec stopped working on my test
platform. This patch fixes it.

Signed-off-by: Ricardo Ribalda 
---
Changes in v5:
- Add warning when multiple text sections are found. Thanks Simon!
- Add Fixes tag.
- Link to v4: 
https://lore.kernel.org/r/20230321-kexec_clang16-v4-0-1340518f9...@chromium.org

Changes in v4:
- Add Cc: stable
- Add linker script for x86
- Add a warning when the kernel image has overlapping sections.
- Link to v3: 
https://lore.kernel.org/r/20230321-kexec_clang16-v3-0-5f016c8d0...@chromium.org

Changes in v3:
- Fix initial value. Thanks Ross!
- Link to v2: 
https://lore.kernel.org/r/20230321-kexec_clang16-v2-0-d10e5d517...@chromium.org

Changes in v2:
- Fix if condition. Thanks Steven!.
- Update Philipp email. Thanks Baoquan.
- Link to v1: 
https://lore.kernel.org/r/20230321-kexec_clang16-v1-0-a768fc2c7...@chromium.org

---
Ricardo Ribalda (2):
  kexec: Support purgatories with .text.hot sections
  x86/purgatory: Add linker script

 arch/x86/purgatory/.gitignore|  2 ++
 arch/x86/purgatory/Makefile  | 20 +
 arch/x86/purgatory/kexec-purgatory.S |  2 +-
 arch/x86/purgatory/purgatory.lds.S   | 57 
 kernel/kexec_file.c  | 14 -
 5 files changed, 87 insertions(+), 8 deletions(-)
---
base-commit: 17214b70a159c6547df9ae204a6275d983146f6b
change-id: 20230321-kexec_clang16-4510c23d129c

Best regards,
-- 
Ricardo Ribalda 


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v5 1/2] kexec: Support purgatories with .text.hot sections

2023-03-30 Thread Ricardo Ribalda
Clang16 links the purgatory text in two sections:

  [ 1] .text PROGBITS   0040
   11a1    AX   0 0 16
  [ 2] .rela.textRELA   3498
   0648  0018   I  24 1 8
  ...
  [17] .text.hot.PROGBITS   3220
   020b    AX   0 0 1
  [18] .rela.text.hot.   RELA   4428
   0078  0018   I  2417 8

And both of them have their range [sh_addr ... sh_addr+sh_size] on the
area pointed by `e_entry`.

This causes that image->start is calculated twice, once for .text and
another time for .text.hot. The second calculation leaves image->start
in a random location.

Because of this, the system crashes immediately after:

kexec_core: Starting new kernel

Cc: sta...@vger.kernel.org
Fixes: 930457057abe ("kernel/kexec_file.c: split up __kexec_load_puragory")
Reviewed-by: Ross Zwisler 
Signed-off-by: Ricardo Ribalda 
---
 kernel/kexec_file.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index f1a0e4e3fb5c..c7a0e51a6d87 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -901,10 +901,22 @@ static int kexec_purgatory_setup_sechdrs(struct 
purgatory_info *pi,
}
 
offset = ALIGN(offset, align);
+
+   /*
+* Check if the segment contains the entry point, if so,
+* calculate the value of image->start based on it.
+* If the compiler has produced more than one .text section
+* (Eg: .text.hot), they are generally after the main .text
+* section, and they shall not be used to calculate
+* image->start. So do not re-calculate image->start if it
+* is not set to the initial value, and warn the user so they
+* have a chance to fix their purgatory's linker script.
+*/
if (sechdrs[i].sh_flags & SHF_EXECINSTR &&
pi->ehdr->e_entry >= sechdrs[i].sh_addr &&
pi->ehdr->e_entry < (sechdrs[i].sh_addr
-+ sechdrs[i].sh_size)) {
++ sechdrs[i].sh_size) &&
+   !WARN_ON(kbuf->image->start != pi->ehdr->e_entry)) {
kbuf->image->start -= sechdrs[i].sh_addr;
kbuf->image->start += kbuf->mem + offset;
}

-- 
2.40.0.348.gf938b09366-goog


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4 1/2] kexec: Support purgatories with .text.hot sections

2023-03-30 Thread Simon Horman
On Mon, Mar 27, 2023 at 05:06:53PM +0200, Ricardo Ribalda wrote:
> Clang16 links the purgatory text in two sections:
> 
>   [ 1] .text PROGBITS   0040
>11a1    AX   0 0 16
>   [ 2] .rela.textRELA   3498
>0648  0018   I  24 1 8
>   ...
>   [17] .text.hot.PROGBITS   3220
>020b    AX   0 0 1
>   [18] .rela.text.hot.   RELA   4428
>0078  0018   I  2417 8
> 
> And both of them have their range [sh_addr ... sh_addr+sh_size] on the
> area pointed by `e_entry`.
> 
> This causes that image->start is calculated twice, once for .text and
> another time for .text.hot. The second calculation leaves image->start
> in a random location.
> 
> Because of this, the system crashes inmediatly after:

s/inmediatly/immediately/

> 
> kexec_core: Starting new kernel
> 
> Cc: sta...@vger.kernel.org

Maybe a fixes tag is warranted here.

> Reviewed-by: Ross Zwisler 
> Signed-off-by: Ricardo Ribalda 
> ---
>  kernel/kexec_file.c | 13 -
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index f1a0e4e3fb5c..25a37d8f113a 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -901,10 +901,21 @@ static int kexec_purgatory_setup_sechdrs(struct 
> purgatory_info *pi,
>   }
>  
>   offset = ALIGN(offset, align);
> +
> + /*
> +  * Check if the segment contains the entry point, if so,
> +  * calculate the value of image->start based on it.
> +  * If the compiler has produced more than one .text sections

nit: s/sections/section/

> +  * (Eg: .text.hot), they are generally after the main .text

If this is the general case, then are there cases where this doesn't hold?

> +  * section, and they shall not be used to calculate
> +  * image->start. So do not re-calculate image->start if it
> +  * is not set to the initial value.
> +  */
>   if (sechdrs[i].sh_flags & SHF_EXECINSTR &&
>   pi->ehdr->e_entry >= sechdrs[i].sh_addr &&
>   pi->ehdr->e_entry < (sechdrs[i].sh_addr
> -  + sechdrs[i].sh_size)) {
> +  + sechdrs[i].sh_size) &&
> + kbuf->image->start == pi->ehdr->e_entry) {
>   kbuf->image->start -= sechdrs[i].sh_addr;
>   kbuf->image->start += kbuf->mem + offset;
>   }
> 
> -- 
> 2.40.0.348.gf938b09366-goog-b4-0.11.0-dev-696ae
> 
> ___
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
> 

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec