Message ID | 20241116175922.3265872-3-pasha.tatashin@soleen.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Page Detective | expand |
On Sat, Nov 16, 2024 at 05:59:18PM +0000, Pasha Tatashin wrote: > } while (start = next, start < end); > return err; > } > +EXPORT_SYMBOL_GPL(walk_page_range); Umm, no. We really should not expose all these page table detail to modules. > +EXPORT_SYMBOL_GPL(walk_page_range_kernel); Even more so here.
On Sun, Nov 17, 2024 at 10:49:06PM -0800, Christoph Hellwig wrote: > On Sat, Nov 16, 2024 at 05:59:18PM +0000, Pasha Tatashin wrote: > > } while (start = next, start < end); > > return err; > > } > > +EXPORT_SYMBOL_GPL(walk_page_range); > > Umm, no. We really should not expose all these page table detail > to modules. > > > +EXPORT_SYMBOL_GPL(walk_page_range_kernel); > > Even more so here. > Very much agree. You basically then have the ability for any (GPL) driver to come in and modify page tables at will which is VERY MUCH not a good idea. The rules around page table manipulation are very subtle and constantly changing, this is not something for anything outside of mm to be fiddling with. Again, I find it bizarre we're exporting mm internal implementation details to a driver to do stuff with rather than adding functionality to mm.
On Mon, Nov 18, 2024 at 1:49 AM Christoph Hellwig <hch@infradead.org> wrote: > > On Sat, Nov 16, 2024 at 05:59:18PM +0000, Pasha Tatashin wrote: > > } while (start = next, start < end); > > return err; > > } > > +EXPORT_SYMBOL_GPL(walk_page_range); > > Umm, no. We really should not expose all these page table detail > to modules. > > > +EXPORT_SYMBOL_GPL(walk_page_range_kernel); > > Even more so here. I will remove these exports in the next version, as I am going to convert Page Detective to be part of core mm instead of misc device. Thanks, Pasha
diff --git a/include/linux/pagewalk.h b/include/linux/pagewalk.h index f5eb5a32aeed..ff25374470f0 100644 --- a/include/linux/pagewalk.h +++ b/include/linux/pagewalk.h @@ -124,6 +124,8 @@ int walk_page_range_novma(struct mm_struct *mm, unsigned long start, int walk_page_range_vma(struct vm_area_struct *vma, unsigned long start, unsigned long end, const struct mm_walk_ops *ops, void *private); +int walk_page_range_kernel(unsigned long start, unsigned long end, + const struct mm_walk_ops *ops, void *private); int walk_page_vma(struct vm_area_struct *vma, const struct mm_walk_ops *ops, void *private); int walk_page_mapping(struct address_space *mapping, pgoff_t first_index, diff --git a/mm/pagewalk.c b/mm/pagewalk.c index 5f9f01532e67..050790aeb15f 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c @@ -478,6 +478,7 @@ int walk_page_range(struct mm_struct *mm, unsigned long start, } while (start = next, start < end); return err; } +EXPORT_SYMBOL_GPL(walk_page_range); /** * walk_page_range_novma - walk a range of pagetables not backed by a vma @@ -541,6 +542,37 @@ int walk_page_range_novma(struct mm_struct *mm, unsigned long start, return walk_pgd_range(start, end, &walk); } +/** + * walk_page_range_kernel - walk a range of pagetables of kernel/init_mm + * @start: start address of the virtual address range + * @end: end address of the virtual address range + * @ops: operation to call during the walk + * @private: private data for callbacks' usage + * + * Similar to walk_page_range_novma() but specifically walks init_mm.pgd table. + * + * Note: This function takes two looks: get_online_mems(), and mmap_read, this + * is to prevent kernel page tables from being freed while walking. + */ +int walk_page_range_kernel(unsigned long start, unsigned long end, + const struct mm_walk_ops *ops, void *private) +{ + get_online_mems(); + if (mmap_read_lock_killable(&init_mm)) { + put_online_mems(); + return -EAGAIN; + } + + walk_page_range_novma(&init_mm, start, end, ops, + init_mm.pgd, private); + + mmap_read_unlock(&init_mm); + put_online_mems(); + + return 0; +} +EXPORT_SYMBOL_GPL(walk_page_range_kernel); + int walk_page_range_vma(struct vm_area_struct *vma, unsigned long start, unsigned long end, const struct mm_walk_ops *ops, void *private)
Page Detective will use it to walk the kernel page table. Make this function accessible from modules, and also while here make walk_page_range() accessible from modules, so Page Detective could use it to walk user page tables. Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> --- include/linux/pagewalk.h | 2 ++ mm/pagewalk.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+)