Re: [PATCHv3 0/4] arm64: make phys_to_virt() correct
Gently ping, any comments or suggestions? Thanks On Tue, Dec 28, 2021 at 9:27 PM Pingfan Liu wrote: > > Currently phys_to_virt() does not work well on 52-bits VA arm64 kernel. > One issue is contributed by phys_offset not signed. > The other is contributed by wrong page_offset. > > v2 -> v3: > Discussed with Kairui off-list, 48-bits VA kernel can not handle flipped > mm yet. So introducing [4/4], which judges whether the kernel is with > flipped mm layout and adopt different formula accordingly. > > As for [1-3/4], they are the same as [1-3/3] in V2. > > v1 -> v2 > Fix broken patch [2/3] in v1 > Move arch_scan_vmcoreinfo declaration to util_lib/include/elf_info.h > Using UINT64_MAX instread of 0x > > > Cc: Kairui Song > Cc: Simon Horman > Cc: Philipp Rudo > To: kexec@lists.infradead.org > *** BLURB HERE *** > > Kairui Song (1): > arm64: fix PAGE_OFFSET calc for flipped mm > > Pingfan Liu (3): > arm64: make phys_offset signed > arm64/crashdump: unify routine to get page_offset > arm64: read VA_BITS from kcore for 52-bits VA kernel > > kexec/arch/arm64/crashdump-arm64.c | 23 +--- > kexec/arch/arm64/kexec-arm64.c | 60 -- > kexec/arch/arm64/kexec-arm64.h | 3 +- > util_lib/elf_info.c| 7 +++- > util_lib/include/elf_info.h| 3 +- > 5 files changed, 60 insertions(+), 36 deletions(-) > > -- > 2.31.1 > ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH 1/3] memblock: define functions to set the usable memory range
On Tue, Jan 11, 2022 at 12:31:58PM +0200, Mike Rapoport wrote: > > --- a/include/linux/memblock.h > > +++ b/include/linux/memblock.h > > @@ -481,6 +481,8 @@ phys_addr_t memblock_reserved_size(void); > > phys_addr_t memblock_start_of_DRAM(void); > > phys_addr_t memblock_end_of_DRAM(void); > > void memblock_enforce_memory_limit(phys_addr_t memory_limit); > > +void memblock_set_usable_range(phys_addr_t base, phys_addr_t size); > > +void memblock_enforce_usable_range(void); > > void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size); > > void memblock_mem_limit_remove_map(phys_addr_t limit); > > We already have 3 very similar interfaces that deal with memory capping. > Now you suggest to add fourth that will "generically" solve a single use > case of DT, EFI and kdump interaction on arm64. > > Looks like a workaround for a fundamental issue of incompatibility between > DT and EFI wrt memory registration. Yep, I figured this would be the main argument against this - arm64 already added several other more-or-less special cased interfaces over time. I'm more than happy to solve this in a different way. What would you suggest: 1) Try to merge the similar interfaces in to one. 2) Just deal with it at a lower (arm64) level? 3) Some other way? Thanks, - Frank ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v2 2/5] riscv: mm: init: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
On Mon, 06 Dec 2021 08:05:11 PST (-0800), jszh...@kernel.org wrote: Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE" by a check for "IS_ENABLED(CONFIG_KEXEC_CORE)", to simplify the code and increase compile coverage. Signed-off-by: Jisheng Zhang --- arch/riscv/mm/init.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index a15640eeb334..84879a5ce818 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -748,7 +748,6 @@ static inline void setup_vm_final(void) } #endif /* CONFIG_MMU */ -#ifdef CONFIG_KEXEC_CORE /* * reserve_crashkernel() - reserves memory for crash kernel * @@ -765,6 +764,8 @@ static void __init reserve_crashkernel(void) int ret = 0; + if (!IS_ENABLED(CONFIG_KEXEC_CORE)) + return; /* * Don't reserve a region for a crash kernel on a crash kernel * since it doesn't make much sense and we have limited memory @@ -805,7 +806,6 @@ static void __init reserve_crashkernel(void) crashk_res.start = crash_base; crashk_res.end = crash_base + crash_size - 1; } -#endif /* CONFIG_KEXEC_CORE */ void __init paging_init(void) { @@ -819,9 +819,7 @@ void __init misc_mem_init(void) arch_numa_init(); sparse_init(); zone_sizes_init(); -#ifdef CONFIG_KEXEC_CORE reserve_crashkernel(); -#endif memblock_dump_all(); } Acked-by: Palmer Dabbelt LMK if you wanted me to take this through the RISC-V tree, otherwise I'm going to assume all these are going in together. Thanks! ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v19 06/13] kexec: move crashk[_low]_res to crash_core module
On 12/28/21 7:26 AM, Zhen Lei wrote: From: Chen Zhou Move the definition and declaration of global variable crashk[_low]_res from kexec module to crash_core module, in preparation of adding generic reserve_crashkernel_mem[_low]() to crash_core.c, the latter refers to variable crashk[_low]_res. Due to the config KEXEC automatically selects CRASH_CORE, and the header crash_core.h is included by kexec.h, so there is no functional change. Signed-off-by: Chen Zhou Signed-off-by: Zhen Lei > Acked-by: John Donnelly --- include/linux/crash_core.h | 4 include/linux/kexec.h | 4 kernel/crash_core.c| 16 kernel/kexec_core.c| 17 - 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h index 598fd55d83c169e..f5437c9c9411fce 100644 --- a/include/linux/crash_core.h +++ b/include/linux/crash_core.h @@ -73,6 +73,10 @@ extern unsigned char *vmcoreinfo_data; extern size_t vmcoreinfo_size; extern u32 *vmcoreinfo_note; +/* Location of a reserved region to hold the crash kernel. */ +extern struct resource crashk_res; +extern struct resource crashk_low_res; + Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type, void *data, size_t data_len); void final_note(Elf_Word *buf); diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 0c994ae37729e1e..47e784d66ea8645 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -350,10 +350,6 @@ extern int kexec_load_disabled; #define KEXEC_FILE_FLAGS (KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \ KEXEC_FILE_NO_INITRAMFS) -/* Location of a reserved region to hold the crash kernel. - */ -extern struct resource crashk_res; -extern struct resource crashk_low_res; extern note_buf_t __percpu *crash_notes; /* flag to track if kexec reboot is in progress */ diff --git a/kernel/crash_core.c b/kernel/crash_core.c index b7d024eb464d0ae..686d8a65e12a337 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -22,6 +22,22 @@ u32 *vmcoreinfo_note; /* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */ static unsigned char *vmcoreinfo_data_safecopy; +/* Location of the reserved area for the crash kernel */ +struct resource crashk_res = { + .name = "Crash kernel", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, + .desc = IORES_DESC_CRASH_KERNEL +}; +struct resource crashk_low_res = { + .name = "Crash kernel", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, + .desc = IORES_DESC_CRASH_KERNEL +}; + /* * parsing the "crashkernel" commandline * diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 5a5d192a89ac307..1e0d4909bbb6b77 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -54,23 +54,6 @@ note_buf_t __percpu *crash_notes; /* Flag to indicate we are going to kexec a new kernel */ bool kexec_in_progress = false; - -/* Location of the reserved area for the crash kernel */ -struct resource crashk_res = { - .name = "Crash kernel", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, - .desc = IORES_DESC_CRASH_KERNEL -}; -struct resource crashk_low_res = { - .name = "Crash kernel", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, - .desc = IORES_DESC_CRASH_KERNEL -}; - int kexec_should_crash(struct task_struct *p) { /* ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v19 05/13] x86/setup: Add and use CRASH_BASE_ALIGN
On 12/28/21 7:26 AM, Zhen Lei wrote: Add macro CRASH_BASE_ALIGN to indicate the alignment for crash kernel fixed region, in preparation for making partial implementation of reserve_crashkernel[_low]() generic. Signed-off-by: Zhen Lei > Acked-by: John Donnelly --- arch/x86/kernel/setup.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 93d78aae1937db3..cb7f237a2ae0dfa 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -392,9 +392,12 @@ static void __init memblock_x86_reserve_range_setup_data(void) #ifdef CONFIG_KEXEC_CORE -/* 16M alignment for crash kernel regions */ +/* alignment for crash kernel dynamic regions */ #define CRASH_ALIGN SZ_16M +/* alignment for crash kernel fixed region */ +#define CRASH_BASE_ALIGN SZ_1M + /* * Keep the crash kernel below this limit. * @@ -509,7 +512,7 @@ static void __init reserve_crashkernel(void) } else { unsigned long long start; - start = memblock_phys_alloc_range(crash_size, SZ_1M, crash_base, + start = memblock_phys_alloc_range(crash_size, CRASH_BASE_ALIGN, crash_base, crash_base + crash_size); if (start != crash_base) { pr_info("crashkernel reservation failed - memory is in use.\n"); ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v19 04/13] kdump: reduce unnecessary parameters of parse_crashkernel_{high|low}()
On 12/28/21 7:26 AM, Zhen Lei wrote: Delete confusing parameters 'system_ram' and 'crash_base' of parse_crashkernel_{high|low}(), they are only needed by the case of "crashkernel=X@[offset]". Signed-off-by: Zhen Lei > Acked-by: John Donnelly --- kernel/crash_core.c | 21 ++--- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/kernel/crash_core.c b/kernel/crash_core.c index 3b9e01fc450b2a4..b7d024eb464d0ae 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -278,20 +278,20 @@ int __init parse_crashkernel(char *cmdline, } static int __init parse_crashkernel_high(char *cmdline, -unsigned long long system_ram, -unsigned long long *crash_size, -unsigned long long *crash_base) +unsigned long long *crash_size) { - return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base, + unsigned long long base; + + return __parse_crashkernel(cmdline, 0, crash_size, , "crashkernel=", suffix_tbl[SUFFIX_HIGH]); } static int __init parse_crashkernel_low(char *cmdline, -unsigned long long system_ram, -unsigned long long *crash_size, -unsigned long long *crash_base) + unsigned long long *crash_size) { - return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base, + unsigned long long base; + + return __parse_crashkernel(cmdline, 0, crash_size, , "crashkernel=", suffix_tbl[SUFFIX_LOW]); } @@ -310,12 +310,11 @@ int __init parse_crashkernel_high_low(char *cmdline, unsigned long long *low_size) { int ret; - unsigned long long base; BUG_ON(!high_size || !low_size); /* crashkernel=X,high */ - ret = parse_crashkernel_high(cmdline, 0, high_size, ); + ret = parse_crashkernel_high(cmdline, high_size); if (ret) return ret; @@ -323,7 +322,7 @@ int __init parse_crashkernel_high_low(char *cmdline, return -EINVAL; /* crashkernel=Y,low */ - ret = parse_crashkernel_low(cmdline, 0, low_size, ); + ret = parse_crashkernel_low(cmdline, low_size); if (ret) *low_size = -1; ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v19 03/13] kdump: make parse_crashkernel_{high|low}() static
On 12/28/21 7:26 AM, Zhen Lei wrote: Make parse_crashkernel_{high|low}() static, they are only referenced by parse_crashkernel_high_low() in the same file. The latter is recommended. Signed-off-by: Zhen Lei > Acked-by: John Donnelly --- include/linux/crash_core.h | 4 kernel/crash_core.c| 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h index 2d3a64761d18998..598fd55d83c169e 100644 --- a/include/linux/crash_core.h +++ b/include/linux/crash_core.h @@ -79,10 +79,6 @@ void final_note(Elf_Word *buf); int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base); -int parse_crashkernel_high(char *cmdline, unsigned long long system_ram, - unsigned long long *crash_size, unsigned long long *crash_base); -int parse_crashkernel_low(char *cmdline, unsigned long long system_ram, - unsigned long long *crash_size, unsigned long long *crash_base); int __init parse_crashkernel_high_low(char *cmdline, unsigned long long *high_size, unsigned long long *low_size); diff --git a/kernel/crash_core.c b/kernel/crash_core.c index 8966beaf7c4fd52..3b9e01fc450b2a4 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -277,7 +277,7 @@ int __init parse_crashkernel(char *cmdline, "crashkernel=", NULL); } -int __init parse_crashkernel_high(char *cmdline, +static int __init parse_crashkernel_high(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base) @@ -286,7 +286,7 @@ int __init parse_crashkernel_high(char *cmdline, "crashkernel=", suffix_tbl[SUFFIX_HIGH]); } -int __init parse_crashkernel_low(char *cmdline, +static int __init parse_crashkernel_low(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base) ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v19 02/13] x86/setup: Use parse_crashkernel_high_low() to simplify code
On 12/28/21 7:26 AM, Zhen Lei wrote: Use parse_crashkernel_high_low() to bring the parsing of "crashkernel=X,high" and the parsing of "crashkernel=Y,low" together, they are strongly dependent, make code logic clear and more readable. Suggested-by: Borislav Petkov Signed-off-by: Zhen Lei > Acked-by: John Donnelly --- arch/x86/kernel/setup.c | 21 + 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 6a190c7f4d71b05..93d78aae1937db3 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -416,18 +416,16 @@ static void __init memblock_x86_reserve_range_setup_data(void) # define CRASH_ADDR_HIGH_MAX SZ_64T #endif -static int __init reserve_crashkernel_low(void) +static int __init reserve_crashkernel_low(unsigned long long low_size) { #ifdef CONFIG_X86_64 - unsigned long long base, low_base = 0, low_size = 0; + unsigned long long low_base = 0; unsigned long low_mem_limit; - int ret; low_mem_limit = min(memblock_phys_mem_size(), CRASH_ADDR_LOW_MAX); - /* crashkernel=Y,low */ - ret = parse_crashkernel_low(boot_command_line, low_mem_limit, _size, ); - if (ret) { + /* crashkernel=Y,low is not specified */ + if ((long)low_size < 0) { /* * two parts from kernel/dma/swiotlb.c: * -swiotlb size: user-specified with swiotlb= or default. @@ -465,7 +463,7 @@ static int __init reserve_crashkernel_low(void) static void __init reserve_crashkernel(void) { - unsigned long long crash_size, crash_base, total_mem; + unsigned long long crash_size, crash_base, total_mem, low_size; bool high = false; int ret; @@ -474,10 +472,9 @@ static void __init reserve_crashkernel(void) /* crashkernel=XM */ ret = parse_crashkernel(boot_command_line, total_mem, _size, _base); if (ret != 0 || crash_size <= 0) { - /* crashkernel=X,high */ - ret = parse_crashkernel_high(boot_command_line, total_mem, -_size, _base); - if (ret != 0 || crash_size <= 0) + /* crashkernel=X,high and possible crashkernel=Y,low */ + ret = parse_crashkernel_high_low(boot_command_line, _size, _size); + if (ret) return; high = true; } @@ -520,7 +517,7 @@ static void __init reserve_crashkernel(void) } } - if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) { + if (crash_base >= (1ULL << 32) && reserve_crashkernel_low(low_size)) { memblock_phys_free(crash_base, crash_size); return; } ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v19 01/13] kdump: add helper parse_crashkernel_high_low()
On 12/28/21 7:26 AM, Zhen Lei wrote: The bootup command line option crashkernel=Y,low is valid only when crashkernel=X,high is specified. Putting their parsing into a separate function makes the code logic clearer and easier to understand the strong dependencies between them. Signed-off-by: Zhen Lei > Acked-by: John Donnelly --- include/linux/crash_core.h | 3 +++ kernel/crash_core.c| 35 +++ 2 files changed, 38 insertions(+) diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h index de62a722431e7db..2d3a64761d18998 100644 --- a/include/linux/crash_core.h +++ b/include/linux/crash_core.h @@ -83,5 +83,8 @@ int parse_crashkernel_high(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base); int parse_crashkernel_low(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base); +int __init parse_crashkernel_high_low(char *cmdline, + unsigned long long *high_size, + unsigned long long *low_size); #endif /* LINUX_CRASH_CORE_H */ diff --git a/kernel/crash_core.c b/kernel/crash_core.c index eb53f5ec62c900f..8966beaf7c4fd52 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -295,6 +295,41 @@ int __init parse_crashkernel_low(char *cmdline, "crashkernel=", suffix_tbl[SUFFIX_LOW]); } +/** + * parse_crashkernel_high_low - Parsing "crashkernel=X,high" and possible + * "crashkernel=Y,low". + * @cmdline: The bootup command line. + * @high_size: Save the memory size specified by "crashkernel=X,high". + * @low_size: Save the memory size specified by "crashkernel=Y,low" or "-1" + * if it's not specified. + * + * Returns 0 on success, else a negative status code. + */ +int __init parse_crashkernel_high_low(char *cmdline, + unsigned long long *high_size, + unsigned long long *low_size) +{ + int ret; + unsigned long long base; + + BUG_ON(!high_size || !low_size); + + /* crashkernel=X,high */ + ret = parse_crashkernel_high(cmdline, 0, high_size, ); + if (ret) + return ret; + + if (*high_size <= 0) + return -EINVAL; + + /* crashkernel=Y,low */ + ret = parse_crashkernel_low(cmdline, 0, low_size, ); + if (ret) + *low_size = -1; + + return 0; +} + Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type, void *data, size_t data_len) { ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH v5 1/6] s390/kexec_file: Don't opencode appended signature check.
Module verification already implements appeded signature check. Reuse it for kexec_file. The kexec_file implementation uses EKEYREJECTED error in some cases when there is no key and the common implementation uses ENOPKG or EBADMSG instead. Signed-off-by: Michal Suchanek Acked-by: Heiko Carstens --- v3: Philipp Rudo : Update the commit with note about change of return value --- arch/s390/kernel/machine_kexec_file.c | 22 +- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c index 8f43575a4dd3..c944d71316c7 100644 --- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -31,6 +31,7 @@ int s390_verify_sig(const char *kernel, unsigned long kernel_len) const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; struct module_signature *ms; unsigned long sig_len; + int ret; /* Skip signature verification when not secure IPLed. */ if (!ipl_secure_flag) @@ -45,25 +46,12 @@ int s390_verify_sig(const char *kernel, unsigned long kernel_len) kernel_len -= marker_len; ms = (void *)kernel + kernel_len - sizeof(*ms); - kernel_len -= sizeof(*ms); + ret = mod_check_sig(ms, kernel_len, "kexec"); + if (ret) + return ret; sig_len = be32_to_cpu(ms->sig_len); - if (sig_len >= kernel_len) - return -EKEYREJECTED; - kernel_len -= sig_len; - - if (ms->id_type != PKEY_ID_PKCS7) - return -EKEYREJECTED; - - if (ms->algo != 0 || - ms->hash != 0 || - ms->signer_len != 0 || - ms->key_id_len != 0 || - ms->__pad[0] != 0 || - ms->__pad[1] != 0 || - ms->__pad[2] != 0) { - return -EBADMSG; - } + kernel_len -= sizeof(*ms) + sig_len; return verify_pkcs7_signature(kernel, kernel_len, kernel + kernel_len, sig_len, -- 2.31.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH v5 6/6] module: Move duplicate mod_check_sig users code to mod_parse_sig
Multiple users of mod_check_sig check for the marker, then call mod_check_sig, extract signature length, and remove the signature. Put this code in one place together with mod_check_sig. This changes the error from ENOENT to ENODATA for ima_read_modsig in the case the signature marker is missing. This also changes the buffer length in ima_read_modsig from size_t to unsigned long. This reduces the possible value range on 32bit but the length refers to kernel in-memory buffer which cannot be longer than ULONG_MAX. Also change mod_check_sig to unsigned long while at it. Signed-off-by: Michal Suchanek --- v3: - Philipp Rudo : Update the commit with note about change of raturn value - Preserve the EBADMSG error code while moving code araound v4: - remove unused variable ms in module_signing.c - note about buffer length v5: - also change the functions in module_signature.c to unsigned long --- include/linux/module_signature.h| 4 +- kernel/module_signature.c | 58 - kernel/module_signing.c | 27 ++ security/integrity/ima/ima_modsig.c | 22 ++- 4 files changed, 66 insertions(+), 45 deletions(-) diff --git a/include/linux/module_signature.h b/include/linux/module_signature.h index 7eb4b00381ac..e5fb157c085c 100644 --- a/include/linux/module_signature.h +++ b/include/linux/module_signature.h @@ -40,7 +40,9 @@ struct module_signature { __be32 sig_len;/* Length of signature data */ }; -int mod_check_sig(const struct module_signature *ms, size_t file_len, +int mod_check_sig(const struct module_signature *ms, unsigned long file_len, + const char *name); +int mod_parse_sig(const void *data, unsigned long *len, unsigned long *sig_len, const char *name); #endif /* _LINUX_MODULE_SIGNATURE_H */ diff --git a/kernel/module_signature.c b/kernel/module_signature.c index 00132d12487c..4a36405ecd08 100644 --- a/kernel/module_signature.c +++ b/kernel/module_signature.c @@ -8,17 +8,39 @@ #include #include +#include #include #include +/** + * mod_check_sig_marker - check that the given data has signature marker at the end + * + * @data: Data with appended signature + * @len: Length of data. Signature marker length is subtracted on success. + */ +static inline int mod_check_sig_marker(const void *data, unsigned long *len) +{ + const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; + + if (markerlen > *len) + return -ENODATA; + + if (memcmp(data + *len - markerlen, MODULE_SIG_STRING, + markerlen)) + return -ENODATA; + + *len -= markerlen; + return 0; +} + /** * mod_check_sig - check that the given signature is sane * * @ms:Signature to check. - * @file_len: Size of the file to which @ms is appended. + * @file_len: Size of the file to which @ms is appended (without the marker). * @name: What is being checked. Used for error messages. */ -int mod_check_sig(const struct module_signature *ms, size_t file_len, +int mod_check_sig(const struct module_signature *ms, unsigned long file_len, const char *name) { if (be32_to_cpu(ms->sig_len) >= file_len - sizeof(*ms)) @@ -44,3 +66,35 @@ int mod_check_sig(const struct module_signature *ms, size_t file_len, return 0; } + +/** + * mod_parse_sig - check that the given signature is sane and determine signature length + * + * @data: Data with appended signature. + * @len: Length of data. Signature and marker length is subtracted on success. + * @sig_len: Length of signature. Filled on success. + * @name: What is being checked. Used for error messages. + */ +int mod_parse_sig(const void *data, unsigned long *len, unsigned long *sig_len, const char *name) +{ + const struct module_signature *sig; + int rc; + + rc = mod_check_sig_marker(data, len); + if (rc) + return rc; + + if (*len < sizeof(*sig)) + return -EBADMSG; + + sig = data + (*len - sizeof(*sig)); + + rc = mod_check_sig(sig, *len, name); + if (rc) + return rc; + + *sig_len = be32_to_cpu(sig->sig_len); + *len -= *sig_len + sizeof(*sig); + + return 0; +} diff --git a/kernel/module_signing.c b/kernel/module_signing.c index 20857d2a15ca..1d4cb03cce21 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c @@ -25,35 +25,16 @@ int verify_appended_signature(const void *data, unsigned long *len, struct key *trusted_keys, enum key_being_used_for purpose) { - const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; - struct module_signature *ms; - unsigned long sig_len, modlen = *len; + unsigned long sig_len; int ret; - pr_devel("==>%s %s(,%lu)\n", __func__,
[PATCH v5 4/6] module: strip the signature marker in the verification function.
It is stripped by each caller separately. Note: this changes the error for kexec_file from EKEYREJECTED to ENODATA when the signature marker is missing. Signed-off-by: Michal Suchanek --- v3: - Philipp Rudo : Update the commit with note about change of raturn value - the module_signature.h is now no longer needed for kexec_file --- arch/powerpc/kexec/elf_64.c | 11 --- arch/s390/kernel/machine_kexec_file.c | 11 --- kernel/module.c | 7 +-- kernel/module_signing.c | 12 ++-- 4 files changed, 11 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c index 64cd314cce0d..6dec8151ef73 100644 --- a/arch/powerpc/kexec/elf_64.c +++ b/arch/powerpc/kexec/elf_64.c @@ -24,7 +24,6 @@ #include #include #include -#include static void *elf64_load(struct kimage *image, char *kernel_buf, unsigned long kernel_len, char *initrd, @@ -156,16 +155,6 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, #ifdef CONFIG_KEXEC_SIG int elf64_verify_sig(const char *kernel, unsigned long kernel_len) { - const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; - - if (marker_len > kernel_len) - return -EKEYREJECTED; - - if (memcmp(kernel + kernel_len - marker_len, MODULE_SIG_STRING, - marker_len)) - return -EKEYREJECTED; - kernel_len -= marker_len; - return verify_appended_signature(kernel, _len, VERIFY_USE_PLATFORM_KEYRING, "kexec_file"); } diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c index 345f2eab6e04..c3deccf1da83 100644 --- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -28,20 +27,10 @@ const struct kexec_file_ops * const kexec_file_loaders[] = { #ifdef CONFIG_KEXEC_SIG int s390_verify_sig(const char *kernel, unsigned long kernel_len) { - const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; - /* Skip signature verification when not secure IPLed. */ if (!ipl_secure_flag) return 0; - if (marker_len > kernel_len) - return -EKEYREJECTED; - - if (memcmp(kernel + kernel_len - marker_len, MODULE_SIG_STRING, - marker_len)) - return -EKEYREJECTED; - kernel_len -= marker_len; - return verify_appended_signature(kernel, _len, VERIFY_USE_PLATFORM_KEYRING, "kexec_file"); } diff --git a/kernel/module.c b/kernel/module.c index 8481933dfa92..d91ca0f93a40 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2882,7 +2882,6 @@ static inline void kmemleak_load_module(const struct module *mod, static int module_sig_check(struct load_info *info, int flags) { int err = -ENODATA; - const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; const char *reason; const void *mod = info->hdr; @@ -2890,11 +2889,7 @@ static int module_sig_check(struct load_info *info, int flags) * Require flags == 0, as a module with version information * removed is no longer the module that was signed */ - if (flags == 0 && - info->len > markerlen && - memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) { - /* We truncate the module to discard the signature */ - info->len -= markerlen; + if (flags == 0) { err = verify_appended_signature(mod, >len, VERIFY_USE_SECONDARY_KEYRING, "module"); if (!err) { diff --git a/kernel/module_signing.c b/kernel/module_signing.c index 30149969f21f..39a6dd7c6dd2 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c @@ -15,8 +15,7 @@ #include "module-internal.h" /** - * verify_appended_signature - Verify the signature on a module with the - * signature marker stripped. + * verify_appended_signature - Verify the signature on a module * @data: The data to be verified * @len: Size of @data. * @trusted_keys: Keyring to use for verification @@ -25,12 +24,21 @@ int verify_appended_signature(const void *data, unsigned long *len, struct key *trusted_keys, const char *what) { + const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; struct module_signature *ms; unsigned long sig_len, modlen = *len; int ret; pr_devel("==>%s(,%lu)\n", __func__, modlen); + if (markerlen > modlen) + return -ENODATA; + + if (memcmp(data + modlen - markerlen, MODULE_SIG_STRING, + markerlen)) + return -ENODATA; + modlen -= markerlen; +
[PATCH v5 2/6] powerpc/kexec_file: Add KEXEC_SIG support.
Copy the code from s390x Both powerpc and s390x use appended signature format (as opposed to EFI based patforms using PE format). Signed-off-by: Michal Suchanek --- v3: - Philipp Rudo : Update the comit message with explanation why the s390 code is usable on powerpc. - Include correct header for mod_check_sig - Nayna : Mention additional IMA features in kconfig text --- arch/powerpc/Kconfig| 16 arch/powerpc/kexec/elf_64.c | 36 2 files changed, 52 insertions(+) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index dea74d7717c0..1cde9b6c5987 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -560,6 +560,22 @@ config KEXEC_FILE config ARCH_HAS_KEXEC_PURGATORY def_bool KEXEC_FILE +config KEXEC_SIG + bool "Verify kernel signature during kexec_file_load() syscall" + depends on KEXEC_FILE && MODULE_SIG_FORMAT + help + This option makes kernel signature verification mandatory for + the kexec_file_load() syscall. + + In addition to that option, you need to enable signature + verification for the corresponding kernel image type being + loaded in order for this to work. + + Note: on powerpc IMA_ARCH_POLICY also implements kexec'ed kernel + verification. In addition IMA adds kernel hashes to the measurement + list, extends IMA PCR in the TPM, and implements kernel image + blacklist by hash. + config RELOCATABLE bool "Build a relocatable kernel" depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE)) diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c index eeb258002d1e..98d1cb5135b4 100644 --- a/arch/powerpc/kexec/elf_64.c +++ b/arch/powerpc/kexec/elf_64.c @@ -23,6 +23,7 @@ #include #include #include +#include static void *elf64_load(struct kimage *image, char *kernel_buf, unsigned long kernel_len, char *initrd, @@ -151,7 +152,42 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, return ret ? ERR_PTR(ret) : NULL; } +#ifdef CONFIG_KEXEC_SIG +int elf64_verify_sig(const char *kernel, unsigned long kernel_len) +{ + const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; + struct module_signature *ms; + unsigned long sig_len; + int ret; + + if (marker_len > kernel_len) + return -EKEYREJECTED; + + if (memcmp(kernel + kernel_len - marker_len, MODULE_SIG_STRING, + marker_len)) + return -EKEYREJECTED; + kernel_len -= marker_len; + + ms = (void *)kernel + kernel_len - sizeof(*ms); + ret = mod_check_sig(ms, kernel_len, "kexec"); + if (ret) + return ret; + + sig_len = be32_to_cpu(ms->sig_len); + kernel_len -= sizeof(*ms) + sig_len; + + return verify_pkcs7_signature(kernel, kernel_len, + kernel + kernel_len, sig_len, + VERIFY_USE_PLATFORM_KEYRING, + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); +} +#endif /* CONFIG_KEXEC_SIG */ + const struct kexec_file_ops kexec_elf64_ops = { .probe = kexec_elf_probe, .load = elf64_load, +#ifdef CONFIG_KEXEC_SIG + .verify_sig = elf64_verify_sig, +#endif }; -- 2.31.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH v5 0/6] KEXEC_SIG with appended signature
Hello, This is a refresh of the KEXEC_SIG series. This adds KEXEC_SIG support on powerpc and deduplicates the code dealing with appended signatures in the kernel. powerpc supports IMA_KEXEC but that's an exception rather than the norm. On the other hand, KEXEC_SIG is portable across platforms. For distributions to have uniform security features across platforms one option should be used on all platforms. Thanks Michal Previous revision: https://lore.kernel.org/linuxppc-dev/cover.1637862358.git.msucha...@suse.de/ Patched kernel tree: https://github.com/hramrach/kernel/tree/kexec_sig Michal Suchanek (6): s390/kexec_file: Don't opencode appended signature check. powerpc/kexec_file: Add KEXEC_SIG support. kexec_file: Don't opencode appended signature verification. module: strip the signature marker in the verification function. module: Use key_being_used_for for log messages in verify_appended_signature module: Move duplicate mod_check_sig users code to mod_parse_sig arch/powerpc/Kconfig | 16 +++ arch/powerpc/kexec/elf_64.c | 12 + arch/s390/Kconfig| 2 +- arch/s390/kernel/machine_kexec_file.c| 41 + crypto/asymmetric_keys/asymmetric_type.c | 1 + include/linux/module_signature.h | 4 +- include/linux/verification.h | 5 ++ kernel/module-internal.h | 2 - kernel/module.c | 12 ++--- kernel/module_signature.c| 58 +++- kernel/module_signing.c | 34 ++ security/integrity/ima/ima_modsig.c | 22 ++--- 12 files changed, 119 insertions(+), 90 deletions(-) -- 2.31.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH v5 5/6] module: Use key_being_used_for for log messages in verify_appended_signature
Add value for kexec appended signature and pass in key_being_used_for enum rather than a string to verify_appended_signature to produce log messages about the signature. Signed-off-by: Michal Suchanek --- arch/powerpc/kexec/elf_64.c | 2 +- arch/s390/kernel/machine_kexec_file.c| 2 +- crypto/asymmetric_keys/asymmetric_type.c | 1 + include/linux/verification.h | 4 +++- kernel/module.c | 3 ++- kernel/module_signing.c | 11 ++- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c index 6dec8151ef73..c50869195d51 100644 --- a/arch/powerpc/kexec/elf_64.c +++ b/arch/powerpc/kexec/elf_64.c @@ -156,7 +156,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, int elf64_verify_sig(const char *kernel, unsigned long kernel_len) { return verify_appended_signature(kernel, _len, VERIFY_USE_PLATFORM_KEYRING, -"kexec_file"); +VERIFYING_KEXEC_APPENDED_SIGNATURE); } #endif /* CONFIG_KEXEC_SIG */ diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c index c3deccf1da83..63eec38e3137 100644 --- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -32,7 +32,7 @@ int s390_verify_sig(const char *kernel, unsigned long kernel_len) return 0; return verify_appended_signature(kernel, _len, VERIFY_USE_PLATFORM_KEYRING, - "kexec_file"); + VERIFYING_KEXEC_APPENDED_SIGNATURE); } #endif /* CONFIG_KEXEC_SIG */ diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index ad8af3d70ac0..6fd20eec3882 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c @@ -25,6 +25,7 @@ const char *const key_being_used_for[NR__KEY_BEING_USED_FOR] = { [VERIFYING_KEXEC_PE_SIGNATURE] = "kexec PE sig", [VERIFYING_KEY_SIGNATURE] = "key sig", [VERIFYING_KEY_SELF_SIGNATURE] = "key self sig", + [VERIFYING_KEXEC_APPENDED_SIGNATURE]= "kexec appended sig", [VERIFYING_UNSPECIFIED_SIGNATURE] = "unspec sig", }; EXPORT_SYMBOL_GPL(key_being_used_for); diff --git a/include/linux/verification.h b/include/linux/verification.h index 32db9287a7b0..f92c49443b4f 100644 --- a/include/linux/verification.h +++ b/include/linux/verification.h @@ -26,6 +26,7 @@ enum key_being_used_for { VERIFYING_KEXEC_PE_SIGNATURE, VERIFYING_KEY_SIGNATURE, VERIFYING_KEY_SELF_SIGNATURE, + VERIFYING_KEXEC_APPENDED_SIGNATURE, VERIFYING_UNSPECIFIED_SIGNATURE, NR__KEY_BEING_USED_FOR }; @@ -61,7 +62,8 @@ extern int verify_pefile_signature(const void *pebuf, unsigned pelen, #endif int verify_appended_signature(const void *data, unsigned long *len, - struct key *trusted_keys, const char *what); + struct key *trusted_keys, + enum key_being_used_for purpose); #endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ #endif /* _LINUX_VERIFY_PEFILE_H */ diff --git a/kernel/module.c b/kernel/module.c index d91ca0f93a40..0a359dc6b690 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2891,7 +2891,8 @@ static int module_sig_check(struct load_info *info, int flags) */ if (flags == 0) { err = verify_appended_signature(mod, >len, - VERIFY_USE_SECONDARY_KEYRING, "module"); + VERIFY_USE_SECONDARY_KEYRING, + VERIFYING_MODULE_SIGNATURE); if (!err) { info->sig_ok = true; return 0; diff --git a/kernel/module_signing.c b/kernel/module_signing.c index 39a6dd7c6dd2..20857d2a15ca 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c @@ -19,17 +19,18 @@ * @data: The data to be verified * @len: Size of @data. * @trusted_keys: Keyring to use for verification - * @what: Informational string for log messages + * @purpose: The use to which the key is being put */ int verify_appended_signature(const void *data, unsigned long *len, - struct key *trusted_keys, const char *what) + struct key *trusted_keys, + enum key_being_used_for purpose) { const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; struct module_signature *ms; unsigned long sig_len, modlen = *len; int ret; - pr_devel("==>%s(,%lu)\n", __func__, modlen); + pr_devel("==>%s %s(,%lu)\n", __func__, key_being_used_for[purpose], modlen); if
[PATCH v5 3/6] kexec_file: Don't opencode appended signature verification.
Module verification already implements appeded signature verification. Reuse it for kexec_file. Signed-off-by: Michal Suchanek --- v3: - Philipp Rudo : Update the dependency on MODULE_SIG_FORMAT to MODULE_SIG - Include linux/verification.h - previously added in earlier patch v4: - kernel test robot : Use unsigned long rather than size_t for data length - Update the code in kernel/module_signing.c to use pointer rather than memcpy as the kexec and IMA code does --- arch/powerpc/Kconfig | 2 +- arch/powerpc/kexec/elf_64.c | 19 +++ arch/s390/Kconfig | 2 +- arch/s390/kernel/machine_kexec_file.c | 18 ++ include/linux/verification.h | 3 +++ kernel/module-internal.h | 2 -- kernel/module.c | 4 +++- kernel/module_signing.c | 34 --- 8 files changed, 33 insertions(+), 51 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 1cde9b6c5987..4092187474ff 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -562,7 +562,7 @@ config ARCH_HAS_KEXEC_PURGATORY config KEXEC_SIG bool "Verify kernel signature during kexec_file_load() syscall" - depends on KEXEC_FILE && MODULE_SIG_FORMAT + depends on KEXEC_FILE && MODULE_SIG help This option makes kernel signature verification mandatory for the kexec_file_load() syscall. diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c index 98d1cb5135b4..64cd314cce0d 100644 --- a/arch/powerpc/kexec/elf_64.c +++ b/arch/powerpc/kexec/elf_64.c @@ -23,6 +23,7 @@ #include #include #include +#include #include static void *elf64_load(struct kimage *image, char *kernel_buf, @@ -156,9 +157,6 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, int elf64_verify_sig(const char *kernel, unsigned long kernel_len) { const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; - struct module_signature *ms; - unsigned long sig_len; - int ret; if (marker_len > kernel_len) return -EKEYREJECTED; @@ -168,19 +166,8 @@ int elf64_verify_sig(const char *kernel, unsigned long kernel_len) return -EKEYREJECTED; kernel_len -= marker_len; - ms = (void *)kernel + kernel_len - sizeof(*ms); - ret = mod_check_sig(ms, kernel_len, "kexec"); - if (ret) - return ret; - - sig_len = be32_to_cpu(ms->sig_len); - kernel_len -= sizeof(*ms) + sig_len; - - return verify_pkcs7_signature(kernel, kernel_len, - kernel + kernel_len, sig_len, - VERIFY_USE_PLATFORM_KEYRING, - VERIFYING_MODULE_SIGNATURE, - NULL, NULL); + return verify_appended_signature(kernel, _len, VERIFY_USE_PLATFORM_KEYRING, +"kexec_file"); } #endif /* CONFIG_KEXEC_SIG */ diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 2a5bb4f29cfe..cece7152ea35 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -544,7 +544,7 @@ config ARCH_HAS_KEXEC_PURGATORY config KEXEC_SIG bool "Verify kernel signature during kexec_file_load() syscall" - depends on KEXEC_FILE && MODULE_SIG_FORMAT + depends on KEXEC_FILE && MODULE_SIG help This option makes kernel signature verification mandatory for the kexec_file_load() syscall. diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c index c944d71316c7..345f2eab6e04 100644 --- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -29,9 +29,6 @@ const struct kexec_file_ops * const kexec_file_loaders[] = { int s390_verify_sig(const char *kernel, unsigned long kernel_len) { const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; - struct module_signature *ms; - unsigned long sig_len; - int ret; /* Skip signature verification when not secure IPLed. */ if (!ipl_secure_flag) @@ -45,19 +42,8 @@ int s390_verify_sig(const char *kernel, unsigned long kernel_len) return -EKEYREJECTED; kernel_len -= marker_len; - ms = (void *)kernel + kernel_len - sizeof(*ms); - ret = mod_check_sig(ms, kernel_len, "kexec"); - if (ret) - return ret; - - sig_len = be32_to_cpu(ms->sig_len); - kernel_len -= sizeof(*ms) + sig_len; - - return verify_pkcs7_signature(kernel, kernel_len, - kernel + kernel_len, sig_len, - VERIFY_USE_PLATFORM_KEYRING, - VERIFYING_MODULE_SIGNATURE, - NULL, NULL); + return verify_appended_signature(kernel, _len,
Re: [PATCH 1/3] memblock: define functions to set the usable memory range
On Mon, Jan 10, 2022 at 09:08:07PM +, Frank van der Linden wrote: > Some architectures might limit the usable memory range based > on a firmware property, like "linux,usable-memory-range" > for ARM crash kernels. This limit needs to be enforced after > firmware memory map processing has been done, which might be > e.g. FDT or EFI, or both. > > Define an interface for it that is firmware type agnostic. > > Signed-off-by: Frank van der Linden > --- > include/linux/memblock.h | 2 ++ > mm/memblock.c| 37 + > 2 files changed, 39 insertions(+) > > diff --git a/include/linux/memblock.h b/include/linux/memblock.h > index 34de69b3b8ba..6128efa50d33 100644 > --- a/include/linux/memblock.h > +++ b/include/linux/memblock.h > @@ -481,6 +481,8 @@ phys_addr_t memblock_reserved_size(void); > phys_addr_t memblock_start_of_DRAM(void); > phys_addr_t memblock_end_of_DRAM(void); > void memblock_enforce_memory_limit(phys_addr_t memory_limit); > +void memblock_set_usable_range(phys_addr_t base, phys_addr_t size); > +void memblock_enforce_usable_range(void); > void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size); > void memblock_mem_limit_remove_map(phys_addr_t limit); We already have 3 very similar interfaces that deal with memory capping. Now you suggest to add fourth that will "generically" solve a single use case of DT, EFI and kdump interaction on arm64. Looks like a workaround for a fundamental issue of incompatibility between DT and EFI wrt memory registration. > bool memblock_is_memory(phys_addr_t addr); > diff --git a/mm/memblock.c b/mm/memblock.c > index 5096500b2647..cb961965f3ad 100644 > --- a/mm/memblock.c > +++ b/mm/memblock.c > @@ -101,6 +101,7 @@ unsigned long max_low_pfn; > unsigned long min_low_pfn; > unsigned long max_pfn; > unsigned long long max_possible_pfn; > +phys_addr_t usable_start, usable_size; > > static struct memblock_region > memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock; > static struct memblock_region > memblock_reserved_init_regions[INIT_MEMBLOCK_RESERVED_REGIONS] > __initdata_memblock; > @@ -1715,6 +1716,42 @@ void __init memblock_cap_memory_range(phys_addr_t > base, phys_addr_t size) > base + size, PHYS_ADDR_MAX); > } > > +/** > + * memblock_set_usable_range - set usable memory range > + * @base: physical address that is the start of the range > + * @size: size of the range. > + * > + * Used when a firmware property limits the range of usable > + * memory, like for the linux,usable-memory-range property > + * used by ARM crash kernels. > + */ > +void __init memblock_set_usable_range(phys_addr_t base, phys_addr_t size) > +{ > + usable_start = base; > + usable_size = size; > +} > + > +/** > + * memblock_enforce_usable_range - cap memory ranges to usable range > + * > + * Some architectures call this during boot after firmware memory ranges > + * have been scanned, to make sure they fall within the usable range > + * set by memblock_set_usable_range. > + * > + * This may be called more than once if there are multiple firmware sources > + * for memory ranges. > + * > + * Avoid "no memory registered" warning - the warning itself is > + * useful, but we know this can be called with no registered > + * memory (e.g. when the synthetic DT for the crash kernel has > + * been parsed on EFI arm64 systems). > + */ > +void __init memblock_enforce_usable_range(void) > +{ > + if (memblock_memory->total_size) > + memblock_cap_memory_range(usable_start, usable_size); > +} > + > void __init memblock_mem_limit_remove_map(phys_addr_t limit) > { > phys_addr_t max_addr; > -- > 2.32.0 > -- Sincerely yours, Mike. ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec