Re: [PATCH v3 2/7] ima: kexec: move ima log copy from kexec load to execute

2024-01-11 Thread Tushar Sugandhi

Apologies for the late response on this particular patch (v3 2/7) Mimi.
I was on vacation in December.
I was meaning to respond to this one when I came back, but I was caught 
in between other work items last few days. Sorry if it caused any 
confusion.


Responses below.

On 12/20/23 11:02, Mimi Zohar wrote:

Hi Tushar,

On Fri, 2023-12-15 at 17:07 -0800, Tushar Sugandhi wrote:

ima_dump_measurement_list() is called from  ima_add_kexec_buffer() during
kexec 'load', which may result in loss of IMA measurements between kexec
'load' and 'execute'.  It needs to be called during kexec 'execute'.

Implement ima_update_kexec_buffer(), to be called during kexec 'execute'.
Move ima_dump_measurement_list() function call from ima_add_kexec_buffer()
to ima_update_kexec_buffer().  Make the needed variables global for
accessibility during kexec 'load' and 'execute'. Implement and call
ima_measurements_suspend() and ima_measurements_resume() to help ensure
the integrity of the IMA log during copy. Add a reboot notifier_block to
trigger ima_update_kexec_buffer() during kexec soft-reboot.  Exclude ima
segment from calculating and storing digest in function
kexec_calculate_store_digests(), since ima segment can be modified
after the digest is computed during kexec 'load'.

Signed-off-by: Tushar Sugandhi 


Wow!   That's quite a bit for a single patch.

This patch moves the ima_dump_measurement_list() call from kexec load
to exec, but doesn't register the reboot notifier in this patch.  I
don't see how it is possible with just the previous and this patch
applied that the measurement list is carried across kexec.

Ah. That's a good catch.
I was only checking if I can boot into the Kernel for testing 
bisect-safe readiness for each patch.  I will ensure the move of 
ima_dump_measurement_list() and registering the reboot notifier at 
execute stays an atomic operation in a single patch.





Please test after applying each patch in the patch set to make sure
that the measurement list is properly carried across kexec.


