From 9c9c0dfee4c9aea754beb0628f01e59080d39ef6 Mon Sep 17 00:00:00 2001 From: liuyun Date: Mon, 8 May 2023 17:53:59 +0800 Subject: [PATCH 1/7] LoongArch: Fix secondary bridge routing errors LoongArch inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7362E -------------------------------- Signed-off-by: liuyun Change-Id: Id7ee072aba8bb5076cf04c97b31012c13916659d --- drivers/irqchip/irq-loongson-pch-pic.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c index 1d9fa3398cea..2deb84924632 100644 --- a/drivers/irqchip/irq-loongson-pch-pic.c +++ b/drivers/irqchip/irq-loongson-pch-pic.c @@ -392,14 +392,12 @@ static int __init acpi_cascade_irqdomain_init(void) int __init pch_pic_acpi_init(struct irq_domain *parent, struct acpi_madt_bio_pic *acpi_pchpic) { - int ret, vec_base; + int ret; struct fwnode_handle *domain_handle; if (find_pch_pic(acpi_pchpic->gsi_base) >= 0) return 0; - vec_base = acpi_pchpic->gsi_base - GSI_MIN_PCH_IRQ; - domain_handle = irq_domain_alloc_fwnode(&acpi_pchpic->address); if (!domain_handle) { pr_err("Unable to allocate domain handle\n"); @@ -407,7 +405,7 @@ int __init pch_pic_acpi_init(struct irq_domain *parent, } ret = pch_pic_init(acpi_pchpic->address, acpi_pchpic->size, - vec_base, parent, domain_handle, acpi_pchpic->gsi_base); + 0, parent, domain_handle, acpi_pchpic->gsi_base); if (ret < 0) { irq_domain_free_fwnode(domain_handle); -- Gitee From f24b8441d6190d9508f31e09969e9d02d0fd6b43 Mon Sep 17 00:00:00 2001 From: Jianmin Lv Date: Mon, 13 Feb 2023 20:43:35 +0800 Subject: [PATCH 2/7] LoongArch: Remove generic irq migration LoongArch inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7362E -------------------------------- Change-Id: I68a4dfac179ea2575925c3cd256e1179a5934c33 Signed-off-by: Jianmin Lv Signed-off-by: Juxin Gao --- arch/loongarch/Kconfig | 11 +++++----- arch/loongarch/include/asm/irq.h | 1 + arch/loongarch/kernel/irq.c | 36 ++++++++++++++++++++++++++++++++ arch/loongarch/kernel/smp.c | 3 +-- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 34eff7c52582..0d2057c4489d 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -395,13 +395,12 @@ config SMP config HOTPLUG_CPU bool "Support for hot-pluggable CPUs" depends on SMP - select GENERIC_IRQ_MIGRATION help - Say Y here to allow turning CPUs off and on. CPUs can be - controlled through /sys/devices/system/cpu. - (Note: power management support will enable this option - automatically on SMP systems. ) - Say N if you want to disable CPU hotplug. + Say Y here to allow turning CPUs off and on. CPUs can be + controlled through /sys/devices/system/cpu. + (Note: power management support will enable this option + automatically on SMP systems. ) + Say N if you want to disable CPU hotplug. config NR_CPUS int "Maximum number of CPUs (2-256)" diff --git a/arch/loongarch/include/asm/irq.h b/arch/loongarch/include/asm/irq.h index 31be19474288..b434590c3160 100644 --- a/arch/loongarch/include/asm/irq.h +++ b/arch/loongarch/include/asm/irq.h @@ -119,6 +119,7 @@ extern struct fwnode_handle *pch_lpc_handle; extern struct fwnode_handle *pch_pic_handle[MAX_IO_PICS]; extern irqreturn_t loongson3_ipi_interrupt(int irq, void *dev); +extern void fixup_irqs(void); #include diff --git a/arch/loongarch/kernel/irq.c b/arch/loongarch/kernel/irq.c index 126a9dcf7903..edad18cd2789 100644 --- a/arch/loongarch/kernel/irq.c +++ b/arch/loongarch/kernel/irq.c @@ -96,6 +96,42 @@ static int __init get_ipi_irq(void) return -EINVAL; } +#ifdef CONFIG_HOTPLUG_CPU +static void handle_irq_affinity(void) +{ + struct irq_desc *desc; + struct irq_chip *chip; + unsigned int irq; + unsigned long flags; + struct cpumask *affinity; + + for_each_active_irq(irq) { + desc = irq_to_desc(irq); + if (!desc) + continue; + + raw_spin_lock_irqsave(&desc->lock, flags); + + affinity = desc->irq_data.common->affinity; + if (!cpumask_intersects(affinity, cpu_online_mask)) + cpumask_copy(affinity, cpu_online_mask); + + chip = irq_data_get_irq_chip(&desc->irq_data); + if (chip && chip->irq_set_affinity) + chip->irq_set_affinity(&desc->irq_data, + desc->irq_data.common->affinity, true); + raw_spin_unlock_irqrestore(&desc->lock, flags); + } +} + +void fixup_irqs(void) +{ + handle_irq_affinity(); + irq_cpu_offline(); + clear_csr_ecfg(ECFG0_IM); +} +#endif + void __init init_IRQ(void) { int i, ret; diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index 4b7b42cf19bd..4d2cb1e2d661 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -272,8 +272,7 @@ int loongson3_cpu_disable(void) set_cpu_online(cpu, false); calculate_cpu_foreign_map(); local_irq_save(flags); - irq_migrate_all_off_this_cpu(); - clear_csr_ecfg(ECFG0_IM); + fixup_irqs(); local_irq_restore(flags); local_flush_tlb_all(); -- Gitee From dd318f86bf3b2a48f1c15f939f51a39cbfac98ed Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Mon, 21 Nov 2022 19:02:57 +0800 Subject: [PATCH 3/7] LoongArch: Clear FPU/SIMD thread info flags for kernel thread mainline inclusion from mainline-v6.1-rc7 commit e428e9613531d1ef6bd0d91352899712b29134fb category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7362E CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/loongarch?id=e428e9613531d1ef6bd0d91352899712b29134fb -------------------------------- If a kernel thread is created by a user thread, it may carry FPU/SIMD thread info flags (TIF_USEDFPU, TIF_USEDSIMD, etc.). Then it will be considered as a fpu owner and kernel try to save its FPU/SIMD context and cause such errors: [ 41.518931] do_fpu invoked from kernel context![#1]: [ 41.523933] CPU: 1 PID: 395 Comm: iou-wrk-394 Not tainted 6.1.0-rc5+ #217 [ 41.530757] Hardware name: Loongson Loongson-3A5000-7A1000-1w-CRB/Loongson-LS3A5000-7A1000-1w-CRB, BIOS vUDK2018-LoongArch-V2.0.pre-beta8 08/18/2022 [ 41.544064] $ 0 : 0000000000000000 90000000011e9468 9000000106c7c000 9000000106c7fcf0 [ 41.552101] $ 4 : 9000000106305d40 9000000106689800 9000000106c7fd08 0000000003995818 [ 41.560138] $ 8 : 0000000000000001 90000000009a72e4 0000000000000020 fffffffffffffffc [ 41.568174] $12 : 0000000000000000 0000000000000000 0000000000000020 00000009aab7e130 [ 41.576211] $16 : 00000000000001ff 0000000000000407 0000000000000001 0000000000000000 [ 41.584247] $20 : 0000000000000000 0000000000000001 9000000106c7fd70 90000001002f0400 [ 41.592284] $24 : 0000000000000000 900000000178f740 90000000011e9834 90000001063057c0 [ 41.600320] $28 : 0000000000000000 0000000000000001 9000000006826b40 9000000106305140 [ 41.608356] era : 9000000000228848 _save_fp+0x0/0xd8 [ 41.613542] ra : 90000000011e9468 __schedule+0x568/0x8d0 [ 41.619160] CSR crmd: 000000b0 [ 41.619163] CSR prmd: 00000000 [ 41.622359] CSR euen: 00000000 [ 41.625558] CSR ecfg: 00071c1c [ 41.628756] CSR estat: 000f0000 [ 41.635239] ExcCode : f (SubCode 0) [ 41.638783] PrId : 0014c010 (Loongson-64bit) [ 41.643191] Modules linked in: acpi_ipmi vfat fat ipmi_si ipmi_devintf cfg80211 ipmi_msghandler rfkill fuse efivarfs [ 41.653734] Process iou-wrk-394 (pid: 395, threadinfo=0000000004ebe913, task=00000000636fa1be) [ 41.662375] Stack : 00000000ffff0875 9000000006800ec0 9000000006800ec0 90000000002d57e0 [ 41.670412] 0000000000000001 0000000000000000 9000000106535880 0000000000000001 [ 41.678450] 9000000105291800 0000000000000000 9000000105291838 900000000178e000 [ 41.686487] 9000000106c7fd90 9000000106305140 0000000000000001 90000000011e9834 [ 41.694523] 00000000ffff0875 90000000011f034c 9000000105291838 9000000105291830 [ 41.702561] 0000000000000000 9000000006801440 00000000ffff0875 90000000002d48c0 [ 41.710597] 9000000128800001 9000000106305140 9000000105291838 9000000105291838 [ 41.718634] 9000000105291830 9000000107811740 9000000105291848 90000000009bf1e0 [ 41.726672] 9000000105291830 9000000107811748 2d6b72772d756f69 0000000000343933 [ 41.734708] 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 41.742745] ... [ 41.745252] Call Trace: [ 42.197868] [<9000000000228848>] _save_fp+0x0/0xd8 [ 42.205214] [<90000000011ed468>] __schedule+0x568/0x8d0 [ 42.210485] [<90000000011ed834>] schedule+0x64/0xd4 [ 42.215411] [<90000000011f434c>] schedule_timeout+0x88/0x188 [ 42.221115] [<90000000009c36d0>] io_wqe_worker+0x184/0x350 [ 42.226645] [<9000000000221cf0>] ret_from_kernel_thread+0xc/0x9c This can be easily triggered by ltp testcase syscalls/io_uring02 and it can also be easily fixed by clearing the FPU/SIMD thread info flags for kernel threads in copy_thread(). Cc: stable@vger.kernel.org Reported-by: Qi Hu Signed-off-by: Huacai Chen --- arch/loongarch/kernel/process.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c index 86600e39799e..f6c0bdb0238b 100644 --- a/arch/loongarch/kernel/process.c +++ b/arch/loongarch/kernel/process.c @@ -156,7 +156,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, childregs->csr_crmd = p->thread.csr_crmd; childregs->csr_prmd = p->thread.csr_prmd; childregs->csr_ecfg = p->thread.csr_ecfg; - return 0; + goto out; } /* user thread */ @@ -175,14 +175,15 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, */ childregs->csr_euen = 0; + if (clone_flags & CLONE_SETTLS) + childregs->regs[2] = tls; + +out: clear_tsk_thread_flag(p, TIF_USEDFPU); clear_tsk_thread_flag(p, TIF_USEDSIMD); clear_tsk_thread_flag(p, TIF_LSX_CTX_LIVE); clear_tsk_thread_flag(p, TIF_LASX_CTX_LIVE); - if (clone_flags & CLONE_SETTLS) - childregs->regs[2] = tls; - return 0; } -- Gitee From 1267d8f9d7258416182198d38d727559628ce3a9 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Mon, 21 Nov 2022 19:02:57 +0800 Subject: [PATCH 4/7] LoongArch: Set _PAGE_DIRTY only if _PAGE_WRITE is set in {pmd,pte}_mkdirty() mainline inclusion from mainline-v6.1-rc7 commit bf2f34a506e66e2979de6b17c337c5d4b25b4d2c category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7362E CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/loongarch?id=bf2f34a506e66e2979de6b17c337c5d4b25b4d2c -------------------------------- Now {pmd,pte}_mkdirty() set _PAGE_DIRTY bit unconditionally, this causes random segmentation fault after commit 0ccf7f168e17bb7e ("mm/thp: carry over dirty bit when thp splits on pmd"). The reason is: when fork(), parent process use pmd_wrprotect() to clear huge page's _PAGE_WRITE and _PAGE_DIRTY (for COW); then pte_mkdirty() set _PAGE_DIRTY as well as _PAGE_MODIFIED while splitting dirty huge pages; once _PAGE_DIRTY is set, there will be no tlb modify exception so the COW machanism fails; and at last memory corruption occurred between parent and child processes. So, we should set _PAGE_DIRTY only when _PAGE_WRITE is set in {pmd,pte}_ mkdirty(). Cc: stable@vger.kernel.org Cc: Peter Xu Signed-off-by: Huacai Chen Change-Id: Iade25111367c20f3cf777630e09eb6a10a62b6a8 --- arch/loongarch/include/asm/pgtable.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h index eb3318927644..3927874f4d65 100644 --- a/arch/loongarch/include/asm/pgtable.h +++ b/arch/loongarch/include/asm/pgtable.h @@ -361,7 +361,9 @@ static inline pte_t pte_mkclean(pte_t pte) static inline pte_t pte_mkdirty(pte_t pte) { - pte_val(pte) |= (_PAGE_DIRTY | _PAGE_MODIFIED); + pte_val(pte) |= _PAGE_MODIFIED; + if (pte_val(pte) & _PAGE_WRITE) + pte_val(pte) |= _PAGE_DIRTY; return pte; } @@ -487,7 +489,9 @@ static inline pmd_t pmd_mkclean(pmd_t pmd) static inline pmd_t pmd_mkdirty(pmd_t pmd) { - pmd_val(pmd) |= (_PAGE_DIRTY | _PAGE_MODIFIED); + pmd_val(pmd) |= _PAGE_MODIFIED; + if (pmd_val(pmd) & _PAGE_WRITE) + pmd_val(pmd) |= _PAGE_DIRTY; return pmd; } -- Gitee From df87bdf6368f541538ec33ec3ee14b32ebf53851 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Mon, 21 Nov 2022 19:02:57 +0800 Subject: [PATCH 5/7] LoongArch: Set _PAGE_DIRTY only if _PAGE_MODIFIED is set in {pmd,pte}_mkwrite() mainline inclusion from mainline-v6.1-rc7 commit 54e6cd42a183b602e3627ad3aaeeed44f7443e67 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7362E CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/loongarch?id=54e6cd42a183b602e3627ad3aaeeed44f7443e67 -------------------------------- Set _PAGE_DIRTY only if _PAGE_MODIFIED is set in {pmd,pte}_mkwrite(). Otherwise, _PAGE_DIRTY silences the TLB modify exception and make us have no chance to mark a pmd/pte dirty (_PAGE_MODIFIED) for software. Reviewed-by: Guo Ren Signed-off-by: Huacai Chen Change-Id: I05f95f28b6c2a18c44b41f253a2f4cbb987521b9 --- arch/loongarch/include/asm/pgtable.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h index 3927874f4d65..12adbb2bb67d 100644 --- a/arch/loongarch/include/asm/pgtable.h +++ b/arch/loongarch/include/asm/pgtable.h @@ -369,7 +369,9 @@ static inline pte_t pte_mkdirty(pte_t pte) static inline pte_t pte_mkwrite(pte_t pte) { - pte_val(pte) |= (_PAGE_WRITE | _PAGE_DIRTY); + pte_val(pte) |= _PAGE_WRITE; + if (pte_val(pte) & _PAGE_MODIFIED) + pte_val(pte) |= _PAGE_DIRTY; return pte; } @@ -466,7 +468,9 @@ static inline int pmd_write(pmd_t pmd) static inline pmd_t pmd_mkwrite(pmd_t pmd) { - pmd_val(pmd) |= (_PAGE_WRITE | _PAGE_DIRTY); + pmd_val(pmd) |= _PAGE_WRITE; + if (pmd_val(pmd) & _PAGE_MODIFIED) + pmd_val(pmd) |= _PAGE_DIRTY; return pmd; } -- Gitee From 46339cd69eff13a328a95a028f5c56b73ea080c5 Mon Sep 17 00:00:00 2001 From: Hongchen Zhang Date: Thu, 27 Apr 2023 20:35:04 +0800 Subject: [PATCH 6/7] i2c: loongson: fix irq not freed when remove module LoongArch inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7362E -------------------------------- The interrupt resource of i2c_loongson module is not free normally when rmmod. We should free the interrupt resource in loongson_i2c_remove. Signed-off-by: Hongchen Zhang Change-Id: I329560ece8890f5d462b898a814bdcecd5951b6b --- drivers/i2c/busses/i2c-loongson.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-loongson.c b/drivers/i2c/busses/i2c-loongson.c index a2dc0dd1e4f8..be533c53e6da 100644 --- a/drivers/i2c/busses/i2c-loongson.c +++ b/drivers/i2c/busses/i2c-loongson.c @@ -508,6 +508,7 @@ static int loongson_i2c_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); i2c_del_adapter(&dev->adapter); + free_irq(dev->irq, dev); iounmap(dev->base); kfree(dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- Gitee From 850defab3ab186a5ec07650545451d50a34af8dc Mon Sep 17 00:00:00 2001 From: Hongchen Zhang Date: Thu, 4 May 2023 14:15:37 +0800 Subject: [PATCH 7/7] LoongArch: defconfig: enable CONFIG_CACHEFILES LoongArch inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7362E -------------------------------- enable cachefiles module, used by cachefilesd service. Signed-off-by: Hongchen Zhang Change-Id: I2c7a60b51e5c3a656b0821d6be9e505f1f9e6768 --- arch/loongarch/configs/loongson3_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig index ed606e85e72c..dd859c7fe938 100644 --- a/arch/loongarch/configs/loongson3_defconfig +++ b/arch/loongarch/configs/loongson3_defconfig @@ -981,6 +981,7 @@ CONFIG_OVERLAY_FS_INDEX=y CONFIG_OVERLAY_FS_XINO_AUTO=y CONFIG_OVERLAY_FS_METACOPY=y CONFIG_FSCACHE=y +CONFIG_CACHEFILES=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y -- Gitee