[PATCH OLK-5.10 0/3] Bugfix for three issues
Bugfix for the following issues: Liu Mingrui (3): zcopy: Fix invalid paging request while attach transhugepage to same addr zcopy: Fix softlockup while attach PUD-SIZE page zcopy: Fix NULL pointer dereference while attach conflict with free drivers/misc/zcopy/zcopy.c | 104 +++++++++++++++---------------------- 1 file changed, 42 insertions(+), 62 deletions(-) -- 2.25.1
hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IDBFPR -------------------------------- Fix invalid paging request while many processes attach transhugepage to same addr. Return -EAGAIN, while dst addr already has mappings. Do not pin memory to avoid the src pgtable to be modified. User should ensure the memory pinned. Unable to handle kernel paging request at virtual address ffffff0562edc000 Mem abort info: ESR = 0x96000006 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 Data abort info: ISV = 0, ISS = 0x00000006 CM = 0, WnR = 0 swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000002c39a58000 [ffffff0562edc000] pgd=0000002fffff2003, p4d=0000002fffff2003, pud=0000002fffff1003, pmd=0000000000000000 Internal error: Oops: 0000000096000006 [#1] SMP CPU: 46 PID: 20703 Comm: ioctl_zcopy_too Kdump: loaded Not tainted 5.10.0-06a8b5208512 #1 Hardware name: Huawei Taishan 2280 V2/BC82AMDD, BIOS 6.57 05/17/2023 pstate: 20400009 (nzCv daif +PAN -UAO -TCO BTYPE=--) pc : attach_huge_pmd+0x1c0/0x1330 [zcopy] lr : attach_huge_pmd+0x12a8/0x1330 [zcopy] sp : ffff800052833b70 x29: ffff800052833b70 x28: 0000000303700078 x27: ffff4176c55666e8 x26: 0000ffff5ba00000 x25: ffffff06180159c0 x24: ffff4176cc695878 x23: ffff4186000e1058 x22: ffffff05daf55980 x21: ffff6185c1aa2640 x20: ffffb3cdde249880 x19: ffffb3cd7e7cb7c0 x18: ffffffffffffffbc x17: 0000000000000000 x16: ffffb3cddb8cd028 x15: 00000000ffffffc2 x14: 00000000000e89c3 x13: 000000000000003d x12: 0000000000000000 x11: 0000000000bc0000 x10: ffff4185bfdc8640 x9 : 0000000000000000 x8 : ffff4195bfd84640 x7 : fffffdffffe00000 x6 : ffffb3cddda71640 x5 : ffffff0617e03868 x4 : ffffb3cddd2cb000 x3 : ffffff0562edc000 x2 : ffff8dc7e2313000 x1 : 0000000000303700 x0 : 00000105630dc000 Call trace: attach_huge_pmd+0x1c0/0x1330 [zcopy] attach_page_range+0x404/0x68c [zcopy] attach_pages+0x2c0/0xa24 [zcopy] zcopy_ioctl+0x120/0x22c [zcopy] vfs_ioctl+0x3c/0xb0 __se_sys_ioctl+0x12c/0x170 __arm64_sys_ioctl+0x40/0x70 invoke_syscall+0xa0/0x260 el0_svc_common.constprop.0+0xdc/0x2d0 do_el0_svc+0xd4/0x290 el0_svc+0x44/0x60 el0_sync_handler+0x26c/0x280 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 | 96 ++++++++++++++------------------------ 1 file changed, 34 insertions(+), 62 deletions(-) diff --git a/drivers/misc/zcopy/zcopy.c b/drivers/misc/zcopy/zcopy.c index a20269a3d843..c17ef99a2ccc 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; } @@ -264,10 +271,10 @@ int attach_huge_pmd(struct vm_area_struct *dst_vma, struct vm_area_struct *src_v { struct mm_struct *dst_mm, *src_mm; spinlock_t *src_ptl, *dst_ptl; - struct page *src_thp_page, *orig_thp_page; + struct page *src_thp_page; pmd_t pmd, orig_pmd; pgtable_t pgtable; - + int ret = 0; if (!vma_is_anonymous(dst_vma)) return -EINVAL; @@ -280,9 +287,18 @@ int attach_huge_pmd(struct vm_area_struct *dst_vma, struct vm_area_struct *src_v if (unlikely(!pgtable)) return -ENOMEM; - src_ptl = pmd_lockptr(src_mm, src_pmdp); dst_ptl = pmd_lockptr(dst_mm, dst_pmdp); + spin_lock_nested(dst_ptl, SINGLE_DEPTH_NESTING); + orig_pmd = *dst_pmdp; + /* check if exists old mappings */ + if (!pmd_none(orig_pmd)) { + pte_free(dst_mm, pgtable); + spin_unlock(dst_ptl); + return -EAGAIN; + } + spin_unlock(dst_ptl); + src_ptl = pmd_lockptr(src_mm, src_pmdp); spin_lock(src_ptl); pmd = *src_pmdp; src_thp_page = pmd_page(pmd); @@ -297,24 +313,13 @@ int attach_huge_pmd(struct vm_area_struct *dst_vma, struct vm_area_struct *src_v spin_unlock(src_ptl); spin_lock_nested(dst_ptl, SINGLE_DEPTH_NESTING); - orig_pmd = *dst_pmdp; - /* umap the old page mappings */ - if (!pmd_none(orig_pmd)) { - orig_thp_page = pmd_page(orig_pmd); - put_page(orig_thp_page); - atomic_dec(compound_mapcount_ptr(orig_thp_page)); - zcopy_add_mm_counter(dst_mm, MM_ANONPAGES, -HPAGE_PMD_NR); - mm_dec_nr_ptes(dst_mm); - } - zcopy_add_mm_counter(dst_mm, MM_ANONPAGES, HPAGE_PMD_NR); mm_inc_nr_ptes(dst_mm); zcopy_pgtable_trans_huge_deposit(dst_mm, dst_pmdp, pgtable); zcopy_set_pmd_at(dst_mm, dst_addr, dst_pmdp, pmd); flush_tlb_range(dst_vma, dst_addr, dst_addr + HPAGE_PMD_SIZE); spin_unlock(dst_ptl); - - return 0; + return ret; } @@ -324,10 +329,11 @@ static int attach_ptes(struct vm_area_struct *dst_vma, struct vm_area_struct *sr { struct mm_struct *dst_mm = dst_vma->vm_mm; pte_t *src_ptep, *dst_ptep, pte, orig_pte; - struct page *src_page, *orig_page; + struct page *src_page; spinlock_t *dst_ptl; int rss[NR_MM_COUNTERS]; unsigned long src_addr_end = src_addr + len; + int ret = 0; memset(rss, 0, sizeof(int) * NR_MM_COUNTERS); @@ -346,30 +352,26 @@ static int attach_ptes(struct vm_area_struct *dst_vma, struct vm_area_struct *sr if (pte_none(*src_ptep) || pte_special(*src_ptep) || !pte_present(pte)) continue; + /* check if exists old mappings */ + orig_pte = *dst_ptep; + if (!pte_none(orig_pte)) { + ret = -EAGAIN; + goto out; + } + src_page = pte_page(pte); get_page(src_page); page_dup_rmap(src_page, false); rss[MM_ANONPAGES]++; - - /* - * If dst virtual addr has page mapping, before setup the new mapping. - * we should decrease the orig page mapcount and refcount. - */ - orig_pte = *dst_ptep; - if (!pte_none(orig_pte)) { - orig_page = pte_page(orig_pte); - put_page(orig_page); - zcopy_page_remove_rmap(orig_page, false); - rss[MM_ANONPAGES]--; - } zcopy_set_pte_at(dst_mm, dst_addr, dst_ptep, pte); } flush_tlb_range(dst_vma, dst_addr, dst_addr + len); +out: zcopy_add_mm_rss_vec(dst_mm, rss); spin_unlock(dst_ptl); - return 0; + return ret; } static int attach_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, @@ -394,11 +396,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) { @@ -443,11 +443,6 @@ static int attach_pages(unsigned long dst_addr, unsigned long src_addr, { struct mm_struct *dst_mm, *src_mm; struct task_struct *src_task, *dst_task; - struct page **process_pages; - unsigned long nr_pages; - unsigned int flags = 0; - int pinned_pages; - int locked = 1; int ret; ret = -EINVAL; @@ -494,33 +489,10 @@ static int attach_pages(unsigned long dst_addr, unsigned long src_addr, goto put_dst_mm; } - nr_pages = (src_addr + size - 1) / PAGE_SIZE - src_addr / PAGE_SIZE + 1; - process_pages = kvmalloc_array(nr_pages, sizeof(struct pages *), GFP_KERNEL); - if (!process_pages) { - ret = -ENOMEM; - goto put_dst_mm; - } - - mmap_read_lock(src_mm); - pinned_pages = pin_user_pages_remote(src_mm, src_addr, nr_pages, - flags, process_pages, - NULL, &locked); - if (locked) - mmap_read_unlock(src_mm); - - if (pinned_pages <= 0) { - ret = -EFAULT; - goto free_pages_array; - } - trace_attach_page_range_start(dst_mm, src_mm, dst_addr, src_addr, size); ret = attach_page_range(dst_mm, src_mm, dst_addr, src_addr, size); trace_attach_page_range_end(dst_mm, src_mm, dst_addr, src_addr, ret); - unpin_user_pages_dirty_lock(process_pages, pinned_pages, 0); - -free_pages_array: - kvfree(process_pages); put_dst_mm: mmput(dst_mm); put_dst_task: -- 2.25.1
hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IDBQKW -------------------------------- Fix softlockup while attach PUD-SIZE page. Because we are not supported to PUD-SIZE page, just ignore to handle it. Also unsupported to filemapping PTE-PAGE to attach. watchdog: BUG: soft lockup - CPU#22 stuck for 23s! [ioctl_zcopy_too:2604618] CPU: 22 PID: 2604618 Comm: ioctl_zcopy_too Kdump: loaded Tainted: G OE 5.10.0+ #12 Hardware name: Huawei TaiShan 2280 /BC11SPCD, BIOS 1.79 12/28/2022 pstate: 00000005 (nzcv daif -PAN -UAO -TCO BTYPE=--) pc : native_queued_spin_lock_slowpath+0x15c/0x390 lr : attach_huge_pmd+0x654/0x6b8 [zcopy] sp : ffff80002d76bc20 x29: ffff80002d76bc20 x28: fffffe0050e00028 x27: fffffe006dadadc0 x26: ffff001b778e81e8 x25: ffff001440000000 x24: fffffe006dbe3a28 x23: ffff00898038da48 x22: ffff800011b8a1e0 x21: 0000ffff47a00000 x20: ffff0018038c3740 x19: fffffe006dbe3a00 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000020 x15: 0000000000000000 x14: 0000000000000020 x13: 0000000000000008 x12: ffff001ffbffa2c0 x11: 0000000000000008 x10: 0000000000000002 x9 : ffff80000946c818 x8 : ffff80001182f5ee x7 : 0000000000000000 x6 : 0000000000000000 x5 : ffff80001182f5f7 x4 : 0000000000000002 x3 : fffffe0050e00028 x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000002 Call trace: native_queued_spin_lock_slowpath+0x15c/0x390 attach_page_range+0x214/0x4f0 [zcopy] attach_pages+0xf8/0x3a0 [zcopy] zcopy_ioctl.part.0+0x98/0xf0 [zcopy] zcopy_ioctl+0x2c/0xa4 [zcopy] __arm64_sys_ioctl+0xb0/0x110 invoke_syscall+0x50/0x134 el0_svc_common.constprop.0+0x68/0x124 do_el0_svc+0x34/0xe0 el0_svc+0x20/0x30 el0_sync_handler+0xb8/0xc0 fast_work_pending464+0x178/0x18c Kernel panic - not syncing: softlockup: hung tasks Fixes: 975ef0f7a508 ("zcopy: Introduce the pageattach interface") Signed-off-by: Liu Mingrui <liumingrui@huawei.com> --- drivers/misc/zcopy/zcopy.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/misc/zcopy/zcopy.c b/drivers/misc/zcopy/zcopy.c index c17ef99a2ccc..d903365154cd 100644 --- a/drivers/misc/zcopy/zcopy.c +++ b/drivers/misc/zcopy/zcopy.c @@ -145,6 +145,9 @@ static pud_t *zcopy_get_pud(struct mm_struct *mm, unsigned long addr) if (pud_none(*pud)) return NULL; + if (!pud_table(*pud)) + return NULL; + return pud; } @@ -335,6 +338,9 @@ static int attach_ptes(struct vm_area_struct *dst_vma, struct vm_area_struct *sr unsigned long src_addr_end = src_addr + len; int ret = 0; + if (!vma_is_anonymous(dst_vma) || !vma_is_anonymous(src_vma)) + return -EINVAL; + memset(rss, 0, sizeof(int) * NR_MM_COUNTERS); src_ptep = pte_offset_map(src_pmdp, src_addr); -- 2.25.1
hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IDBKGM -------------------------------- Add mm_read_lock to avoid conflict between attach and free. Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 Mem abort info: ESR = 0x0000000096000006 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x06: level 2 translation fault Data abort info: ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000 CM = 0, WnR = 0, TnD = 0, TagAccess = 0 GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 user pgtable: 4k pages, 48-bit VAs, pgdp=000020300acd7000 [0000000000000000] pgd=0800203008421403, p4d=0800203008421403, pud=0800203008422403, pmd=0000000000000000 Internal error: Oops: 0000000096000006 [#1] SMP CPU: 107 PID: 151805 Comm: ioctl_zcopy_too Kdump: loaded Not tainted 6.6.0-f3180605d2a8 #1 Hardware name: Huawei Taishan 2280 V2/BC82AMDD, BIOS 6.57 05/17/2023 pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : attach_pte_range+0x190/0x9a0 [zcopy] lr : attach_pte_range+0xd4/0x9a0 [zcopy] sp : ffff8000be8abb20 x29: ffff8000be8abb80 x28: 0000ffff90e00000 x27: ffffa651cb444d08 x26: 0400000000000001 x25: 0000000000000000 x24: ffff203017961000 x23: 0000ffff87400000 x22: 0010000000000001 x21: fffffc80c05e5840 x20: ffff2020259111d0 x19: ffffa651cb443c40 x18: ffff8000be8ab9b0 x17: 0000000000000000 x16: ffffa651e40182b0 x15: ffffffffffffffbc x14: ffffa651e8b17c58 x13: ffff20301695a000 x12: ffffa651cb444a58 x11: 0000000000000154 x10: 0000ffff91000000 x9 : ffffa651cb43e574 x8 : 0000000000000000 x7 : ffff20300758a880 x6 : 0000000000200000 x5 : ffff203008b1b438 x4 : 0000000000000001 x3 : 00000000000001da x2 : fffffc0000000000 x1 : 0000000000000000 x0 : 00000000000001da Call trace: attach_pte_range+0x190/0x9a0 [zcopy] attach_page_range+0x22c/0x618 [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") Signed-off-by: Liu Mingrui <liumingrui@huawei.com> --- drivers/misc/zcopy/zcopy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/zcopy/zcopy.c b/drivers/misc/zcopy/zcopy.c index d903365154cd..d9cc7d45b3e8 100644 --- a/drivers/misc/zcopy/zcopy.c +++ b/drivers/misc/zcopy/zcopy.c @@ -496,7 +496,9 @@ static int attach_pages(unsigned long dst_addr, unsigned long src_addr, } trace_attach_page_range_start(dst_mm, src_mm, dst_addr, src_addr, size); + mmap_read_lock(src_mm); ret = attach_page_range(dst_mm, src_mm, dst_addr, src_addr, size); + mmap_read_unlock(src_mm); trace_attach_page_range_end(dst_mm, src_mm, dst_addr, src_addr, ret); put_dst_mm: -- 2.25.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/19575 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/ZTL... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/19575 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/ZTL...
participants (2)
-
Liu Mingrui -
patchwork bot