Re: [PATCH v3 2/7] ima: kexec: move ima log copy from kexec load to execute
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
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
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
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
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
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
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
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
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
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
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
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
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
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