diff options
author | 2020-09-05 06:47:34 -0400 | |
---|---|---|
committer | 2020-09-05 06:47:34 -0400 | |
commit | 09b9eacc5ccd529e35e950d1236d2e24afb864d2 (patch) | |
tree | 52b8019267ac47f7838cb26ccf18a16e2bbb5e36 | |
parent | Linux patch 5.4.62 (diff) | |
download | linux-patches-09b9eacc5ccd529e35e950d1236d2e24afb864d2.tar.gz linux-patches-09b9eacc5ccd529e35e950d1236d2e24afb864d2.tar.bz2 linux-patches-09b9eacc5ccd529e35e950d1236d2e24afb864d2.zip |
Linux patch 5.4.635.4-64
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1062_linux-5.4.63.patch | 931 |
2 files changed, 935 insertions, 0 deletions
diff --git a/0000_README b/0000_README index edfdae1d..ddaf5438 100644 --- a/0000_README +++ b/0000_README @@ -291,6 +291,10 @@ Patch: 1061_linux-5.4.62.patch From: http://www.kernel.org Desc: Linux 5.4.62 +Patch: 1062_linux-5.4.63.patch +From: http://www.kernel.org +Desc: Linux 5.4.63 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1062_linux-5.4.63.patch b/1062_linux-5.4.63.patch new file mode 100644 index 00000000..bcca67e6 --- /dev/null +++ b/1062_linux-5.4.63.patch @@ -0,0 +1,931 @@ +diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt +index 2cf3affa1be70..96c0b1440c9c5 100644 +--- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt ++++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt +@@ -15,8 +15,15 @@ Required properties: + - "nvidia,tegra210-sdhci": for Tegra210 + - "nvidia,tegra186-sdhci": for Tegra186 + - "nvidia,tegra194-sdhci": for Tegra194 +-- clocks : Must contain one entry, for the module clock. +- See ../clocks/clock-bindings.txt for details. ++- clocks: For Tegra210, Tegra186 and Tegra194 must contain two entries. ++ One for the module clock and one for the timeout clock. ++ For all other Tegra devices, must contain a single entry for ++ the module clock. See ../clocks/clock-bindings.txt for details. ++- clock-names: For Tegra210, Tegra186 and Tegra194 must contain the ++ strings 'sdhci' and 'tmclk' to represent the module and ++ the timeout clocks, respectively. ++ For all other Tegra devices must contain the string 'sdhci' ++ to represent the module clock. + - resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names : Must include the following entries: +@@ -99,7 +106,7 @@ Optional properties for Tegra210, Tegra186 and Tegra194: + + Example: + sdhci@700b0000 { +- compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; ++ compatible = "nvidia,tegra124-sdhci"; + reg = <0x0 0x700b0000 0x0 0x200>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&tegra_car TEGRA210_CLK_SDMMC1>; +@@ -115,3 +122,22 @@ sdhci@700b0000 { + nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>; + status = "disabled"; + }; ++ ++sdhci@700b0000 { ++ compatible = "nvidia,tegra210-sdhci"; ++ reg = <0x0 0x700b0000 0x0 0x200>; ++ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&tegra_car TEGRA210_CLK_SDMMC1>, ++ <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; ++ clock-names = "sdhci", "tmclk"; ++ resets = <&tegra_car 14>; ++ reset-names = "sdhci"; ++ pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; ++ pinctrl-0 = <&sdmmc1_3v3>; ++ pinctrl-1 = <&sdmmc1_1v8>; ++ nvidia,pad-autocal-pull-up-offset-3v3 = <0x00>; ++ nvidia,pad-autocal-pull-down-offset-3v3 = <0x7d>; ++ nvidia,pad-autocal-pull-up-offset-1v8 = <0x7b>; ++ nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>; ++ status = "disabled"; ++}; +diff --git a/Makefile b/Makefile +index aece56450bd9d..418814b108ae6 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 62 ++SUBLEVEL = 63 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi +index 47cd831fcf445..9abf0cb1dd67f 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi +@@ -309,8 +309,9 @@ + compatible = "nvidia,tegra186-sdhci"; + reg = <0x0 0x03400000 0x0 0x10000>; + interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&bpmp TEGRA186_CLK_SDMMC1>; +- clock-names = "sdhci"; ++ clocks = <&bpmp TEGRA186_CLK_SDMMC1>, ++ <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; ++ clock-names = "sdhci", "tmclk"; + resets = <&bpmp TEGRA186_RESET_SDMMC1>; + reset-names = "sdhci"; + iommus = <&smmu TEGRA186_SID_SDMMC1>; +@@ -335,8 +336,9 @@ + compatible = "nvidia,tegra186-sdhci"; + reg = <0x0 0x03420000 0x0 0x10000>; + interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&bpmp TEGRA186_CLK_SDMMC2>; +- clock-names = "sdhci"; ++ clocks = <&bpmp TEGRA186_CLK_SDMMC2>, ++ <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; ++ clock-names = "sdhci", "tmclk"; + resets = <&bpmp TEGRA186_RESET_SDMMC2>; + reset-names = "sdhci"; + iommus = <&smmu TEGRA186_SID_SDMMC2>; +@@ -356,8 +358,9 @@ + compatible = "nvidia,tegra186-sdhci"; + reg = <0x0 0x03440000 0x0 0x10000>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&bpmp TEGRA186_CLK_SDMMC3>; +- clock-names = "sdhci"; ++ clocks = <&bpmp TEGRA186_CLK_SDMMC3>, ++ <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; ++ clock-names = "sdhci", "tmclk"; + resets = <&bpmp TEGRA186_RESET_SDMMC3>; + reset-names = "sdhci"; + iommus = <&smmu TEGRA186_SID_SDMMC3>; +@@ -379,8 +382,9 @@ + compatible = "nvidia,tegra186-sdhci"; + reg = <0x0 0x03460000 0x0 0x10000>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&bpmp TEGRA186_CLK_SDMMC4>; +- clock-names = "sdhci"; ++ clocks = <&bpmp TEGRA186_CLK_SDMMC4>, ++ <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; ++ clock-names = "sdhci", "tmclk"; + assigned-clocks = <&bpmp TEGRA186_CLK_SDMMC4>, + <&bpmp TEGRA186_CLK_PLLC4_VCO>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLC4_VCO>; +diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi +index 2f3926719434a..5728255bd0c1a 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi +@@ -403,8 +403,9 @@ + compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci"; + reg = <0x03400000 0x10000>; + interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&bpmp TEGRA194_CLK_SDMMC1>; +- clock-names = "sdhci"; ++ clocks = <&bpmp TEGRA194_CLK_SDMMC1>, ++ <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>; ++ clock-names = "sdhci", "tmclk"; + resets = <&bpmp TEGRA194_RESET_SDMMC1>; + reset-names = "sdhci"; + nvidia,pad-autocal-pull-up-offset-3v3-timeout = +@@ -425,8 +426,9 @@ + compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci"; + reg = <0x03440000 0x10000>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&bpmp TEGRA194_CLK_SDMMC3>; +- clock-names = "sdhci"; ++ clocks = <&bpmp TEGRA194_CLK_SDMMC3>, ++ <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>; ++ clock-names = "sdhci", "tmclk"; + resets = <&bpmp TEGRA194_RESET_SDMMC3>; + reset-names = "sdhci"; + nvidia,pad-autocal-pull-up-offset-1v8 = <0x00>; +@@ -448,8 +450,9 @@ + compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci"; + reg = <0x03460000 0x10000>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&bpmp TEGRA194_CLK_SDMMC4>; +- clock-names = "sdhci"; ++ clocks = <&bpmp TEGRA194_CLK_SDMMC4>, ++ <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>; ++ clock-names = "sdhci", "tmclk"; + assigned-clocks = <&bpmp TEGRA194_CLK_SDMMC4>, + <&bpmp TEGRA194_CLK_PLLC4>; + assigned-clock-parents = +diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi +index 659753118e96f..078d2506365c0 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi +@@ -1116,8 +1116,9 @@ + compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; + reg = <0x0 0x700b0000 0x0 0x200>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&tegra_car TEGRA210_CLK_SDMMC1>; +- clock-names = "sdhci"; ++ clocks = <&tegra_car TEGRA210_CLK_SDMMC1>, ++ <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; ++ clock-names = "sdhci", "tmclk"; + resets = <&tegra_car 14>; + reset-names = "sdhci"; + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8", +@@ -1144,8 +1145,9 @@ + compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; + reg = <0x0 0x700b0200 0x0 0x200>; + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&tegra_car TEGRA210_CLK_SDMMC2>; +- clock-names = "sdhci"; ++ clocks = <&tegra_car TEGRA210_CLK_SDMMC2>, ++ <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; ++ clock-names = "sdhci", "tmclk"; + resets = <&tegra_car 9>; + reset-names = "sdhci"; + pinctrl-names = "sdmmc-1v8-drv"; +@@ -1161,8 +1163,9 @@ + compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; + reg = <0x0 0x700b0400 0x0 0x200>; + interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&tegra_car TEGRA210_CLK_SDMMC3>; +- clock-names = "sdhci"; ++ clocks = <&tegra_car TEGRA210_CLK_SDMMC3>, ++ <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; ++ clock-names = "sdhci", "tmclk"; + resets = <&tegra_car 69>; + reset-names = "sdhci"; + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8", +@@ -1184,8 +1187,9 @@ + compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; + reg = <0x0 0x700b0600 0x0 0x200>; + interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&tegra_car TEGRA210_CLK_SDMMC4>; +- clock-names = "sdhci"; ++ clocks = <&tegra_car TEGRA210_CLK_SDMMC4>, ++ <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; ++ clock-names = "sdhci", "tmclk"; + resets = <&tegra_car 15>; + reset-names = "sdhci"; + pinctrl-names = "sdmmc-3v3-drv", "sdmmc-1v8-drv"; +diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h +index ddf9d762ac622..a4ffd9b55e72c 100644 +--- a/arch/arm64/include/asm/kvm_arm.h ++++ b/arch/arm64/include/asm/kvm_arm.h +@@ -72,11 +72,12 @@ + * IMO: Override CPSR.I and enable signaling with VI + * FMO: Override CPSR.F and enable signaling with VF + * SWIO: Turn set/way invalidates into set/way clean+invalidate ++ * PTW: Take a stage2 fault if a stage1 walk steps in device memory + */ + #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ + HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \ + HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \ +- HCR_FMO | HCR_IMO) ++ HCR_FMO | HCR_IMO | HCR_PTW ) + #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF) + #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK) + #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) +diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h +index 44a243754c1b8..64d79b2884344 100644 +--- a/arch/arm64/include/asm/kvm_asm.h ++++ b/arch/arm64/include/asm/kvm_asm.h +@@ -88,6 +88,34 @@ extern u32 __kvm_get_mdcr_el2(void); + *__hyp_this_cpu_ptr(sym); \ + }) + ++#define __KVM_EXTABLE(from, to) \ ++ " .pushsection __kvm_ex_table, \"a\"\n" \ ++ " .align 3\n" \ ++ " .long (" #from " - .), (" #to " - .)\n" \ ++ " .popsection\n" ++ ++ ++#define __kvm_at(at_op, addr) \ ++( { \ ++ int __kvm_at_err = 0; \ ++ u64 spsr, elr; \ ++ asm volatile( \ ++ " mrs %1, spsr_el2\n" \ ++ " mrs %2, elr_el2\n" \ ++ "1: at "at_op", %3\n" \ ++ " isb\n" \ ++ " b 9f\n" \ ++ "2: msr spsr_el2, %1\n" \ ++ " msr elr_el2, %2\n" \ ++ " mov %w0, %4\n" \ ++ "9:\n" \ ++ __KVM_EXTABLE(1b, 2b) \ ++ : "+r" (__kvm_at_err), "=&r" (spsr), "=&r" (elr) \ ++ : "r" (addr), "i" (-EFAULT)); \ ++ __kvm_at_err; \ ++} ) ++ ++ + #else /* __ASSEMBLY__ */ + + .macro hyp_adr_this_cpu reg, sym, tmp +@@ -113,6 +141,21 @@ extern u32 __kvm_get_mdcr_el2(void); + kern_hyp_va \vcpu + .endm + ++/* ++ * KVM extable for unexpected exceptions. ++ * In the same format _asm_extable, but output to a different section so that ++ * it can be mapped to EL2. The KVM version is not sorted. The caller must ++ * ensure: ++ * x18 has the hypervisor value to allow any Shadow-Call-Stack instrumented ++ * code to write to it, and that SPSR_EL2 and ELR_EL2 are restored by the fixup. ++ */ ++.macro _kvm_extable, from, to ++ .pushsection __kvm_ex_table, "a" ++ .align 3 ++ .long (\from - .), (\to - .) ++ .popsection ++.endm ++ + #endif + + #endif /* __ARM_KVM_ASM_H__ */ +diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S +index 8d0374ffdd2d6..4f77de8ce1384 100644 +--- a/arch/arm64/kernel/vmlinux.lds.S ++++ b/arch/arm64/kernel/vmlinux.lds.S +@@ -24,6 +24,13 @@ ENTRY(_text) + + jiffies = jiffies_64; + ++ ++#define HYPERVISOR_EXTABLE \ ++ . = ALIGN(SZ_8); \ ++ __start___kvm_ex_table = .; \ ++ *(__kvm_ex_table) \ ++ __stop___kvm_ex_table = .; ++ + #define HYPERVISOR_TEXT \ + /* \ + * Align to 4 KB so that \ +@@ -39,6 +46,7 @@ jiffies = jiffies_64; + __hyp_idmap_text_end = .; \ + __hyp_text_start = .; \ + *(.hyp.text) \ ++ HYPERVISOR_EXTABLE \ + __hyp_text_end = .; + + #define IDMAP_TEXT \ +diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S +index e5cc8d66bf537..dc3d7bc2292fd 100644 +--- a/arch/arm64/kvm/hyp/entry.S ++++ b/arch/arm64/kvm/hyp/entry.S +@@ -173,20 +173,23 @@ alternative_endif + // This is our single instruction exception window. A pending + // SError is guaranteed to occur at the earliest when we unmask + // it, and at the latest just after the ISB. +- .global abort_guest_exit_start + abort_guest_exit_start: + + isb + +- .global abort_guest_exit_end + abort_guest_exit_end: + + msr daifset, #4 // Mask aborts ++ ret ++ ++ _kvm_extable abort_guest_exit_start, 9997f ++ _kvm_extable abort_guest_exit_end, 9997f ++9997: ++ msr daifset, #4 // Mask aborts ++ mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT) + +- // If the exception took place, restore the EL1 exception +- // context so that we can report some information. +- // Merge the exception code with the SError pending bit. +- tbz x0, #ARM_EXIT_WITH_SERROR_BIT, 1f ++ // restore the EL1 exception context so that we can report some ++ // information. Merge the exception code with the SError pending bit. + msr elr_el2, x2 + msr esr_el2, x3 + msr spsr_el2, x4 +diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S +index ffa68d5713f1d..f36aad0f207bb 100644 +--- a/arch/arm64/kvm/hyp/hyp-entry.S ++++ b/arch/arm64/kvm/hyp/hyp-entry.S +@@ -15,6 +15,30 @@ + #include <asm/kvm_mmu.h> + #include <asm/mmu.h> + ++.macro save_caller_saved_regs_vect ++ /* x0 and x1 were saved in the vector entry */ ++ stp x2, x3, [sp, #-16]! ++ stp x4, x5, [sp, #-16]! ++ stp x6, x7, [sp, #-16]! ++ stp x8, x9, [sp, #-16]! ++ stp x10, x11, [sp, #-16]! ++ stp x12, x13, [sp, #-16]! ++ stp x14, x15, [sp, #-16]! ++ stp x16, x17, [sp, #-16]! ++.endm ++ ++.macro restore_caller_saved_regs_vect ++ ldp x16, x17, [sp], #16 ++ ldp x14, x15, [sp], #16 ++ ldp x12, x13, [sp], #16 ++ ldp x10, x11, [sp], #16 ++ ldp x8, x9, [sp], #16 ++ ldp x6, x7, [sp], #16 ++ ldp x4, x5, [sp], #16 ++ ldp x2, x3, [sp], #16 ++ ldp x0, x1, [sp], #16 ++.endm ++ + .text + .pushsection .hyp.text, "ax" + +@@ -142,13 +166,19 @@ el1_error: + b __guest_exit + + el2_sync: +- /* Check for illegal exception return, otherwise panic */ ++ /* Check for illegal exception return */ + mrs x0, spsr_el2 ++ tbnz x0, #20, 1f + +- /* if this was something else, then panic! */ +- tst x0, #PSR_IL_BIT +- b.eq __hyp_panic ++ save_caller_saved_regs_vect ++ stp x29, x30, [sp, #-16]! ++ bl kvm_unexpected_el2_exception ++ ldp x29, x30, [sp], #16 ++ restore_caller_saved_regs_vect + ++ eret ++ ++1: + /* Let's attempt a recovery from the illegal exception return */ + get_vcpu_ptr x1, x0 + mov x0, #ARM_EXCEPTION_IL +@@ -156,27 +186,14 @@ el2_sync: + + + el2_error: +- ldp x0, x1, [sp], #16 ++ save_caller_saved_regs_vect ++ stp x29, x30, [sp, #-16]! ++ ++ bl kvm_unexpected_el2_exception ++ ++ ldp x29, x30, [sp], #16 ++ restore_caller_saved_regs_vect + +- /* +- * Only two possibilities: +- * 1) Either we come from the exit path, having just unmasked +- * PSTATE.A: change the return code to an EL2 fault, and +- * carry on, as we're already in a sane state to handle it. +- * 2) Or we come from anywhere else, and that's a bug: we panic. +- * +- * For (1), x0 contains the original return code and x1 doesn't +- * contain anything meaningful at that stage. We can reuse them +- * as temp registers. +- * For (2), who cares? +- */ +- mrs x0, elr_el2 +- adr x1, abort_guest_exit_start +- cmp x0, x1 +- adr x1, abort_guest_exit_end +- ccmp x0, x1, #4, ne +- b.ne __hyp_panic +- mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT) + eret + sb + +diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c +index 6f4838b475d0d..65660b6144740 100644 +--- a/arch/arm64/kvm/hyp/switch.c ++++ b/arch/arm64/kvm/hyp/switch.c +@@ -14,6 +14,7 @@ + + #include <asm/arch_gicv3.h> + #include <asm/cpufeature.h> ++#include <asm/extable.h> + #include <asm/kprobes.h> + #include <asm/kvm_asm.h> + #include <asm/kvm_emulate.h> +@@ -25,6 +26,9 @@ + #include <asm/processor.h> + #include <asm/thread_info.h> + ++extern struct exception_table_entry __start___kvm_ex_table; ++extern struct exception_table_entry __stop___kvm_ex_table; ++ + /* Check whether the FP regs were dirtied while in the host-side run loop: */ + static bool __hyp_text update_fp_enabled(struct kvm_vcpu *vcpu) + { +@@ -257,10 +261,10 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar) + * saved the guest context yet, and we may return early... + */ + par = read_sysreg(par_el1); +- asm volatile("at s1e1r, %0" : : "r" (far)); +- isb(); +- +- tmp = read_sysreg(par_el1); ++ if (!__kvm_at("s1e1r", far)) ++ tmp = read_sysreg(par_el1); ++ else ++ tmp = SYS_PAR_EL1_F; /* back to the guest */ + write_sysreg(par, par_el1); + + if (unlikely(tmp & SYS_PAR_EL1_F)) +@@ -791,3 +795,30 @@ void __hyp_text __noreturn hyp_panic(struct kvm_cpu_context *host_ctxt) + + unreachable(); + } ++ ++asmlinkage void __hyp_text kvm_unexpected_el2_exception(void) ++{ ++ unsigned long addr, fixup; ++ struct kvm_cpu_context *host_ctxt; ++ struct exception_table_entry *entry, *end; ++ unsigned long elr_el2 = read_sysreg(elr_el2); ++ ++ entry = hyp_symbol_addr(__start___kvm_ex_table); ++ end = hyp_symbol_addr(__stop___kvm_ex_table); ++ host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt; ++ ++ while (entry < end) { ++ addr = (unsigned long)&entry->insn + entry->insn; ++ fixup = (unsigned long)&entry->fixup + entry->fixup; ++ ++ if (addr != elr_el2) { ++ entry++; ++ continue; ++ } ++ ++ write_sysreg(fixup, elr_el2); ++ return; ++ } ++ ++ hyp_panic(host_ctxt); ++} +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c +index 7e4e2959bf4f7..0c9c40720ca9a 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c +@@ -12,6 +12,7 @@ + + #include "common.xml.h" + #include "state.xml.h" ++#include "state_blt.xml.h" + #include "state_hi.xml.h" + #include "state_3d.xml.h" + #include "cmdstream.xml.h" +@@ -233,6 +234,8 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu) + struct etnaviv_cmdbuf *buffer = &gpu->buffer; + unsigned int waitlink_offset = buffer->user_size - 16; + u32 link_target, flush = 0; ++ bool has_blt = !!(gpu->identity.minor_features5 & ++ chipMinorFeatures5_BLT_ENGINE); + + lockdep_assert_held(&gpu->lock); + +@@ -248,16 +251,38 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu) + if (flush) { + unsigned int dwords = 7; + ++ if (has_blt) ++ dwords += 10; ++ + link_target = etnaviv_buffer_reserve(gpu, buffer, dwords); + + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); ++ if (has_blt) { ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); ++ CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); ++ } + CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush); +- if (gpu->exec_state == ETNA_PIPE_3D) +- CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, +- VIVS_TS_FLUSH_CACHE_FLUSH); ++ if (gpu->exec_state == ETNA_PIPE_3D) { ++ if (has_blt) { ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); ++ } else { ++ CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, ++ VIVS_TS_FLUSH_CACHE_FLUSH); ++ } ++ } + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); ++ if (has_blt) { ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); ++ CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); ++ } + CMD_END(buffer); + + etnaviv_buffer_replace_wait(buffer, waitlink_offset, +@@ -323,6 +348,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, + bool switch_mmu_context = gpu->mmu_context != mmu_context; + unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq); + bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq; ++ bool has_blt = !!(gpu->identity.minor_features5 & ++ chipMinorFeatures5_BLT_ENGINE); + + lockdep_assert_held(&gpu->lock); + +@@ -433,6 +460,15 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, + * 2 semaphore stall + 1 event + 1 wait + 1 link. + */ + return_dwords = 7; ++ ++ /* ++ * When the BLT engine is present we need 6 more dwords in the return ++ * target: 3 enable/flush/disable + 4 enable/semaphore stall/disable, ++ * but we don't need the normal TS flush state. ++ */ ++ if (has_blt) ++ return_dwords += 6; ++ + return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords); + CMD_LINK(cmdbuf, return_dwords, return_target); + +@@ -447,11 +483,25 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, + CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, + VIVS_GL_FLUSH_CACHE_DEPTH | + VIVS_GL_FLUSH_CACHE_COLOR); +- CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, +- VIVS_TS_FLUSH_CACHE_FLUSH); ++ if (has_blt) { ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); ++ } else { ++ CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, ++ VIVS_TS_FLUSH_CACHE_FLUSH); ++ } + } + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); ++ ++ if (has_blt) { ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); ++ CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); ++ } ++ + CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) | + VIVS_GL_EVENT_FROM_PE); + CMD_WAIT(buffer); +diff --git a/drivers/gpu/drm/etnaviv/state_blt.xml.h b/drivers/gpu/drm/etnaviv/state_blt.xml.h +index daae55995def0..0e8bcf9dcc93b 100644 +--- a/drivers/gpu/drm/etnaviv/state_blt.xml.h ++++ b/drivers/gpu/drm/etnaviv/state_blt.xml.h +@@ -46,6 +46,8 @@ DEALINGS IN THE SOFTWARE. + + /* This is a cut-down version of the state_blt.xml.h file */ + ++#define VIVS_BLT_SET_COMMAND 0x000140ac ++ + #define VIVS_BLT_ENABLE 0x000140b8 + #define VIVS_BLT_ENABLE_ENABLE 0x00000001 + +diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c +index dfb29e6eeff1e..30c5ddd6d081c 100644 +--- a/drivers/gpu/drm/scheduler/sched_main.c ++++ b/drivers/gpu/drm/scheduler/sched_main.c +@@ -496,8 +496,10 @@ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched) + fence = sched->ops->run_job(s_job); + + if (IS_ERR_OR_NULL(fence)) { ++ if (IS_ERR(fence)) ++ dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); ++ + s_job->s_fence->parent = NULL; +- dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); + } else { + s_job->s_fence->parent = fence; + } +@@ -748,8 +750,9 @@ static int drm_sched_main(void *param) + r); + dma_fence_put(fence); + } else { ++ if (IS_ERR(fence)) ++ dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); + +- dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); + drm_sched_process_job(NULL, &sched_job->cb); + } + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 359616e3efbbb..d2ecc9c452554 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1597,6 +1597,17 @@ static void hid_output_field(const struct hid_device *hid, + } + } + ++/* ++ * Compute the size of a report. ++ */ ++static size_t hid_compute_report_size(struct hid_report *report) ++{ ++ if (report->size) ++ return ((report->size - 1) >> 3) + 1; ++ ++ return 0; ++} ++ + /* + * Create a report. 'data' has to be allocated using + * hid_alloc_report_buf() so that it has proper size. +@@ -1609,7 +1620,7 @@ void hid_output_report(struct hid_report *report, __u8 *data) + if (report->id > 0) + *data++ = report->id; + +- memset(data, 0, ((report->size - 1) >> 3) + 1); ++ memset(data, 0, hid_compute_report_size(report)); + for (n = 0; n < report->maxfield; n++) + hid_output_field(report->device, report->field[n], data); + } +@@ -1739,7 +1750,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, + csize--; + } + +- rsize = ((report->size - 1) >> 3) + 1; ++ rsize = hid_compute_report_size(report); + + if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) + rsize = HID_MAX_BUFFER_SIZE - 1; +diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c +index e8641ce677e47..e3d475f4baf66 100644 +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -1132,6 +1132,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel + } + + mapped: ++ /* Mapping failed, bail out */ ++ if (!bit) ++ return; ++ + if (device->driver->input_mapped && + device->driver->input_mapped(device, hidinput, field, usage, + &bit, &max) < 0) { +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 39e4da7468e11..128d8f4319b9f 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -864,6 +864,8 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, + code = BTN_0 + ((usage->hid - 1) & HID_USAGE); + + hid_map_usage(hi, usage, bit, max, EV_KEY, code); ++ if (!*bit) ++ return -1; + input_set_capability(hi->input, EV_KEY, code); + return 1; + +diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c +index a25c3a4d3f6cb..e37d271ca9636 100644 +--- a/drivers/mmc/host/sdhci-tegra.c ++++ b/drivers/mmc/host/sdhci-tegra.c +@@ -1370,7 +1370,6 @@ static const struct sdhci_ops tegra210_sdhci_ops = { + + static const struct sdhci_pltfm_data sdhci_tegra210_pdata = { + .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | +- SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | + SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_NO_HISPD_BIT | + SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | +@@ -1407,7 +1406,6 @@ static const struct sdhci_ops tegra186_sdhci_ops = { + + static const struct sdhci_pltfm_data sdhci_tegra186_pdata = { + .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | +- SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | + SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_NO_HISPD_BIT | + SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | +diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c +index 8888cdf3eead9..ea925b102b322 100644 +--- a/drivers/target/target_core_user.c ++++ b/drivers/target/target_core_user.c +@@ -676,8 +676,10 @@ static void scatter_data_area(struct tcmu_dev *udev, + from = kmap_atomic(sg_page(sg)) + sg->offset; + while (sg_remaining > 0) { + if (block_remaining == 0) { +- if (to) ++ if (to) { ++ flush_dcache_page(page); + kunmap_atomic(to); ++ } + + block_remaining = DATA_BLOCK_SIZE; + dbi = tcmu_cmd_get_dbi(tcmu_cmd); +@@ -722,7 +724,6 @@ static void scatter_data_area(struct tcmu_dev *udev, + memcpy(to + offset, + from + sg->length - sg_remaining, + copy_bytes); +- tcmu_flush_dcache_range(to, copy_bytes); + } + + sg_remaining -= copy_bytes; +@@ -731,8 +732,10 @@ static void scatter_data_area(struct tcmu_dev *udev, + kunmap_atomic(from - sg->offset); + } + +- if (to) ++ if (to) { ++ flush_dcache_page(page); + kunmap_atomic(to); ++ } + } + + static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd, +@@ -778,13 +781,13 @@ static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd, + dbi = tcmu_cmd_get_dbi(cmd); + page = tcmu_get_block_page(udev, dbi); + from = kmap_atomic(page); ++ flush_dcache_page(page); + } + copy_bytes = min_t(size_t, sg_remaining, + block_remaining); + if (read_len < copy_bytes) + copy_bytes = read_len; + offset = DATA_BLOCK_SIZE - block_remaining; +- tcmu_flush_dcache_range(from, copy_bytes); + memcpy(to + sg->length - sg_remaining, from + offset, + copy_bytes); + +@@ -1007,7 +1010,7 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) + entry->hdr.cmd_id = 0; /* not used for PAD */ + entry->hdr.kflags = 0; + entry->hdr.uflags = 0; +- tcmu_flush_dcache_range(entry, sizeof(*entry)); ++ tcmu_flush_dcache_range(entry, sizeof(entry->hdr)); + + UPDATE_HEAD(mb->cmd_head, pad_size, udev->cmdr_size); + tcmu_flush_dcache_range(mb, sizeof(*mb)); +@@ -1072,7 +1075,7 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) + cdb_off = CMDR_OFF + cmd_head + base_command_size; + memcpy((void *) mb + cdb_off, se_cmd->t_task_cdb, scsi_command_size(se_cmd->t_task_cdb)); + entry->req.cdb_off = cdb_off; +- tcmu_flush_dcache_range(entry, sizeof(*entry)); ++ tcmu_flush_dcache_range(entry, command_size); + + UPDATE_HEAD(mb->cmd_head, command_size, udev->cmdr_size); + tcmu_flush_dcache_range(mb, sizeof(*mb)); +diff --git a/include/linux/hid.h b/include/linux/hid.h +index 875f71132b142..c7044a14200ea 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -959,34 +959,49 @@ static inline void hid_device_io_stop(struct hid_device *hid) { + * @max: maximal valid usage->code to consider later (out parameter) + * @type: input event type (EV_KEY, EV_REL, ...) + * @c: code which corresponds to this usage and type ++ * ++ * The value pointed to by @bit will be set to NULL if either @type is ++ * an unhandled event type, or if @c is out of range for @type. This ++ * can be used as an error condition. + */ + static inline void hid_map_usage(struct hid_input *hidinput, + struct hid_usage *usage, unsigned long **bit, int *max, +- __u8 type, __u16 c) ++ __u8 type, unsigned int c) + { + struct input_dev *input = hidinput->input; +- +- usage->type = type; +- usage->code = c; ++ unsigned long *bmap = NULL; ++ unsigned int limit = 0; + + switch (type) { + case EV_ABS: +- *bit = input->absbit; +- *max = ABS_MAX; ++ bmap = input->absbit; ++ limit = ABS_MAX; + break; + case EV_REL: +- *bit = input->relbit; +- *max = REL_MAX; ++ bmap = input->relbit; ++ limit = REL_MAX; + break; + case EV_KEY: +- *bit = input->keybit; +- *max = KEY_MAX; ++ bmap = input->keybit; ++ limit = KEY_MAX; + break; + case EV_LED: +- *bit = input->ledbit; +- *max = LED_MAX; ++ bmap = input->ledbit; ++ limit = LED_MAX; + break; + } ++ ++ if (unlikely(c > limit || !bmap)) { ++ pr_warn_ratelimited("%s: Invalid code %d type %d\n", ++ input->name, c, type); ++ *bit = NULL; ++ return; ++ } ++ ++ usage->type = type; ++ usage->code = c; ++ *max = limit; ++ *bit = bmap; + } + + /** +@@ -1000,7 +1015,8 @@ static inline void hid_map_usage_clear(struct hid_input *hidinput, + __u8 type, __u16 c) + { + hid_map_usage(hidinput, usage, bit, max, type, c); +- clear_bit(c, *bit); ++ if (*bit) ++ clear_bit(usage->code, *bit); + } + + /** +diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt +index c6f9f31b60398..15fd108afbe63 100644 +--- a/tools/perf/Documentation/perf-record.txt ++++ b/tools/perf/Documentation/perf-record.txt +@@ -33,6 +33,10 @@ OPTIONS + - a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a + hexadecimal event descriptor. + ++ - a symbolic or raw PMU event followed by an optional colon ++ and a list of event modifiers, e.g., cpu-cycles:p. See the ++ linkperf:perf-list[1] man page for details on event modifiers. ++ + - a symbolically formed PMU event like 'pmu/param1=0x3,param2/' where + 'param1', 'param2', etc are defined as formats for the PMU in + /sys/bus/event_source/devices/<pmu>/format/*. +diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt +index 930c51c01201a..9abf1cf217e28 100644 +--- a/tools/perf/Documentation/perf-stat.txt ++++ b/tools/perf/Documentation/perf-stat.txt +@@ -39,6 +39,10 @@ report:: + - a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a + hexadecimal event descriptor. + ++ - a symbolic or raw PMU event followed by an optional colon ++ and a list of event modifiers, e.g., cpu-cycles:p. See the ++ linkperf:perf-list[1] man page for details on event modifiers. ++ + - a symbolically formed event like 'pmu/param1=0x3,param2/' where + param1 and param2 are defined as formats for the PMU in + /sys/bus/event_source/devices/<pmu>/format/* |