hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID96R2 -------------------------------- Add some judge to avoid panic on tran hugepage split case. Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 CPU: 59 PID: 215951 Comm: ioctl_zcopy_too Kdump: loaded Not tainted 6.6 Hardware name: Huawei Taishan 2280 V2/BC82AMDD, BIOS 6.57 05/17/2023 pstate: 20400009 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : attach_pte_range+0x3b0/0x978 [zcopy] lr : attach_pte_range+0xd4/0x978 [zcopy] sp : ffff8000cd1ebb30 x29: ffff8000cd1ebb90 x28: 0000ffff7dc00000 x27: 00600036c876afc3 x26: 0400000000000001 x25: ffff002c621ee000 x24: 0000000000000000 x23: 0000ffffaf600000 x22: 0010000000000001 x21: fffffc0094c90000 x20: 0000000000000000 x19: ffffaf6cd4307c40 x18: 000000000014080d x17: 00fffefdfcfbfaf9 x16: ffffaf6d281727f8 x15: 0000000000000001 x14: 0000000000000000 x13: ffffaf6d283444c8 x12: 0000ffffb78d3fff x11: 0000000000000000 x10: 0000ffff7de00000 x9 : ffffaf6cd43026fc x8 : 0000000000000000 x7 : ffff0020a20b0000 x6 : 0000000000200000 x5 : ffff002118e6bf70 x4 : 0000000000000200 x3 : 0000000000000001 x2 : 0000000000001000 x1 : 0000000000001000 x0 : 00000000000001ff Call trace: attach_pte_range+0x3b0/0x978 [zcopy] attach_page_range+0x1f4/0x600 [zcopy] attach_pages+0x2b8/0x8b8 [zcopy] zcopy_ioctl+0xe8/0x168 [zcopy] vfs_ioctl+0x3c/0xa8 __se_sys_ioctl+0x12c/0x160 __arm64_sys_ioctl+0x40/0x68 invoke_syscall+0x8c/0x1d0 el0_svc_common.constprop.0+0x64/0x1d0 do_el0_svc+0x54/0xe0 el0_slow_syscall+0x44/0x1e8 el0t_64_sync_handler+0xc0/0xc8 el0t_64_sync+0x188/0x190 Fixes: 975ef0f7a508 ("zcopy: Introduce the pageattach interface") Fixes: 2125c55fc876 ("zcopy: Extend PMD trans hugepage mapping ability") Signed-off-by: Liu Mingrui <liumingrui@huawei.com> --- drivers/misc/zcopy/zcopy.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/misc/zcopy/zcopy.c b/drivers/misc/zcopy/zcopy.c index a20269a3d843..3a5e8626de63 100644 --- a/drivers/misc/zcopy/zcopy.c +++ b/drivers/misc/zcopy/zcopy.c @@ -177,11 +177,12 @@ static pud_t *zcopy_alloc_new_pud(struct mm_struct *mm, unsigned long addr) return zcopy_pud_alloc(mm, p4d, addr); } -static pmd_t *zcopy_alloc_pmd(struct mm_struct *mm, unsigned long addr) +static pmd_t *zcopy_alloc_pmd(struct mm_struct *mm, unsigned long addr, int *rc) { pud_t *pud; pmd_t *pmd; + *rc = -ENOMEM; pud = zcopy_alloc_new_pud(mm, addr); if (!pud) return NULL; @@ -190,6 +191,12 @@ static pmd_t *zcopy_alloc_pmd(struct mm_struct *mm, unsigned long addr) if (!pmd) return NULL; + if (pmd_trans_huge(*pmd)) { + pr_warn_once("va mapped to hugepage, please free it and realloc va\n"); + *rc = -EAGAIN; + return NULL; + } + return pmd; } @@ -394,11 +401,9 @@ static int attach_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, src_pmd = zcopy_get_pmd(src_mm, src_addr); if (!src_pmd) continue; - dst_pmd = zcopy_alloc_pmd(dst_mm, dst_addr); - if (!dst_pmd) { - ret = -ENOMEM; + dst_pmd = zcopy_alloc_pmd(dst_mm, dst_addr, &ret); + if (!dst_pmd) break; - } if (pmd_trans_huge(*src_pmd)) { if (extent == HPAGE_PMD_SIZE) { -- 2.25.1