Message ID | 20250218225502.747963-3-chenste@linux.microsoft.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | ima: kexec: measure events between kexec load and execute | expand |
Hi steven, kernel test robot noticed the following build warnings: [auto build test WARNING on linus/master] [also build test WARNING on v6.14-rc3 next-20250219] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/steven-chen/ima-define-and-call-ima_alloc_kexec_file_buf/20250219-065931 base: linus/master patch link: https://lore.kernel.org/r/20250218225502.747963-3-chenste%40linux.microsoft.com patch subject: [PATCH v8 2/7] kexec: define functions to map and unmap segments config: x86_64-buildonly-randconfig-004-20250220 (https://download.01.org/0day-ci/archive/20250220/202502200848.MJEuphR1-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250220/202502200848.MJEuphR1-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202502200848.MJEuphR1-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from include/linux/crash_dump.h:5, from mm/mm_init.c:30: >> include/linux/kexec.h:479:47: warning: 'struct kimage' declared inside parameter list will not be visible outside of this definition or declaration 479 | static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size) | ^~~~~~ vim +479 include/linux/kexec.h 466 467 #define kexec_dprintk(fmt, arg...) \ 468 do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0) 469 470 extern void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size); 471 extern void kimage_unmap_segment(void *buffer); 472 #else /* !CONFIG_KEXEC_CORE */ 473 struct pt_regs; 474 struct task_struct; 475 static inline void __crash_kexec(struct pt_regs *regs) { } 476 static inline void crash_kexec(struct pt_regs *regs) { } 477 static inline int kexec_should_crash(struct task_struct *p) { return 0; } 478 static inline int kexec_crash_loaded(void) { return 0; } > 479 static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size) 480 { return NULL; } 481 static inline void kimage_unmap_segment(void *buffer) { } 482 #define kexec_in_progress false 483 #endif /* CONFIG_KEXEC_CORE */ 484
Hi Steven, On Tue, 2025-02-18 at 14:54 -0800, steven chen wrote: > Currently, the mechanism to map and unmap segments to the kimage > structure is not available to the subsystems outside of kexec. This > functionality is needed when IMA is allocating the memory segments > during kexec 'load' operation. Implement functions to map and unmap > segments to kimage. Obviously up to now Kexec was mapping the segments. Missing from this patch description is the reason "why" these functions are needed now. It's not enough to say "is needed when IMA is allocating the memory segments during kexec 'load' operation". The question is why does "IMA" need to allocate the memory segments. Don't make the kexec/kexec_dump maintainers guess. Refer to the section "Describe your changes" in https://www.kernel.org/doc/Documentation/process/submitting-patches.rst > > Implement kimage_map_segment() to enable mapping of IMA buffer source > pages to the kimage structure post kexec 'load'. This function, > accepting a kimage pointer, an address, and a size, will gather the > source pages within the specified address range, create an array of page > pointers, and map these to a contiguous virtual address range. The > function returns the start of this range if successful, or NULL if > unsuccessful. > > Implement kimage_unmap_segment() for unmapping segments > using vunmap(). > > From: Tushar Sugandhi <tusharsu@linux.microsoft.com> > Author: Tushar Sugandhi <tusharsu@linux.microsoft.com> Again, no such thing as an "Author" tag. Refer to the comments on 1/7. > Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> As previously requested, please add the Cc's inline here and in all the kexec/kdump related patches: Cc: Eric Biederman <ebiederm@xmission.com> Cc: Baoquan He <bhe@redhat.com> Cc: Vivek Goyal <vgoyal@redhat.com> Cc: Dave Young <dyoung@redhat.com> > Signed-off-by: steven chen <chenste@linux.microsoft.com> thanks, Mimi
diff --git a/include/linux/kexec.h b/include/linux/kexec.h index f0e9f8eda7a3..4dbf806bccef 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -467,6 +467,8 @@ extern bool kexec_file_dbg_print; #define kexec_dprintk(fmt, arg...) \ do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0) +extern void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size); +extern void kimage_unmap_segment(void *buffer); #else /* !CONFIG_KEXEC_CORE */ struct pt_regs; struct task_struct; @@ -474,6 +476,9 @@ static inline void __crash_kexec(struct pt_regs *regs) { } static inline void crash_kexec(struct pt_regs *regs) { } static inline int kexec_should_crash(struct task_struct *p) { return 0; } static inline int kexec_crash_loaded(void) { return 0; } +static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size) +{ return NULL; } +static inline void kimage_unmap_segment(void *buffer) { } #define kexec_in_progress false #endif /* CONFIG_KEXEC_CORE */ diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index c0bdc1686154..63e4d16b6023 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -867,6 +867,60 @@ int kimage_load_segment(struct kimage *image, return result; } +void *kimage_map_segment(struct kimage *image, + unsigned long addr, unsigned long size) +{ + unsigned long eaddr = addr + size; + unsigned long src_page_addr, dest_page_addr; + unsigned int npages; + struct page **src_pages; + int i; + kimage_entry_t *ptr, entry; + void *vaddr = NULL; + + /* + * Collect the source pages and map them in a contiguous VA range. + */ + npages = PFN_UP(eaddr) - PFN_DOWN(addr); + src_pages = kmalloc_array(npages, sizeof(*src_pages), GFP_KERNEL); + if (!src_pages) { + pr_err("Could not allocate ima pages array.\n"); + return NULL; + } + + i = 0; + for_each_kimage_entry(image, ptr, entry) { + if (entry & IND_DESTINATION) { + dest_page_addr = entry & PAGE_MASK; + } else if (entry & IND_SOURCE) { + if (dest_page_addr >= addr && dest_page_addr < eaddr) { + src_page_addr = entry & PAGE_MASK; + src_pages[i++] = + virt_to_page(__va(src_page_addr)); + if (i == npages) + break; + dest_page_addr += PAGE_SIZE; + } + } + } + + /* Sanity check. */ + WARN_ON(i < npages); + + vaddr = vmap(src_pages, npages, VM_MAP, PAGE_KERNEL); + kfree(src_pages); + + if (!vaddr) + pr_err("Could not map ima buffer.\n"); + + return vaddr; +} + +void kimage_unmap_segment(void *segment_buffer) +{ + vunmap(segment_buffer); +} + struct kexec_load_limit { /* Mutex protects the limit count. */ struct mutex mutex;