Yup. I was only checking if I can boot into the Kernel after each patch.
My bad. :(

Going forward, I will check each patch for the measurement list carry 
over after kexec.



Additional inline comments below.


---
  include/linux/kexec.h  |  3 ++
  kernel/kexec_file.c|  8 
  security/integrity/ima/ima.h   |  2 +
  security/integrity/ima/ima_kexec.c | 61 +-
  security/integrity/ima/ima_queue.c | 19 ++
  5 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 22b5cd24f581..fd94404acc66 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -366,6 +366,9 @@ struct kimage {
  
  	phys_addr_t ima_buffer_addr;

size_t ima_buffer_size;
+
+   unsigned long ima_segment_index;
+   bool is_ima_segment_index_set;
  #endif
  
  	/* Core ELF header buffer */

diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index f989f5f1933b..bf758fd5062c 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -734,6 +734,14 @@ static int kexec_calculate_store_digests(struct kimage 
*image)
if (ksegment->kbuf == pi->purgatory_buf)
continue;
  
+		/*

+* Skip the segment if ima_segment_index is set and matches
+* the current index
+*/
+   if (image->is_ima_segment_index_set &&
+   i == image->ima_segment_index)
+   continue;


With this change, the IMA segment is not included in the digest
calculation, nor should it be included in the digest verification.
However, I'm not seeing the matching code change in the digest
verification.


Fair question.

But I don't think anything else needs to be done here.

The way kexec_calculate_store_digests() and verify_sha256_digest()
are implemented, it already skips verification of the segments if
the segment is not part of 'purgatory_sha_regions'.

In kexec_calculate_store_digests(), my change is to 'continue' when the
segment is the IMA segment when the function is going through all the
segments in a for loop [1].

Therefore in kexec_calculate_store_digests() -
 - crypto_shash_update() is not called for IMA segment [1].
 - sha_regions[j] is not updated with IMA segment  [1].
 - This 'sha_regions' variable later becomes 'purgatory_sha_regions'
   in kexec_calculate_store_digests  [1].
 - and verify_sha256_digest() only verifies 'purgatory_sha_regions'[2].

 Since IMA segment is not part of the 'purgatory_sha_regions', it is
 not included in the verification as part of verify_sha256_digest().

I have pasted the relevant code below for quick reference [1][2].


Please make ignoring the IMA segment a separate patch.


Sure. Will do.


ret = crypto_shash_update(desc, ksegment->kbuf,
  ksegment->bufsz);
if (ret)

...
...
...

diff 

Re: [PATCH v3 6/7] ima: configure memory to log events between kexec load and execute

2024-01-11 Thread Tushar Sugandhi




On 1/11/24 11:20, Stefan Berger wrote:



On 1/11/24 13:13, Tushar Sugandhi wrote:



On 1/7/24 09:00, Mimi Zohar wrote:

On Fri, 2024-01-05 at 12:20 -0800, Tushar Sugandhi wrote:
diff --git a/security/integrity/ima/Kconfig 
b/security/integrity/ima/Kconfig

index 60a511c6b583..8792b7aab768 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -338,3 +338,12 @@ config IMA_DISABLE_HTABLE
  default n
  help
 This option disables htable to allow measurement of 
duplicate records.

+
+config IMA_KEXEC_EXTRA_MEMORY_KB
+    int
+    depends on IMA && IMA_KEXEC
+    default 64


Since this isn't optional, the default should remain as a half page.
Since a page is architecture specific, the default will need to be 
arch

   specific


It was a feedback from Stefan in the V2 of this series to convert it
from number of PAGES to KB.[1]

But I can revert it to number of pages again.

Also, making the default value as a fraction (1/2 page) feels weird for
a CONFIG variable.

Is it ok to make the default value as one page rather than half page?


The point is not whether the extra memory is specified in terms of 
pages or KB.

For backwards compatibility the existing default should be the same as
previously.  This means the default needs to be architecture specific.b
$ uname -m; getconf PAGESIZE
x86_64
4096
$ uname -m; getconf PAGESIZE
ppc64le
65536

For example:

default 32 if PPC_64K_PAGES
default 2


Ok. Thanks for the clarification.


Do we want to support only 64K or 4K as possible PAGE_SIZE values?
I spot checked a few architectures, there are scenarios where PAGE_SIZE
could be 8K, 16K, 128K, 256K etc. And of course mega pages with
PAGE_SIZE IN MBs (details below).


I would let the user specify the number of kilobytes to reserve and from 
this you can conclude the page numbers:


needed_pages = KBs_TO_RESERVE / PAGE_SIZE
if (KBs_TO_RESERVER % PAGE_SIZE)
     needed_pages++;

    Stefan

Thanks Stefan.

But the issue here is about the default value,
not the user specified value.

Mimi is suggesting to keep the default value half-a-page,
to maintain backwards compatibility.

If we go with the KBs approach -
half-a-page translates to different KBs on different architectures.
And setting the right default value in KBs which would translate to
the desired half-a-page, on a given arch, inside the Kconfig seems
fragile (as I mentioned in the context of Option A in my previous
response.

And if we go with num_pages approach -
putting a fractional value (0.5) as a default in Kconfig seems to be non
trivial too.

Translating num_pages to KBs is trivial in code, but I think its
orthogonal to this conversation, since its about setting the desired 
arch specific default value in Kconfig.



Option A:
-
config IMA_KEXEC_EXTRA_MEMORY_KB
int
depends on IMA && IMA_KEXEC
default 128 if PAGE_SIZE_256KB
default 32 if PPC_64K_PAGES || PAGE_SIZE_64KB || PARISC_PAGE_SIZE_16KB
default 16 if PAGE_SIZE_32KB
default 8 if PAGE_SIZE_16KB || ARC_PAGE_SIZE_16K || 
PARISC_PAGE_SIZE_16KB

default 4 if PAGE_SIZE_8KB || ARC_PAGE_SIZE_8K
default 2
  IMA_KEXEC_EXTRA_MEMORY_KB determines the number of extra
  memory (in KB) to be allocated for IMA measurements added
  during kexec soft-reboot.

Option B:

config IMA_KEXEC_EXTRA_PAGES
int
depends on IMA && IMA_KEXEC
default 1
help
  IMA_KEXEC_EXTRA_PAGES determines the number of extra
  pages to be allocated for IMA measurements added during
  kexec soft-reboot.

~Tushar



Re: [PATCH v3 6/7] ima: configure memory to log events between kexec load and execute

2024-01-11 Thread Stefan Berger




On 1/11/24 13:13, Tushar Sugandhi wrote:



On 1/7/24 09:00, Mimi Zohar wrote:

On Fri, 2024-01-05 at 12:20 -0800, Tushar Sugandhi wrote:
diff --git a/security/integrity/ima/Kconfig 
b/security/integrity/ima/Kconfig

index 60a511c6b583..8792b7aab768 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -338,3 +338,12 @@ config IMA_DISABLE_HTABLE
  default n
  help
 This option disables htable to allow measurement of 
duplicate records.

+
+config IMA_KEXEC_EXTRA_MEMORY_KB
+    int
+    depends on IMA && IMA_KEXEC
+    default 64


Since this isn't optional, the default should remain as a half page.
Since a page is architecture specific, the default will need to be arch
   specific


It was a feedback from Stefan in the V2 of this series to convert it
from number of PAGES to KB.[1]

But I can revert it to number of pages again.

Also, making the default value as a fraction (1/2 page) feels weird for
a CONFIG variable.

Is it ok to make the default value as one page rather than half page?


The point is not whether the extra memory is specified in terms of 
pages or KB.

For backwards compatibility the existing default should be the same as
previously.  This means the default needs to be architecture specific.b
$ uname -m; getconf PAGESIZE
x86_64
4096
$ uname -m; getconf PAGESIZE
ppc64le
65536

For example:

default 32 if PPC_64K_PAGES
default 2


Ok. Thanks for the clarification.


Do we want to support only 64K or 4K as possible PAGE_SIZE values?
I spot checked a few architectures, there are scenarios where PAGE_SIZE
could be 8K, 16K, 128K, 256K etc. And of course mega pages with
PAGE_SIZE IN MBs (details below).


I would let the user specify the number of kilobytes to reserve and from 
this you can conclude the page numbers:


needed_pages = KBs_TO_RESERVE / PAGE_SIZE
if (KBs_TO_RESERVER % PAGE_SIZE)
needed_pages++;

   Stefan



Re: [PATCH v3 5/7] ima: suspend measurements during buffer copy at kexec execute

2024-01-11 Thread Tushar Sugandhi




On 1/11/24 09:30, Mimi Zohar wrote:

On Fri, 2024-01-05 at 11:50 -0800, Tushar Sugandhi wrote:


On 12/20/23 12:44, Mimi Zohar wrote:

On Fri, 2023-12-15 at 17:07 -0800, Tushar Sugandhi wrote:

If the new measurements are added to the IMA log while it is being
being copied to the kexec buffer during kexec 'execute', it can miss
copying those new measurements to the kexec buffer, and the buffer can go
out of sync with TPM PCRs.  This could result in breaking the integrity
of the measurements after the kexec soft reboot to the new Kernel.

Add a check in the ima_add_template_entry() function not to measure
events and return from the function early when 'suspend_ima_measurements'
flag is set.

This ensures the consistency of the IMA measurement list while copying
them to the kexec buffer.  When the 'suspend_ima_measurements' flag is
set, any new measurements will be ignored until the flag is unset.  This
allows the buffer to be safely copied without worrying about concurrent
modifications to the measurement list.  This is crucial for maintaining
the integrity of the measurements during a kexec soft reboot.

Signed-off-by: Tushar Sugandhi 
---
   security/integrity/ima/ima_queue.c | 13 +
   1 file changed, 13 insertions(+)

diff --git a/security/integrity/ima/ima_queue.c 
b/security/integrity/ima/ima_queue.c
index cb9abc02a304..5946a26a2849 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -195,6 +195,19 @@ int ima_add_template_entry(struct ima_template_entry 
*entry, int violation,
}
}
   
+	/*

+* suspend_ima_measurements will be set if the system is
+* undergoing kexec soft boot to a new kernel.
+* suspending measurements in this short window ensures the
+* consistency of the IMA measurement list during copying
+* of the kexec buffer.
+*/
+   if (atomic_read(_ima_measurements)) {
+   audit_cause = "measurements_suspended";
+   audit_info = 0;
+   goto out;
+   }
+
result = ima_add_digest_entry(entry,
  !IS_ENABLED(CONFIG_IMA_DISABLE_HTABLE));
if (result < 0) {


I assume you meant to include the suspend/resume code in "ima: kexec:
move ima log copy from kexec load to execute"  in this patch.



Sure, I can move the suspend/resume code from Patch 2/7 of this series
to this patch (5/7).

Earlier I introduced the suspend/resume functionality in patch 2 because
it was used in the functions in that patch.

But shifting it hear will make the patches cleaner.


Just a reminder this isn't the only issued mentioned in 2/7.  Please refer to it
for the other comments (e.g. make not including/verifying the IMA segment hash a
separate patch).

Before reposting, please remember to test after applying each patch in the patch
set to ensure that the measurement list is properly carried across kexec.


Yes, I had read your responses on patch 2/7.
I have been meaning to respond to you on 2/7, but I kept getting 
distracted by some other work-items on my plate. Really sorry :(


I will respond to your comments on 2/7 by end of the day, and 
incorporate the feedback before reposting.






Re: [PATCH v3 6/7] ima: configure memory to log events between kexec load and execute

2024-01-11 Thread Tushar Sugandhi




On 1/7/24 09:00, Mimi Zohar wrote:

On Fri, 2024-01-05 at 12:20 -0800, Tushar Sugandhi wrote:

diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 60a511c6b583..8792b7aab768 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -338,3 +338,12 @@ config IMA_DISABLE_HTABLE
  default n
  help
 This option disables htable to allow measurement of duplicate records.
+
+config IMA_KEXEC_EXTRA_MEMORY_KB
+int
+depends on IMA && IMA_KEXEC
+default 64


Since this isn't optional, the default should remain as a half page.
Since a page is architecture specific, the default will need to be arch
   specific


It was a feedback from Stefan in the V2 of this series to convert it
from number of PAGES to KB.[1]

But I can revert it to number of pages again.

Also, making the default value as a fraction (1/2 page) feels weird for
a CONFIG variable.

Is it ok to make the default value as one page rather than half page?


The point is not whether the extra memory is specified in terms of pages or KB.
For backwards compatibility the existing default should be the same as
previously.  This means the default needs to be architecture specific.b
  
$ uname -m; getconf PAGESIZE

x86_64
4096
  
$ uname -m; getconf PAGESIZE

ppc64le
65536

For example:

default 32 if PPC_64K_PAGES
default 2


Ok. Thanks for the clarification.


Do we want to support only 64K or 4K as possible PAGE_SIZE values?
I spot checked a few architectures, there are scenarios where PAGE_SIZE
could be 8K, 16K, 128K, 256K etc. And of course mega pages with
PAGE_SIZE IN MBs (details below).

About the unit of the config value (KB v/s num_pages), if we go with
num pages, I am having hard time figuring out how to set the config
value to a float - if we truly want to support 1/2 a page (0.5) as
a default. Majority are bools or ints. I couldn't find any
config value with float which I can refer to.

Being said that, I can think of two ways to handle it:
Option (A) fine tune it to half a page given arch specific page size
config.

Option (B) Keep it simple and make the default extra memory to be
a single page rather than half-a-page.

(A) seems fragile, and I am worried we will not cover all the scenarios.

(B) Even though we are technically breaking the backward compatibility
by changing the default extra memory from half-a-page to a full page,
I don't see it adversely affecting anything else in the IMA/kexec
functionality.

I am leaning towards (B), but please let me know your thoughts.

Sample code for both the options:

Option A:
-
config IMA_KEXEC_EXTRA_MEMORY_KB
int
depends on IMA && IMA_KEXEC
default 128 if PAGE_SIZE_256KB
default 32 if PPC_64K_PAGES || PAGE_SIZE_64KB || PARISC_PAGE_SIZE_16KB
default 16 if PAGE_SIZE_32KB
default 8 if PAGE_SIZE_16KB || ARC_PAGE_SIZE_16K || 
PARISC_PAGE_SIZE_16KB

default 4 if PAGE_SIZE_8KB || ARC_PAGE_SIZE_8K
default 2
  IMA_KEXEC_EXTRA_MEMORY_KB determines the number of extra
  memory (in KB) to be allocated for IMA measurements added
  during kexec soft-reboot.

Option B:

config IMA_KEXEC_EXTRA_PAGES
int
depends on IMA && IMA_KEXEC
default 1
help
  IMA_KEXEC_EXTRA_PAGES determines the number of extra
  pages to be allocated for IMA measurements added during
  kexec soft-reboot.


Below are a few PAGE_SIZE configs I found for a some architectures.


-
https://elixir.bootlin.com/linux/v6.7-rc8/source/arch/arc/Kconfig
choice
prompt "MMU Page Size"
default ARC_PAGE_SIZE_8K

config ARC_PAGE_SIZE_8K
bool "8KB"
help
 Choose between 8k vs 16k

config ARC_PAGE_SIZE_16K
bool "16KB"

config ARC_PAGE_SIZE_4K
bool "4KB"
depends on ARC_MMU_V3 || ARC_MMU_V4

endchoice

choice
prompt "MMU Super Page Size"
depends on ISA_ARCV2 && TRANSPARENT_HUGEPAGE
default ARC_HUGEPAGE_2M

config ARC_HUGEPAGE_2M
bool "2MB"

config ARC_HUGEPAGE_16M
bool "16MB"

endchoice
-
https://elixir.bootlin.com/linux/v6.7-rc8/source/arch/hexagon/Kconfig
choice
prompt "Kernel page size"
default PAGE_SIZE_4KB
help
 Changes the default page size; use with caution.

config PAGE_SIZE_4KB
bool "4KB"

config PAGE_SIZE_16KB
bool "16KB"

config PAGE_SIZE_64KB
bool "64KB"

config PAGE_SIZE_256KB
bool "256KB"

endchoice
-
https://elixir.bootlin.com/linux/v6.7-rc8/source/arch/loongarch/Kconfig

config PAGE_SIZE_4KB
bool

config PAGE_SIZE_16KB
bool

config PAGE_SIZE_64KB
bool

-

https://elixir.bootlin.com/linux/v6.7-rc8/source/arch/mips/Kconfig
choice
prompt "Kernel page size"

Re: [PATCH v3 7/7] ima: measure kexec load and exec events as critical data

2024-01-11 Thread Tushar Sugandhi




On 1/7/24 06:24, Mimi Zohar wrote:

On Fri, 2024-01-05 at 12:22 -0800, Tushar Sugandhi wrote:

@@ -194,6 +206,15 @@ static int ima_update_kexec_buffer(struct notifier_block 
*self,
  return ret;
  }
   
+buf_size = ima_get_binary_runtime_size();

+scnprintf(ima_kexec_event, IMA_KEXEC_EVENT_LEN,
+  "kexec_segment_size=%lu;ima_binary_runtime_size=%lu;",
+  kexec_segment_size, buf_size);
+
+ima_measure_critical_data("ima_kexec", "kexec_execute",
+  ima_kexec_event, strlen(ima_kexec_event),
+  false, NULL, 0);
+


Please consider including the number of measurement records as well.

Will do. I think that would be valuable information.

Per my understanding, I will have to use the function
ima_show_measurements_count() or ima_show_htable_value() to get the
number of measurement records value[1]. So I will have to expose that
function from "ima_fs.c" to "ima_kexec.c". Hope that's ok.

[1]
https://elixir.bootlin.com/linux/latest/sourcesecurity/integrity/ima/ima_fs.c


static ssize_t ima_show_measurements_count(struct file *filp,
   char __user *buf,
   size_t count, loff_t *ppos)
{
  return ima_show_htable_value(buf, count, ppos, _htable.len);


I don't see a need to expose this function.  ima_htable is defined in ima.h.
You can read the ima_htable.len directly, as ima_show_htable_value does.


Agreed. Thanks for the pointer.
That's what I concluded too when I was implementing this change.
I will use ima_htable.len directly.

~Tushar




Re: [PATCH v3 5/7] ima: suspend measurements during buffer copy at kexec execute

2024-01-11 Thread Mimi Zohar
On Fri, 2024-01-05 at 11:50 -0800, Tushar Sugandhi wrote:
> 
> On 12/20/23 12:44, Mimi Zohar wrote:
> > On Fri, 2023-12-15 at 17:07 -0800, Tushar Sugandhi wrote:
> >> If the new measurements are added to the IMA log while it is being
> >> being copied to the kexec buffer during kexec 'execute', it can miss
> >> copying those new measurements to the kexec buffer, and the buffer can go
> >> out of sync with TPM PCRs.  This could result in breaking the integrity
> >> of the measurements after the kexec soft reboot to the new Kernel.
> >>
> >> Add a check in the ima_add_template_entry() function not to measure
> >> events and return from the function early when 'suspend_ima_measurements'
> >> flag is set.
> >>
> >> This ensures the consistency of the IMA measurement list while copying
> >> them to the kexec buffer.  When the 'suspend_ima_measurements' flag is
> >> set, any new measurements will be ignored until the flag is unset.  This
> >> allows the buffer to be safely copied without worrying about concurrent
> >> modifications to the measurement list.  This is crucial for maintaining
> >> the integrity of the measurements during a kexec soft reboot.
> >>
> >> Signed-off-by: Tushar Sugandhi 
> >> ---
> >>   security/integrity/ima/ima_queue.c | 13 +
> >>   1 file changed, 13 insertions(+)
> >>
> >> diff --git a/security/integrity/ima/ima_queue.c 
> >> b/security/integrity/ima/ima_queue.c
> >> index cb9abc02a304..5946a26a2849 100644
> >> --- a/security/integrity/ima/ima_queue.c
> >> +++ b/security/integrity/ima/ima_queue.c
> >> @@ -195,6 +195,19 @@ int ima_add_template_entry(struct ima_template_entry 
> >> *entry, int violation,
> >>}
> >>}
> >>   
> >> +  /*
> >> +   * suspend_ima_measurements will be set if the system is
> >> +   * undergoing kexec soft boot to a new kernel.
> >> +   * suspending measurements in this short window ensures the
> >> +   * consistency of the IMA measurement list during copying
> >> +   * of the kexec buffer.
> >> +   */
> >> +  if (atomic_read(_ima_measurements)) {
> >> +  audit_cause = "measurements_suspended";
> >> +  audit_info = 0;
> >> +  goto out;
> >> +  }
> >> +
> >>result = ima_add_digest_entry(entry,
> >>  !IS_ENABLED(CONFIG_IMA_DISABLE_HTABLE));
> >>if (result < 0) {
> > 
> > I assume you meant to include the suspend/resume code in "ima: kexec:
> > move ima log copy from kexec load to execute"  in this patch.
> > 
> 
> Sure, I can move the suspend/resume code from Patch 2/7 of this series
> to this patch (5/7).
> 
> Earlier I introduced the suspend/resume functionality in patch 2 because
> it was used in the functions in that patch.
> 
> But shifting it hear will make the patches cleaner.

Just a reminder this isn't the only issued mentioned in 2/7.  Please refer to it
for the other comments (e.g. make not including/verifying the IMA segment hash a
separate patch).

Before reposting, please remember to test after applying each patch in the patch
set to ensure that the measurement list is properly carried across kexec.
-- 
thanks,

Mimi




[ANNOUNCE] kexec-tools 2.0.28

2024-01-11 Thread Simon Horman
Hi all,

I am happy to announce the release of kexec-tools 2.0.28.

This is a feature release coinciding with the release of v6.7
of the Linux Kernel.

This release can be downloaded from kernel.org:

http://kernel.org/pub/linux/utils/kernel/kexec/kexec-tools-2.0.28.tar.xz
http://kernel.org/pub/linux/utils/kernel/kexec/

It is also tagged it in git:

git://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git

Thanks to everyone who has contributed to kexec!

Commits since v2.0.27:

adef8a8e4bfd kexec-tools 2.0.28
5d7bc25cf15b kexec-tools 2.0.28-rc1
549466430ae6 LoongArch: Load vmlinux.efi to the link address
ba0ac0efe299 LoongArch: Fix an issue with relocatable vmlinux
74dfaefd6316 m68k: fix getrandom() use with uclibc
22dcf5cb940a lzma: Relax memory limit for lzma decompressor
44e7b73c331f kexec: ppc64: print help to stdout instead of stderr
74d66d405f30 workflow: update to Ubuntu 22.04
ab3a70af8567 kexec/loongarch64: fix 'make dist' file loss issue
6419b008fde7 kexec: provide a memfd_create() wrapper if not present in libc
118b567ce74a crashdump/x86: set the elfcorehdr segment size for hotplug
d59d17f37239 crashdump/x86: identify elfcorehdr segment for hotplug
a56376080a93 crashdump: exclude elfcorehdr segment from digest for hotplug
75ac71fd94ff crashdump: setup general hotplug support
d6cfd2984844 crashdump: introduce the hotplug command line options
c36d3e8b2e99 kexec: define KEXEC_UPDATE_ELFCOREHDR
bd0200c47c45 kexec: update manpage with explicit mention of clean kexec
2495ccfc5206 zboot: add loongarch kexec_load support
8f08e3b51f25 zboot: enable arm64 kexec_load for zboot image
c3f35ff06e54 build: fix tarball creation
056c179cd3c2 kexec-tools 2.0.27.git

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


[PATCH v15 1/5] crash: forward memory_notify arg to arch crash hotplug handler

2024-01-11 Thread Sourabh Jain
In the event of memory hotplug or online/offline events, the crash
memory hotplug notifier `crash_memhp_notifier()` receives a
`memory_notify` object but doesn't forward that object to the
generic and architecture-specific crash hotplug handler.

The `memory_notify` object contains the starting PFN (Page Frame Number)
and the number of pages in the hot-removed memory. This information is
necessary for architectures like PowerPC to update/recreate the kdump
image, specifically `elfcorehdr`.

So update the function signature of `crash_handle_hotplug_event()` and
`arch_crash_handle_hotplug_event()` to accept the `memory_notify` object
as an argument from crash memory hotplug notifier.

Since no such object is available in the case of CPU hotplug event, the
crash CPU hotplug notifier `crash_cpuhp_online()` passes NULL to the
crash hotplug handler.

Signed-off-by: Sourabh Jain 
Cc: Akhil Raj 
Cc: Andrew Morton 
Cc: Aneesh Kumar K.V 
Cc: Baoquan He 
Cc: Borislav Petkov (AMD) 
Cc: Boris Ostrovsky 
Cc: Christophe Leroy 
Cc: Dave Hansen 
Cc: Dave Young 
Cc: David Hildenbrand 
Cc: Greg Kroah-Hartman 
Cc: Hari Bathini 
Cc: Laurent Dufour 
Cc: Mahesh Salgaonkar 
Cc: Michael Ellerman 
Cc: Mimi Zohar 
Cc: Naveen N Rao 
Cc: Oscar Salvador 
Cc: Thomas Gleixner 
Cc: Valentin Schneider 
Cc: Vivek Goyal 
Cc: kexec@lists.infradead.org
Cc: x...@kernel.org
---
 arch/x86/include/asm/kexec.h |  2 +-
 arch/x86/kernel/crash.c  |  3 ++-
 include/linux/kexec.h|  2 +-
 kernel/crash_core.c  | 14 +++---
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index c9f6a6c5de3c..9bb6607e864e 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -208,7 +208,7 @@ int arch_kimage_file_post_load_cleanup(struct kimage 
*image);
 extern void kdump_nmi_shootdown_cpus(void);
 
 #ifdef CONFIG_CRASH_HOTPLUG
-void arch_crash_handle_hotplug_event(struct kimage *image);
+void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
 #define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index b6b044356f1b..44744e9c68ec 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -428,10 +428,11 @@ unsigned int arch_crash_get_elfcorehdr_size(void)
 /**
  * arch_crash_handle_hotplug_event() - Handle hotplug elfcorehdr changes
  * @image: a pointer to kexec_crash_image
+ * @arg: struct memory_notify handler for memory hotplug case and NULL for CPU 
hotplug case.
  *
  * Prepare the new elfcorehdr and replace the existing elfcorehdr.
  */
-void arch_crash_handle_hotplug_event(struct kimage *image)
+void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
 {
void *elfbuf = NULL, *old_elfcorehdr;
unsigned long nr_mem_ranges;
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 400cb6c02176..802052d9c64b 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -483,7 +483,7 @@ static inline void arch_kexec_pre_free_pages(void *vaddr, 
unsigned int pages) {
 #endif
 
 #ifndef arch_crash_handle_hotplug_event
-static inline void arch_crash_handle_hotplug_event(struct kimage *image) { }
+static inline void arch_crash_handle_hotplug_event(struct kimage *image, void 
*arg) { }
 #endif
 
 int crash_check_update_elfcorehdr(void);
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index d48315667752..ab1c8e79759d 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -914,7 +914,7 @@ int crash_check_update_elfcorehdr(void)
  * list of segments it checks (since the elfcorehdr changes and thus
  * would require an update to purgatory itself to update the digest).
  */
-static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int 
cpu)
+static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int 
cpu, void *arg)
 {
struct kimage *image;
 
@@ -976,7 +976,7 @@ static void crash_handle_hotplug_event(unsigned int 
hp_action, unsigned int cpu)
image->hp_action = hp_action;
 
/* Now invoke arch-specific update handler */
-   arch_crash_handle_hotplug_event(image);
+   arch_crash_handle_hotplug_event(image, arg);
 
/* No longer handling a hotplug event */
image->hp_action = KEXEC_CRASH_HP_NONE;
@@ -992,17 +992,17 @@ static void crash_handle_hotplug_event(unsigned int 
hp_action, unsigned int cpu)
crash_hotplug_unlock();
 }
 
-static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, 
void *v)
+static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, 
void *arg)
 {
switch (val) {
case MEM_ONLINE:
crash_handle_hotplug_event(KEXEC_CRASH_HP_ADD_MEMORY,
-   KEXEC_CRASH_HP_INVALID_CPU);
+   KEXEC_CRASH_HP_INVALID_CPU, arg);
break;
 
case MEM_OFFLINE:
 

[PATCH v15 0/5] powerpc/crash: Kernel handling of CPU and memory hotplug

2024-01-11 Thread Sourabh Jain
Commit 247262756121 ("crash: add generic infrastructure for crash
hotplug support") added a generic infrastructure that allows
architectures to selectively update the kdump image component during CPU
or memory add/remove events within the kernel itself.

This patch series adds crash hotplug handler for PowerPC and enable
support to update the kdump image on CPU/Memory add/remove events.

Among the 5 patches in this series, the first two patches make changes
to the generic crash hotplug handler to assist PowerPC in adding support
for this feature. The last three patches add support for this feature.

The following section outlines the problem addressed by this patch
series, along with the current solution, its shortcomings, and the
proposed resolution.

Problem:

Due to CPU/Memory hotplug or online/offline events the elfcorehdr
(which describes the CPUs and memory of the crashed kernel) and FDT
(Flattened Device Tree) of kdump image becomes outdated. Consequently,
attempting dump collection with an outdated elfcorehdr or FDT can lead
to failed or inaccurate dump collection.

Going forward CPU hotplug or online/offline events are referred as
CPU/Memory add/remove events.

Existing solution and its shortcoming:
==
The current solution to address the above issue involves monitoring the
CPU/memory add/remove events in userspace using udev rules and whenever
there are changes in CPU and memory resources, the entire kdump image
is loaded again. The kdump image includes kernel, initrd, elfcorehdr,
FDT, purgatory. Given that only elfcorehdr and FDT get outdated due to
CPU/Memory add/remove events, reloading the entire kdump image is
inefficient. More importantly, kdump remains inactive for a substantial
amount of time until the kdump reload completes.

Proposed solution:
==
Instead of initiating a full kdump image reload from userspace on
CPU/Memory hotplug and online/offline events, the proposed solution aims
to update only the necessary kdump image component within the kernel
itself.

Git tree for testing:
=
Git tree rebased on top of v6.7:
https://github.com/sourabhjains/linux/tree/kdump-in-kernel-crash-update-v15

To realize this feature, the kdump udev rule must be updated. On RHEL,
add the following two lines at the top of the
"/usr/lib/udev/rules.d/98-kexec.rules" file.

SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
SUBSYSTEM=="memory", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"

With the above change to the kdump udev rule, kdump reload is avoided
during CPU/Memory add/remove events if this feature is enabled in the
kernel.

Note: only kexec_file_load syscall will work. For kexec_load minor changes
are required in kexec tool.

Changelog:
--
v15:
  - Remove the patch that adds a new kexec flag for FDT update.
  - Introduce a generic kexec flag bit to share hotplug support
intent between the kexec tool and the kernel for the kexec_load
syscall. (2/5)
  - Introduce an architecture-specific handler to process the kexec
flag for crash hotplug support. (2/5)
  - Rename the @update_elfcorehdr member of the struct kimage to
@hotplug_support. (2/5)
  - Use a common function to advertise hotplug support for both CPU
and Memory. (2/5)

v14:
  - Fix build warnings by including necessary header files
  - Rebase to v6.7-rc5

v13:
  - Fix a build warning, take ranges.c out of CONFIG_KEXEC_FILE
  - Rebase to v6.7-rc4

v12:
  - A patch to add new kexec flags to support this feature on kexec_load
system call
  - Change in the way this feature is advertise to userspace for both
kexec_load syscall
  - Rebase to v6.6-rc7

v11:
  - Rebase to v6.4-rc6
  - The patch that introduced CONFIG_CRASH_HOTPLUG for PowerPC has been
removed. The config is now part of common configuration:
https://lore.kernel.org/all/87ilbpflsk.fsf@mail.lhotse/

v10:
  - Drop the patch that adds fdt_index attribute to struct kimage_arch
Find the fdt segment index when needed.
  - Added more details into commits messages.
  - Rebased onto 6.3.0-rc5

v9:
  - Removed patch to prepare elfcorehdr crash notes for possible CPUs.
The patch is moved to generic patch series that introduces generic
infrastructure for in kernel crash update.
  - Removed patch to pass the hotplug action type to the arch crash
hotplug handler function. The generic patch series has introduced
the hotplug action type in kimage struct.
  - Add detail commit message for better understanding.

v8:
  - Restrict fdt_index initialization to machine_kexec_post_load
it work for both kexec_load and kexec_file_load.[3/8] Laurent Dufour

  - Updated the logic to find the number of offline core. [6/8]

  - Changed the logic to find the elfcore program header to accommodate
future memory ranges due memory hotplug events. [8/8]

v7
  - added a new config to configure this feature
  - pass hotplug action type to arch 

[PATCH v15 5/5] powerpc: add crash memory hotplug support

2024-01-11 Thread Sourabh Jain
Extend the arch crash hotplug handler, as introduced by the patch title
("powerpc: add crash CPU hotplug support"), to also support memory
add/remove events.

Elfcorehdr describes the memory of the crash kernel to capture the
kernel; hence, it needs to be updated if memory resources change due to
memory add/remove events. Therefore, arch_crash_handle_hotplug_event()
is updated to recreate the elfcorehdr and replace it with the previous
one on memory add/remove events.

The memblock list is used to prepare the elfcorehdr. In the case of
memory hot removal, the memblock list is updated after the arch crash
hotplug handler is triggered, as depicted in Figure 1. Thus, the
hot-removed memory is explicitly removed from the crash memory ranges
to ensure that the memory ranges added to elfcorehdr do not include the
hot-removed memory.

Memory remove
  |
  v
Offline pages
  |
  v
 Initiate memory notify call <> crash hotplug handler
 chain for MEM_OFFLINE event
  |
  v
 Update memblock list

Figure 1

There are two system calls, `kexec_file_load` and `kexec_load`, used to
load the kdump image. A few changes have been made to ensure that the
kernel can safely update the elfcorehdr component of the kdump image for
both system calls.

For the kexec_file_load syscall, kdump image is prepared in the kernel.
To support an increasing number of memory regions, the elfcorehdr is
built with extra buffer space to ensure that it can accommodate
additional memory ranges in future.

For the kexec_load syscall, the elfcorehdr is updated only if the
KEXEC_CRASH_HOTPLUG_SUPPORT kexec flag is passed to the kernel by the
kexec tool. Passing this flag to the kernel indicates that the
elfcorehdr is built to accommodate additional memory ranges and the
elfcorehdr segment is not considered for SHA calculation, making it safe
to update.

The changes related to this feature are kept under the CRASH_HOTPLUG
config, and it is enabled by default.

Signed-off-by: Sourabh Jain 
Cc: Akhil Raj 
Cc: Andrew Morton 
Cc: Aneesh Kumar K.V 
Cc: Baoquan He 
Cc: Borislav Petkov (AMD) 
Cc: Boris Ostrovsky 
Cc: Christophe Leroy 
Cc: Dave Hansen 
Cc: Dave Young 
Cc: David Hildenbrand 
Cc: Greg Kroah-Hartman 
Cc: Hari Bathini 
Cc: Laurent Dufour 
Cc: Mahesh Salgaonkar 
Cc: Michael Ellerman 
Cc: Mimi Zohar 
Cc: Naveen N Rao 
Cc: Oscar Salvador 
Cc: Thomas Gleixner 
Cc: Valentin Schneider 
Cc: Vivek Goyal 
Cc: kexec@lists.infradead.org
Cc: x...@kernel.org
---
 arch/powerpc/include/asm/kexec.h|   5 +-
 arch/powerpc/include/asm/kexec_ranges.h |   1 +
 arch/powerpc/kexec/core_64.c| 107 +++-
 arch/powerpc/kexec/file_load_64.c   |  34 +++-
 arch/powerpc/kexec/ranges.c |  85 +++
 5 files changed, 225 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 943e58eb9bff..25ff5b7f1a28 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -116,8 +116,11 @@ int get_crash_memory_ranges(struct crash_mem **mem_ranges);
 #ifdef CONFIG_CRASH_HOTPLUG
 void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
 #define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event
-#endif /*CONFIG_CRASH_HOTPLUG */
 
+unsigned int arch_crash_get_elfcorehdr_size(void);
+#define crash_get_elfcorehdr_size arch_crash_get_elfcorehdr_size
+
+#endif /*CONFIG_CRASH_HOTPLUG */
 #endif /* CONFIG_PPC64 */
 
 #ifdef CONFIG_KEXEC_FILE
diff --git a/arch/powerpc/include/asm/kexec_ranges.h 
b/arch/powerpc/include/asm/kexec_ranges.h
index f83866a19e87..802abf580cf0 100644
--- a/arch/powerpc/include/asm/kexec_ranges.h
+++ b/arch/powerpc/include/asm/kexec_ranges.h
@@ -7,6 +7,7 @@
 void sort_memory_ranges(struct crash_mem *mrngs, bool merge);
 struct crash_mem *realloc_mem_ranges(struct crash_mem **mem_ranges);
 int add_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
+int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
 int add_tce_mem_ranges(struct crash_mem **mem_ranges);
 int add_initrd_mem_range(struct crash_mem **mem_ranges);
 #ifdef CONFIG_PPC_64S_HASH_MMU
diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
index 43fcd78c2102..4673f150f973 100644
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -19,8 +19,11 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -546,6 +549,101 @@ int update_cpus_node(void *fdt)
 #undef pr_fmt
 #define pr_fmt(fmt) "crash hp: " fmt
 
+/*
+ * Advertise preferred elfcorehdr size to userspace via
+ * /sys/kernel/crash_elfcorehdr_size sysfs interface.
+ */
+unsigned int arch_crash_get_elfcorehdr_size(void)
+{
+   unsigned int sz;
+   unsigned long elf_phdr_cnt;
+
+   /* Program header for CPU notes and vmcoreinfo */
+   elf_phdr_cnt = 2;
+   if 

[PATCH v15 3/5] powerpc/kexec: turn some static helper functions public

2024-01-11 Thread Sourabh Jain
Move the functions update_cpus_node and get_crash_memory_ranges from
kexec/file_load_64.c to kexec/core_64.c to make these functions usable
by other kexec components.

get_crash_memory_ranges uses functions defined in ranges.c, so take
ranges.c out of CONFIG_KEXEC_FILE.

Later in the series, these functions are utilized for in-kernel updates
to kdump image during CPU/Memory hotplug or online/offline events for
both kexec_load and kexec_file_load syscalls.

There is no intended functional change.

Signed-off-by: Sourabh Jain 
Reviewed-by: Laurent Dufour 
Cc: Akhil Raj 
Cc: Andrew Morton 
Cc: Aneesh Kumar K.V 
Cc: Baoquan He 
Cc: Borislav Petkov (AMD) 
Cc: Boris Ostrovsky 
Cc: Christophe Leroy 
Cc: Dave Hansen 
Cc: Dave Young 
Cc: David Hildenbrand 
Cc: Greg Kroah-Hartman 
Cc: Hari Bathini 
Cc: Mahesh Salgaonkar 
Cc: Michael Ellerman 
Cc: Mimi Zohar 
Cc: Naveen N Rao 
Cc: Oscar Salvador 
Cc: Thomas Gleixner 
Cc: Valentin Schneider 
Cc: Vivek Goyal 
Cc: kexec@lists.infradead.org
Cc: x...@kernel.org
---
 arch/powerpc/include/asm/kexec.h  |   6 ++
 arch/powerpc/kexec/Makefile   |   4 +-
 arch/powerpc/kexec/core_64.c  | 166 ++
 arch/powerpc/kexec/file_load_64.c | 162 -
 4 files changed, 174 insertions(+), 164 deletions(-)

diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index e1b43aa12175..562e1bb689da 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -108,6 +108,12 @@ void crash_free_reserved_phys_range(unsigned long begin, 
unsigned long end);
 #endif /* CONFIG_PPC_RTAS */
 #endif /* CONFIG_CRASH_DUMP */
 
+#ifdef CONFIG_PPC64
+struct crash_mem;
+int update_cpus_node(void *fdt);
+int get_crash_memory_ranges(struct crash_mem **mem_ranges);
+#endif /* CONFIG_PPC64 */
+
 #ifdef CONFIG_KEXEC_FILE
 extern const struct kexec_file_ops kexec_elf64_ops;
 
diff --git a/arch/powerpc/kexec/Makefile b/arch/powerpc/kexec/Makefile
index 0c2abe7f9908..f2ed5b85b912 100644
--- a/arch/powerpc/kexec/Makefile
+++ b/arch/powerpc/kexec/Makefile
@@ -3,11 +3,11 @@
 # Makefile for the linux kernel.
 #
 
-obj-y  += core.o crash.o core_$(BITS).o
+obj-y  += core.o crash.o ranges.o core_$(BITS).o
 
 obj-$(CONFIG_PPC32)+= relocate_32.o
 
-obj-$(CONFIG_KEXEC_FILE)   += file_load.o ranges.o file_load_$(BITS).o 
elf_$(BITS).o
+obj-$(CONFIG_KEXEC_FILE)   += file_load.o file_load_$(BITS).o elf_$(BITS).o
 
 # Disable GCOV, KCOV & sanitizers in odd or sensitive code
 GCOV_PROFILE_core_$(BITS).o := n
diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
index 762e4d09aacf..48beaadcfb70 100644
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -17,6 +17,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -30,6 +32,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 int machine_kexec_prepare(struct kimage *image)
 {
@@ -376,6 +380,168 @@ void default_machine_kexec(struct kimage *image)
/* NOTREACHED */
 }
 
+/**
+ * get_crash_memory_ranges - Get crash memory ranges. This list includes
+ *   first/crashing kernel's memory regions that
+ *   would be exported via an elfcore.
+ * @mem_ranges:  Range list to add the memory ranges to.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+int get_crash_memory_ranges(struct crash_mem **mem_ranges)
+{
+   phys_addr_t base, end;
+   struct crash_mem *tmem;
+   u64 i;
+   int ret;
+
+   for_each_mem_range(i, , ) {
+   u64 size = end - base;
+
+   /* Skip backup memory region, which needs a separate entry */
+   if (base == BACKUP_SRC_START) {
+   if (size > BACKUP_SRC_SIZE) {
+   base = BACKUP_SRC_END + 1;
+   size -= BACKUP_SRC_SIZE;
+   } else
+   continue;
+   }
+
+   ret = add_mem_range(mem_ranges, base, size);
+   if (ret)
+   goto out;
+
+   /* Try merging adjacent ranges before reallocation attempt */
+   if ((*mem_ranges)->nr_ranges == (*mem_ranges)->max_nr_ranges)
+   sort_memory_ranges(*mem_ranges, true);
+   }
+
+   /* Reallocate memory ranges if there is no space to split ranges */
+   tmem = *mem_ranges;
+   if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) {
+   tmem = realloc_mem_ranges(mem_ranges);
+   if (!tmem)
+   goto out;
+   }
+
+   /* Exclude crashkernel region */
+   ret = crash_exclude_mem_range(tmem, crashk_res.start, crashk_res.end);
+   if (ret)
+   goto out;
+
+   /*
+* FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL
+*   

[PATCH v15 4/5] powerpc: add crash CPU hotplug support

2024-01-11 Thread Sourabh Jain
Due to CPU/Memory hotplug or online/offline events, the elfcorehdr
(which describes the CPUs and memory of the crashed kernel) and FDT
(Flattened Device Tree) of kdump image becomes outdated. Consequently,
attempting dump collection with an outdated elfcorehdr or FDT can lead
to failed or inaccurate dump collection.

Going forward, CPU hotplug or online/offline events are referred as
CPU/Memory add/remove events.

The current solution to address the above issue involves monitoring the
CPU/Memory add/remove events in userspace using udev rules and whenever
there are changes in CPU and memory resources, the entire kdump image
is loaded again. The kdump image includes kernel, initrd, elfcorehdr,
FDT, purgatory. Given that only elfcorehdr and FDT get outdated due to
CPU/Memory add/remove events, reloading the entire kdump image is
inefficient. More importantly, kdump remains inactive for a substantial
amount of time until the kdump reload completes.

To address the aforementioned issue, commit 247262756121 ("crash: add
generic infrastructure for crash hotplug support") added a generic
infrastructure that allows architectures to selectively update the kdump
image component during CPU or memory add/remove events within the kernel
itself.

In the event of a CPU or memory add/remove events, the generic crash
hotplug event handler, `crash_handle_hotplug_event()`, is triggered. It
then acquires the necessary locks to update the kdump image and invokes
the architecture-specific crash hotplug handler,
`arch_crash_handle_hotplug_event()`, to update the required kdump image
components.

This patch adds crash hotplug handler for PowerPC and enable support to
update the kdump image on CPU add/remove events. Support for memory
add/remove events is added in a subsequent patch with the title
"powerpc: add crash memory hotplug support"

As mentioned earlier, only the elfcorehdr and FDT kdump image components
need to be updated in the event of CPU or memory add/remove events.
However, on PowerPC architecture crash hotplug handler only updates the
FDT to enable crash hotplug support for CPU add/remove events. Here's
why.

The elfcorehdr on PowerPC is built with possible CPUs, and thus, it does
not need an update on CPU add/remove events. On the other hand, the FDT
needs to be updated on CPU add events to include the newly added CPU. If
the FDT is not updated and the kernel crashes on a newly added CPU, the
kdump kernel will fail to boot due to the unavailability of the crashing
CPU in the FDT. During the early boot, it is expected that the boot CPU
must be a part of the FDT; otherwise, the kernel will raise a BUG and
fail to boot. For more information, refer to commit 36ae37e3436b0
("powerpc: Make boot_cpuid common between 32 and 64-bit"). Since it is
okay to have an offline CPU in the kdump FDT, no action is taken in case
of CPU removal.

There are two system calls, `kexec_file_load` and `kexec_load`, used to
load the kdump image. Few changes have been made to ensure kernel can
safely update the FDT of kdump image loaded using both system calls.

For kexec_file_load syscall the kdump image is prepared in kernel. So to
support an increasing number of CPUs, the FDT is constructed with extra
buffer space to ensure it can accommodate a possible number of CPU
nodes. Additionally, a call to fdt_pack (which trims the unused space
once the FDT is prepared) is avoided if this feature is enabled.

For the kexec_load syscall, the FDT is updated only if the
KEXEC_CRASH_HOTPLUG_SUPPORT kexec flag is passed to the kernel by
userspace (kexec tools). When userspace passes this flag to the kernel,
it indicates that the FDT is built to accommodate possible CPUs, and the
FDT segment is excluded from SHA calculation, making it safe to update.

The changes related to this feature are kept under the CRASH_HOTPLUG
config, and it is enabled by default.

Signed-off-by: Sourabh Jain 
Cc: Akhil Raj 
Cc: Andrew Morton 
Cc: Aneesh Kumar K.V 
Cc: Baoquan He 
Cc: Borislav Petkov (AMD) 
Cc: Boris Ostrovsky 
Cc: Christophe Leroy 
Cc: Dave Hansen 
Cc: Dave Young 
Cc: David Hildenbrand 
Cc: Greg Kroah-Hartman 
Cc: Hari Bathini 
Cc: Laurent Dufour 
Cc: Mahesh Salgaonkar 
Cc: Michael Ellerman 
Cc: Mimi Zohar 
Cc: Naveen N Rao 
Cc: Oscar Salvador 
Cc: Thomas Gleixner 
Cc: Valentin Schneider 
Cc: Vivek Goyal 
Cc: kexec@lists.infradead.org
Cc: x...@kernel.org
---
 arch/powerpc/Kconfig  |  4 ++
 arch/powerpc/include/asm/kexec.h  |  6 +++
 arch/powerpc/kexec/core_64.c  | 69 +++
 arch/powerpc/kexec/elf_64.c   | 12 +-
 arch/powerpc/kexec/file_load_64.c | 15 +++
 5 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 414b978b8010..91d7bb0b81ee 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -682,6 +682,10 @@ config RELOCATABLE_TEST
 config ARCH_SUPPORTS_CRASH_DUMP
def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
 
+config 

[PATCH v15 2/5] crash: add a new kexec flag for hotplug support

2024-01-11 Thread Sourabh Jain
Commit a72bbec70da2 ("crash: hotplug support for kexec_load()")
introduced a new kexec flag, `KEXEC_UPDATE_ELFCOREHDR`. Kexec tool uses
this flag to indicate to the kernel that it is safe to modify the
elfcorehdr of the kdump image loaded using the kexec_load system call.

However, it is possible that architectures may need to update kexec
segments other then elfcorehdr. For example, FDT (Flatten Device Tree)
on PowerPC. Introducing a new kexec flag for every new kexec segment
may not be a good solution. Hence, a generic kexec flag bit,
`KEXEC_CRASH_HOTPLUG_SUPPORT`, is introduced to share the CPU/Memory
hotplug support intent between the kexec tool and the kernel for the
kexec_load system call.

Now, if the kexec tool sends KEXEC_CRASH_HOTPLUG_SUPPORT kexec flag to
the kernel, it indicates to the kernel that all the required kexec
segment is skipped from SHA calculation and it is safe to update kdump
image loaded using the kexec_load syscall.

While loading the kdump image using the kexec_load syscall, the
@update_elfcorehdr member of struct kimage is set if the kexec tool
sends the KEXEC_UPDATE_ELFCOREHDR kexec flag. This member is later used
to determine whether it is safe to update elfcorehdr on hotplug events.
However, with the introduction of the KEXEC_CRASH_HOTPLUG_SUPPORT kexec
flag, the kexec tool could mark all the required kexec segments on an
architecture as safe to update. So rename the @update_elfcorehdr to
@hotplug_support. If @hotplug_support is set, the kernel can safely
update all the required kexec segments of the kdump image during
CPU/Memory hotplug events.

Introduce an architecture-specific function to process kexec flags for
determining hotplug support. Set the @hotplug_support member of struct
kimage for both kexec_load and kexec_file_load system calls. This
simplifies kernel checks to identify hotplug support for the currently
loaded kdump image by just examining the value of @hotplug_support.

Signed-off-by: Sourabh Jain 
Cc: Akhil Raj 
Cc: Andrew Morton 
Cc: Aneesh Kumar K.V 
Cc: Baoquan He 
Cc: Borislav Petkov (AMD) 
Cc: Boris Ostrovsky 
Cc: Christophe Leroy 
Cc: Dave Hansen 
Cc: Dave Young 
Cc: David Hildenbrand 
Cc: Eric DeVolder 
Cc: Greg Kroah-Hartman 
Cc: Hari Bathini 
Cc: Laurent Dufour 
Cc: Mahesh Salgaonkar 
Cc: Michael Ellerman 
Cc: Mimi Zohar 
Cc: Naveen N Rao 
Cc: Oscar Salvador 
Cc: Thomas Gleixner 
Cc: Valentin Schneider 
Cc: Vivek Goyal 
Cc: kexec@lists.infradead.org
Cc: x...@kernel.org
---
 arch/x86/include/asm/kexec.h |  3 +++
 arch/x86/kernel/crash.c  | 18 +++---
 drivers/base/cpu.c   |  2 +-
 drivers/base/memory.c|  2 +-
 include/linux/kexec.h| 25 +++--
 include/uapi/linux/kexec.h   |  1 +
 kernel/crash_core.c  | 11 ---
 kernel/kexec.c   |  4 ++--
 kernel/kexec_file.c  |  5 +
 9 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 9bb6607e864e..e791129fdf6c 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -211,6 +211,9 @@ extern void kdump_nmi_shootdown_cpus(void);
 void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
 #define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event
 
+int arch_crash_hotplug_support(struct kimage *image, unsigned long 
kexec_flags);
+#define arch_crash_hotplug_support arch_crash_hotplug_support
+
 #ifdef CONFIG_HOTPLUG_CPU
 int arch_crash_hotplug_cpu_support(void);
 #define crash_hotplug_cpu_support arch_crash_hotplug_cpu_support
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 44744e9c68ec..293b54bff706 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -398,20 +398,16 @@ int crash_load_segments(struct kimage *image)
 #undef pr_fmt
 #define pr_fmt(fmt) "crash hp: " fmt
 
-/* These functions provide the value for the sysfs crash_hotplug nodes */
-#ifdef CONFIG_HOTPLUG_CPU
-int arch_crash_hotplug_cpu_support(void)
+int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags)
 {
-   return crash_check_update_elfcorehdr();
-}
-#endif
 
-#ifdef CONFIG_MEMORY_HOTPLUG
-int arch_crash_hotplug_memory_support(void)
-{
-   return crash_check_update_elfcorehdr();
-}
+#ifdef CONFIG_KEXEC_FILE
+   if (image->file_mode)
+   return 1;
 #endif
+   return (kexec_flags & KEXEC_UPDATE_ELFCOREHDR ||
+   kexec_flags & KEXEC_CRASH_HOTPLUG_SUPPORT);
+}
 
 unsigned int arch_crash_get_elfcorehdr_size(void)
 {
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 548491de818e..2f411ddfbd8b 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -306,7 +306,7 @@ static ssize_t crash_hotplug_show(struct device *dev,
 struct device_attribute *attr,
 char *buf)
 {
-   return sysfs_emit(buf, "%d\n", crash_hotplug_cpu_support());
+   return