diff --git a/debian/changelog b/debian/changelog index f89759dc8..9c37d05f4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -17,6 +17,9 @@ linux (4.19.67-3) UNRELEASED; urgency=medium * drivers/net/ethernet/amazon: Backport driver fixes from Linux 5.4 (Closes: #941291) + [ Aurelien Jarno ] + * [mips*] tlbex: Fix build_restore_pagemask KScratch restore. + -- Romain Perier Wed, 28 Aug 2019 13:28:09 +0200 linux (4.19.67-2+deb10u2) buster-security; urgency=high diff --git a/debian/patches/bugfix/mips/MIPS-tlbex-Fix-build_restore_pagemask-KScratch-resto.patch b/debian/patches/bugfix/mips/MIPS-tlbex-Fix-build_restore_pagemask-KScratch-resto.patch new file mode 100644 index 000000000..822c5aa94 --- /dev/null +++ b/debian/patches/bugfix/mips/MIPS-tlbex-Fix-build_restore_pagemask-KScratch-resto.patch @@ -0,0 +1,104 @@ +From: Paul Burton +Date: Fri, 18 Oct 2019 15:38:48 -0700 +Subject: MIPS: tlbex: Fix build_restore_pagemask KScratch restore +Origin: https://git.kernel.org/linus/b42aa3fd5957e4daf4b69129e5ce752a2a53e7d6 + +build_restore_pagemask() will restore the value of register $1/$at when +its restore_scratch argument is non-zero, and aims to do so by filling a +branch delay slot. Commit 0b24cae4d535 ("MIPS: Add missing EHB in mtc0 +-> mfc0 sequence.") added an EHB instruction (Execution Hazard Barrier) +prior to restoring $1 from a KScratch register, in order to resolve a +hazard that can result in stale values of the KScratch register being +observed. In particular, P-class CPUs from MIPS with out of order +execution pipelines such as the P5600 & P6600 are affected. + +Unfortunately this EHB instruction was inserted in the branch delay slot +causing the MFC0 instruction which performs the restoration to no longer +execute along with the branch. The result is that the $1 register isn't +actually restored, ie. the TLB refill exception handler clobbers it - +which is exactly the problem the EHB is meant to avoid for the P-class +CPUs. + +Similarly build_get_pgd_vmalloc() will restore the value of $1/$at when +its mode argument equals refill_scratch, and suffers from the same +problem. + +Fix this by in both cases moving the EHB earlier in the emitted code. +There's no reason it needs to immediately precede the MFC0 - it simply +needs to be between the MTC0 & MFC0. + +This bug only affects Cavium Octeon systems which use +build_fast_tlb_refill_handler(). + +Signed-off-by: Paul Burton +Fixes: 0b24cae4d535 ("MIPS: Add missing EHB in mtc0 -> mfc0 sequence.") +Cc: Dmitry Korotin +Cc: stable@vger.kernel.org # v3.15+ +Cc: linux-mips@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +--- + arch/mips/mm/tlbex.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c +index e01cb33bfa1a..41bb91f05688 100644 +--- a/arch/mips/mm/tlbex.c ++++ b/arch/mips/mm/tlbex.c +@@ -653,6 +653,13 @@ static void build_restore_pagemask(u32 **p, struct uasm_reloc **r, + int restore_scratch) + { + if (restore_scratch) { ++ /* ++ * Ensure the MFC0 below observes the value written to the ++ * KScratch register by the prior MTC0. ++ */ ++ if (scratch_reg >= 0) ++ uasm_i_ehb(p); ++ + /* Reset default page size */ + if (PM_DEFAULT_MASK >> 16) { + uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16); +@@ -667,12 +674,10 @@ static void build_restore_pagemask(u32 **p, struct uasm_reloc **r, + uasm_i_mtc0(p, 0, C0_PAGEMASK); + uasm_il_b(p, r, lid); + } +- if (scratch_reg >= 0) { +- uasm_i_ehb(p); ++ if (scratch_reg >= 0) + UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg); +- } else { ++ else + UASM_i_LW(p, 1, scratchpad_offset(0), 0); +- } + } else { + /* Reset default page size */ + if (PM_DEFAULT_MASK >> 16) { +@@ -921,6 +926,10 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, + } + if (mode != not_refill && check_for_high_segbits) { + uasm_l_large_segbits_fault(l, *p); ++ ++ if (mode == refill_scratch && scratch_reg >= 0) ++ uasm_i_ehb(p); ++ + /* + * We get here if we are an xsseg address, or if we are + * an xuseg address above (PGDIR_SHIFT+PGDIR_BITS) boundary. +@@ -939,12 +948,10 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, + uasm_i_jr(p, ptr); + + if (mode == refill_scratch) { +- if (scratch_reg >= 0) { +- uasm_i_ehb(p); ++ if (scratch_reg >= 0) + UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg); +- } else { ++ else + UASM_i_LW(p, 1, scratchpad_offset(0), 0); +- } + } else { + uasm_i_nop(p); + } +-- +2.24.0 + diff --git a/debian/patches/series b/debian/patches/series index 3f2ff81f2..9cb598a32 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -81,6 +81,7 @@ bugfix/arm/ARM-dts-sun8i-h3-add-sy8106a-to-orange-pi-plus.patch bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch bugfix/powerpc/powerpc-vdso-make-vdso32-installation-conditional-in.patch +bugfix/mips/MIPS-tlbex-Fix-build_restore_pagemask-KScratch-resto.patch # Arch features features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch