From 55a2aa08b3af519a9693f99cdf7fa6d8b62d9f65 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 27 Apr 2018 09:28:34 +1000 Subject: [PATCH 1/7] MIPS: c-r4k: Fix data corruption related to cache coherence When DMA will be performed to a MIPS32 1004K CPS, the L1-cache for the range needs to be flushed and invalidated first. The code currently takes one of two approaches. 1/ If the range is less than the size of the dcache, then HIT type requests flush/invalidate cache lines for the particular addresses. HIT-type requests a globalised by the CPS so this is safe on SMP. 2/ If the range is larger than the size of dcache, then INDEX type requests flush/invalidate the whole cache. INDEX type requests affect the local cache only. CPS does not propagate them in any way. So this invalidation is not safe on SMP CPS systems. Data corruption due to '2' can quite easily be demonstrated by repeatedly "echo 3 > /proc/sys/vm/drop_caches" and then sha1sum a file that is several times the size of available memory. Dropping caches means that large contiguous extents (large than dcache) are more likely. This was not a problem before Linux-4.8 because option 2 was never used if CONFIG_MIPS_CPS was defined. The commit which removed that apparently didn't appreciate the full consequence of the change. We could, in theory, globalize the INDEX based flush by sending an IPI to other cores. These cache invalidation routines can be called with interrupts disabled and synchronous IPI require interrupts to be enabled. Asynchronous IPI may not trigger writeback soon enough. So we cannot use IPI in practice. We can already test if IPI would be needed for an INDEX operation with r4k_op_needs_ipi(R4K_INDEX). If this is true then we mustn't try the INDEX approach as we cannot use IPI. If this is false (e.g. when there is only one core and hence one L1 cache) then it is safe to use the INDEX approach without IPI. This patch avoids options 2 if r4k_op_needs_ipi(R4K_INDEX), and so eliminates the corruption. Fixes: c00ab4896ed5 ("MIPS: Remove cpu_has_safe_index_cacheops") Signed-off-by: NeilBrown Cc: Ralf Baechle Cc: Paul Burton Cc: linux-mips@linux-mips.org Cc: # 4.8+ Patchwork: https://patchwork.linux-mips.org/patch/19259/ Signed-off-by: James Hogan --- arch/mips/mm/c-r4k.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 6f534b209971..e12dfa48b478 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -851,9 +851,12 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) /* * Either no secondary cache or the available caches don't have the * subset property so we have to flush the primary caches - * explicitly + * explicitly. + * If we would need IPI to perform an INDEX-type operation, then + * we have to use the HIT-type alternative as IPI cannot be used + * here due to interrupts possibly being disabled. */ - if (size >= dcache_size) { + if (!r4k_op_needs_ipi(R4K_INDEX) && size >= dcache_size) { r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; @@ -890,7 +893,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) return; } - if (size >= dcache_size) { + if (!r4k_op_needs_ipi(R4K_INDEX) && size >= dcache_size) { r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; From c60128ce97674fd05adb8b5ae79eb6745a03192e Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 28 Mar 2018 17:38:12 +0200 Subject: [PATCH 2/7] MIPS: Fix build with DEBUG_ZBOOT and MACH_JZ4770 The debug definitions were missing for MACH_JZ4770, resulting in a build failure when DEBUG_ZBOOT was set. Since the UART addresses are the same across all Ingenic SoCs, we just use a #ifdef CONFIG_MACH_INGENIC instead of checking for individual Ingenic SoCs. Additionally, I added a #define for the UART0 address in-code and dropped the include, for the reason that this include file is slowly being phased out as the whole platform is being moved to devicetree. Fixes: 9be5f3e92ed5 ("MIPS: ingenic: Initial JZ4770 support") Signed-off-by: Paul Cercueil Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: # 4.16 Patchwork: https://patchwork.linux-mips.org/patch/18957/ Signed-off-by: James Hogan --- arch/mips/boot/compressed/uart-16550.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c index b3043c08f769..aee8d7b8f091 100644 --- a/arch/mips/boot/compressed/uart-16550.c +++ b/arch/mips/boot/compressed/uart-16550.c @@ -18,9 +18,9 @@ #define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset)) #endif -#if defined(CONFIG_MACH_JZ4740) || defined(CONFIG_MACH_JZ4780) -#include -#define PORT(offset) (CKSEG1ADDR(JZ4740_UART0_BASE_ADDR) + (4 * offset)) +#ifdef CONFIG_MACH_INGENIC +#define INGENIC_UART0_BASE_ADDR 0x10030000 +#define PORT(offset) (CKSEG1ADDR(INGENIC_UART0_BASE_ADDR) + (4 * offset)) #endif #ifdef CONFIG_CPU_XLR From 71e909c0cdad28a1df1fa14442929e68615dee45 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 30 Apr 2018 15:56:47 +0100 Subject: [PATCH 3/7] MIPS: ptrace: Expose FIR register through FP regset Correct commit 7aeb753b5353 ("MIPS: Implement task_user_regset_view.") and expose the FIR register using the unused 4 bytes at the end of the NT_PRFPREG regset. Without that register included clients cannot use the PTRACE_GETREGSET request to retrieve the complete FPU register set and have to resort to one of the older interfaces, either PTRACE_PEEKUSR or PTRACE_GETFPREGS, to retrieve the missing piece of data. Also the register is irreversibly missing from core dumps. This register is architecturally hardwired and read-only so the write path does not matter. Ignore data supplied on writes then. Fixes: 7aeb753b5353 ("MIPS: Implement task_user_regset_view.") Signed-off-by: James Hogan Signed-off-by: Maciej W. Rozycki Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: # 3.13+ Patchwork: https://patchwork.linux-mips.org/patch/19273/ Signed-off-by: James Hogan --- arch/mips/kernel/ptrace.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 0b23b1ad99e6..aede42990f08 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -463,7 +463,7 @@ static int fpr_get_msa(struct task_struct *target, /* * Copy the floating-point context to the supplied NT_PRFPREG buffer. * Choose the appropriate helper for general registers, and then copy - * the FCSR register separately. + * the FCSR and FIR registers separately. */ static int fpr_get(struct task_struct *target, const struct user_regset *regset, @@ -471,6 +471,7 @@ static int fpr_get(struct task_struct *target, void *kbuf, void __user *ubuf) { const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t); + const int fir_pos = fcr31_pos + sizeof(u32); int err; if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t)) @@ -483,6 +484,12 @@ static int fpr_get(struct task_struct *target, err = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.fpu.fcr31, fcr31_pos, fcr31_pos + sizeof(u32)); + if (err) + return err; + + err = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &boot_cpu_data.fpu_id, + fir_pos, fir_pos + sizeof(u32)); return err; } @@ -531,7 +538,8 @@ static int fpr_set_msa(struct task_struct *target, /* * Copy the supplied NT_PRFPREG buffer to the floating-point context. * Choose the appropriate helper for general registers, and then copy - * the FCSR register separately. + * the FCSR register separately. Ignore the incoming FIR register + * contents though, as the register is read-only. * * We optimize for the case where `count % sizeof(elf_fpreg_t) == 0', * which is supposed to have been guaranteed by the kernel before @@ -545,6 +553,7 @@ static int fpr_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t); + const int fir_pos = fcr31_pos + sizeof(u32); u32 fcr31; int err; @@ -572,6 +581,11 @@ static int fpr_set(struct task_struct *target, ptrace_setfcr31(target, fcr31); } + if (count > 0) + err = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + fir_pos, + fir_pos + sizeof(u32)); + return err; } From ba3696e94d9d590d9a7e55f68e81c25dba515191 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 14 May 2018 18:23:50 +0100 Subject: [PATCH 4/7] KVM: Fix spelling mistake: "cop_unsuable" -> "cop_unusable" Trivial fix to spelling mistake in debugfs_entries text. Fixes: 669e846e6c4e ("KVM/MIPS32: MIPS arch specific APIs for KVM") Signed-off-by: Colin Ian King Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: kernel-janitors@vger.kernel.org Cc: # 3.10+ Signed-off-by: James Hogan --- arch/mips/kvm/mips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 2549fdd27ee1..0f725e9cee8f 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -45,7 +45,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "cache", VCPU_STAT(cache_exits), KVM_STAT_VCPU }, { "signal", VCPU_STAT(signal_exits), KVM_STAT_VCPU }, { "interrupt", VCPU_STAT(int_exits), KVM_STAT_VCPU }, - { "cop_unsuable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU }, + { "cop_unusable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU }, { "tlbmod", VCPU_STAT(tlbmod_exits), KVM_STAT_VCPU }, { "tlbmiss_ld", VCPU_STAT(tlbmiss_ld_exits), KVM_STAT_VCPU }, { "tlbmiss_st", VCPU_STAT(tlbmiss_st_exits), KVM_STAT_VCPU }, From a5a92abbce56c41ff121db41a33b9c0a0ff39365 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 25 Apr 2018 23:10:35 +0200 Subject: [PATCH 5/7] MIPS: xilfpga: Stop generating useless dtb.o A dtb.o is generated from nexys4ddr.dts but this is never used since it has been moved to mips/generic with commit b35565bb16a5 ("MIPS: generic: Add support for MIPSfpga"). Fixes: b35565bb16a5 ("MIPS: generic: Add support for MIPSfpga") Signed-off-by: Alexandre Belloni Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: # 4.15+ Patchwork: https://patchwork.linux-mips.org/patch/19244/ Signed-off-by: James Hogan --- arch/mips/boot/dts/xilfpga/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/mips/boot/dts/xilfpga/Makefile b/arch/mips/boot/dts/xilfpga/Makefile index 9987e0e378c5..69ca00590b8d 100644 --- a/arch/mips/boot/dts/xilfpga/Makefile +++ b/arch/mips/boot/dts/xilfpga/Makefile @@ -1,4 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_FIT_IMAGE_FDT_XILFPGA) += nexys4ddr.dtb - -obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) From 947bc875116042d5375446aa29bc1073c2d38977 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 25 Apr 2018 23:10:36 +0200 Subject: [PATCH 6/7] MIPS: xilfpga: Actually include FDT in fitImage Commit b35565bb16a5 ("MIPS: generic: Add support for MIPSfpga") added and its.S file for xilfpga but forgot to add it to arch/mips/generic/Platform so it is never used. Fixes: b35565bb16a5 ("MIPS: generic: Add support for MIPSfpga") Signed-off-by: Alexandre Belloni Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: # 4.15+ Patchwork: https://patchwork.linux-mips.org/patch/19245/ Signed-off-by: James Hogan --- arch/mips/generic/Platform | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/generic/Platform b/arch/mips/generic/Platform index b51432dd10b6..0dd0d5d460a5 100644 --- a/arch/mips/generic/Platform +++ b/arch/mips/generic/Platform @@ -16,3 +16,4 @@ all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb its-y := vmlinux.its.S its-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += board-boston.its.S its-$(CONFIG_FIT_IMAGE_FDT_NI169445) += board-ni169445.its.S +its-$(CONFIG_FIT_IMAGE_FDT_XILFPGA) += board-xilfpga.its.S From 9a3a92ccfe3620743d4ae57c987dc8e9c5f88996 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 14 May 2018 16:49:43 +0100 Subject: [PATCH 7/7] MIPS: Fix ptrace(2) PTRACE_PEEKUSR and PTRACE_POKEUSR accesses to o32 FGRs Check the TIF_32BIT_FPREGS task setting of the tracee rather than the tracer in determining the layout of floating-point general registers in the floating-point context, correcting access to odd-numbered registers for o32 tracees where the setting disagrees between the two processes. Fixes: 597ce1723e0f ("MIPS: Support for 64-bit FP with O32 binaries") Signed-off-by: Maciej W. Rozycki Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: # 3.14+ Signed-off-by: James Hogan --- arch/mips/kernel/ptrace.c | 4 ++-- arch/mips/kernel/ptrace32.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index aede42990f08..8d098b9f395c 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -807,7 +807,7 @@ long arch_ptrace(struct task_struct *child, long request, fregs = get_fpu_regs(child); #ifdef CONFIG_32BIT - if (test_thread_flag(TIF_32BIT_FPREGS)) { + if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) { /* * The odd registers are actually the high * order bits of the values stored in the even @@ -902,7 +902,7 @@ long arch_ptrace(struct task_struct *child, long request, init_fp_ctx(child); #ifdef CONFIG_32BIT - if (test_thread_flag(TIF_32BIT_FPREGS)) { + if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) { /* * The odd registers are actually the high * order bits of the values stored in the even diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index 2b9260f92ccd..656a137c1fe2 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c @@ -99,7 +99,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, break; } fregs = get_fpu_regs(child); - if (test_thread_flag(TIF_32BIT_FPREGS)) { + if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) { /* * The odd registers are actually the high * order bits of the values stored in the even @@ -212,7 +212,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, sizeof(child->thread.fpu)); child->thread.fpu.fcr31 = 0; } - if (test_thread_flag(TIF_32BIT_FPREGS)) { + if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) { /* * The odd registers are actually the high * order bits of the values stored in the even