summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pagano <mpagano@gentoo.org>2020-09-05 06:48:26 -0400
committerMike Pagano <mpagano@gentoo.org>2020-09-05 06:48:26 -0400
commit1dd46bf348e30b3b618337b4d4cdc91feebf1b9a (patch)
treefd0829b76f3b2ffaa09e57594a646310893cb853
parentRemove incorrect patch, add correct one (diff)
downloadlinux-patches-1dd46bf3.tar.gz
linux-patches-1dd46bf3.tar.bz2
linux-patches-1dd46bf3.zip
Linux patch 5.8.75.8-10
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r--0000_README4
-rw-r--r--1006_linux-5.8.7.patch939
2 files changed, 943 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index ba2f3898..62e43d7c 100644
--- a/0000_README
+++ b/0000_README
@@ -67,6 +67,10 @@ Patch: 1005_linux-5.8.6.patch
From: http://www.kernel.org
Desc: Linux 5.8.6
+Patch: 1006_linux-5.8.7.patch
+From: http://www.kernel.org
+Desc: Linux 5.8.7
+
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/1006_linux-5.8.7.patch b/1006_linux-5.8.7.patch
new file mode 100644
index 00000000..d773b7ce
--- /dev/null
+++ b/1006_linux-5.8.7.patch
@@ -0,0 +1,939 @@
+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 5cf35650373b1..5081bd85af29f 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 8
+-SUBLEVEL = 6
++SUBLEVEL = 7
+ EXTRAVERSION =
+ NAME = Kleptomaniac Octopus
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+index 58100fb9cd8b5..93236febd327f 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+@@ -331,8 +331,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>;
+@@ -357,8 +358,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>;
+@@ -378,8 +380,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>;
+@@ -401,8 +404,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 4bc187a4eacdb..980a8500b4b27 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+@@ -453,8 +453,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 =
+@@ -475,8 +476,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>;
+@@ -498,8 +500,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 08655081f72d1..04f3a2d4990de 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+@@ -1180,8 +1180,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",
+@@ -1208,8 +1209,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";
+@@ -1225,8 +1227,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",
+@@ -1248,8 +1251,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_asm.h b/arch/arm64/include/asm/kvm_asm.h
+index 352aaebf41980..2eff49d81be2d 100644
+--- a/arch/arm64/include/asm/kvm_asm.h
++++ b/arch/arm64/include/asm/kvm_asm.h
+@@ -121,6 +121,34 @@ extern char __smccc_workaround_1_smc[__SMCCC_WORKAROUND_1_SMC_SZ];
+ *__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
+@@ -146,6 +174,21 @@ extern char __smccc_workaround_1_smc[__SMCCC_WORKAROUND_1_SMC_SZ];
+ 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 5423ffe0a9876..1417a9042d135 100644
+--- a/arch/arm64/kernel/vmlinux.lds.S
++++ b/arch/arm64/kernel/vmlinux.lds.S
+@@ -21,6 +21,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 \
+@@ -36,6 +43,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 90186cf6473e0..c2e6da3564082 100644
+--- a/arch/arm64/kvm/hyp/entry.S
++++ b/arch/arm64/kvm/hyp/entry.S
+@@ -198,20 +198,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 9c5cfb04170ee..741f7cbaeb799 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 9270b14157b55..ba225e09aaf15 100644
+--- a/arch/arm64/kvm/hyp/switch.c
++++ b/arch/arm64/kvm/hyp/switch.c
+@@ -14,6 +14,7 @@
+
+ #include <asm/barrier.h>
+ #include <asm/cpufeature.h>
++#include <asm/extable.h>
+ #include <asm/kprobes.h>
+ #include <asm/kvm_asm.h>
+ #include <asm/kvm_emulate.h>
+@@ -24,6 +25,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)
+ {
+@@ -299,10 +303,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))
+@@ -934,3 +938,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/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 3f94b4954225b..e3152155c4b85 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -856,6 +856,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/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
+index 2322f08a98be6..5e057f798a15b 100644
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -3186,14 +3186,16 @@ static int video_put_user(void __user *arg, void *parg, unsigned int cmd)
+ #ifdef CONFIG_COMPAT_32BIT_TIME
+ case VIDIOC_DQEVENT_TIME32: {
+ struct v4l2_event *ev = parg;
+- struct v4l2_event_time32 ev32 = {
+- .type = ev->type,
+- .pending = ev->pending,
+- .sequence = ev->sequence,
+- .timestamp.tv_sec = ev->timestamp.tv_sec,
+- .timestamp.tv_nsec = ev->timestamp.tv_nsec,
+- .id = ev->id,
+- };
++ struct v4l2_event_time32 ev32;
++
++ memset(&ev32, 0, sizeof(ev32));
++
++ ev32.type = ev->type;
++ ev32.pending = ev->pending;
++ ev32.sequence = ev->sequence;
++ ev32.timestamp.tv_sec = ev->timestamp.tv_sec;
++ ev32.timestamp.tv_nsec = ev->timestamp.tv_nsec;
++ ev32.id = ev->id;
+
+ memcpy(&ev32.u, &ev->u, sizeof(ev->u));
+ memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved));
+@@ -3207,21 +3209,23 @@ static int video_put_user(void __user *arg, void *parg, unsigned int cmd)
+ case VIDIOC_DQBUF_TIME32:
+ case VIDIOC_PREPARE_BUF_TIME32: {
+ struct v4l2_buffer *vb = parg;
+- struct v4l2_buffer_time32 vb32 = {
+- .index = vb->index,
+- .type = vb->type,
+- .bytesused = vb->bytesused,
+- .flags = vb->flags,
+- .field = vb->field,
+- .timestamp.tv_sec = vb->timestamp.tv_sec,
+- .timestamp.tv_usec = vb->timestamp.tv_usec,
+- .timecode = vb->timecode,
+- .sequence = vb->sequence,
+- .memory = vb->memory,
+- .m.userptr = vb->m.userptr,
+- .length = vb->length,
+- .request_fd = vb->request_fd,
+- };
++ struct v4l2_buffer_time32 vb32;
++
++ memset(&vb32, 0, sizeof(vb32));
++
++ vb32.index = vb->index;
++ vb32.type = vb->type;
++ vb32.bytesused = vb->bytesused;
++ vb32.flags = vb->flags;
++ vb32.field = vb->field;
++ vb32.timestamp.tv_sec = vb->timestamp.tv_sec;
++ vb32.timestamp.tv_usec = vb->timestamp.tv_usec;
++ vb32.timecode = vb->timecode;
++ vb32.sequence = vb->sequence;
++ vb32.memory = vb->memory;
++ vb32.m.userptr = vb->m.userptr;
++ vb32.length = vb->length;
++ vb32.request_fd = vb->request_fd;
+
+ if (copy_to_user(arg, &vb32, sizeof(vb32)))
+ return -EFAULT;
+diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
+index 3a372ab3d12e8..db1a8d1c96b36 100644
+--- a/drivers/mmc/host/sdhci-tegra.c
++++ b/drivers/mmc/host/sdhci-tegra.c
+@@ -1409,7 +1409,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 |
+@@ -1447,7 +1446,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 9ab960cc39b6f..0209bc23e631e 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);
+
+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/mm/gup.c b/mm/gup.c
+index 6f47697f8fb0b..0d8d76f10ac61 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -843,7 +843,7 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
+ goto unmap;
+ *page = pte_page(*pte);
+ }
+- if (unlikely(!try_get_page(*page))) {
++ if (unlikely(!try_grab_page(*page, gup_flags))) {
+ ret = -ENOMEM;
+ goto unmap;
+ }
+diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
+index b6aad3fc46c35..b85ce6f0c0a6f 100644
+--- a/net/netfilter/nft_set_rbtree.c
++++ b/net/netfilter/nft_set_rbtree.c
+@@ -238,21 +238,27 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
+ *
+ * b1. _ _ __>| !_ _ __| (insert end before existing start)
+ * b2. _ _ ___| !_ _ _>| (insert end after existing start)
+- * b3. _ _ ___! >|_ _ __| (insert start after existing end)
++ * b3. _ _ ___! >|_ _ __| (insert start after existing end, as a leaf)
++ * '--' no nodes falling in this range
++ * b4. >|_ _ ! (insert start before existing start)
+ *
+ * Case a3. resolves to b3.:
+ * - if the inserted start element is the leftmost, because the '0'
+ * element in the tree serves as end element
+- * - otherwise, if an existing end is found. Note that end elements are
+- * always inserted after corresponding start elements.
++ * - otherwise, if an existing end is found immediately to the left. If
++ * there are existing nodes in between, we need to further descend the
++ * tree before we can conclude the new start isn't causing an overlap
++ *
++ * or to b4., which, preceded by a3., means we already traversed one or
++ * more existing intervals entirely, from the right.
+ *
+ * For a new, rightmost pair of elements, we'll hit cases b3. and b2.,
+ * in that order.
+ *
+ * The flag is also cleared in two special cases:
+ *
+- * b4. |__ _ _!|<_ _ _ (insert start right before existing end)
+- * b5. |__ _ >|!__ _ _ (insert end right after existing start)
++ * b5. |__ _ _!|<_ _ _ (insert start right before existing end)
++ * b6. |__ _ >|!__ _ _ (insert end right after existing start)
+ *
+ * which always happen as last step and imply that no further
+ * overlapping is possible.
+@@ -272,7 +278,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
+ if (nft_rbtree_interval_start(new)) {
+ if (nft_rbtree_interval_end(rbe) &&
+ nft_set_elem_active(&rbe->ext, genmask) &&
+- !nft_set_elem_expired(&rbe->ext))
++ !nft_set_elem_expired(&rbe->ext) && !*p)
+ overlap = false;
+ } else {
+ overlap = nft_rbtree_interval_end(rbe) &&
+@@ -288,10 +294,9 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
+ nft_set_elem_active(&rbe->ext,
+ genmask) &&
+ !nft_set_elem_expired(&rbe->ext);
+- } else if (nft_rbtree_interval_end(rbe) &&
+- nft_set_elem_active(&rbe->ext, genmask) &&
++ } else if (nft_set_elem_active(&rbe->ext, genmask) &&
+ !nft_set_elem_expired(&rbe->ext)) {
+- overlap = true;
++ overlap = nft_rbtree_interval_end(rbe);
+ }
+ } else {
+ if (nft_rbtree_interval_end(rbe) &&
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 7fbca0854265a..279c87a2a523b 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -6010,7 +6010,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
+
+ if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
+ params.he_6ghz_capa =
+- nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
++ nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
+
+ if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
+ params.airtime_weight =
+diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
+index fa8a5fcd27aba..950e4ad213747 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 b029ee728a0bc..c8209467076b1 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/*
+diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c
+index c41f24b517f40..65c141ebfbbde 100644
+--- a/tools/testing/selftests/x86/test_vsyscall.c
++++ b/tools/testing/selftests/x86/test_vsyscall.c
+@@ -462,6 +462,17 @@ static int test_vsys_x(void)
+ return 0;
+ }
+
++/*
++ * Debuggers expect ptrace() to be able to peek at the vsyscall page.
++ * Use process_vm_readv() as a proxy for ptrace() to test this. We
++ * want it to work in the vsyscall=emulate case and to fail in the
++ * vsyscall=xonly case.
++ *
++ * It's worth noting that this ABI is a bit nutty. write(2) can't
++ * read from the vsyscall page on any kernel version or mode. The
++ * fact that ptrace() ever worked was a nice courtesy of old kernels,
++ * but the code to support it is fairly gross.
++ */
+ static int test_process_vm_readv(void)
+ {
+ #ifdef __x86_64__
+@@ -477,8 +488,12 @@ static int test_process_vm_readv(void)
+ remote.iov_len = 4096;
+ ret = process_vm_readv(getpid(), &local, 1, &remote, 1, 0);
+ if (ret != 4096) {
+- printf("[OK]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", ret, errno);
+- return 0;
++ /*
++ * We expect process_vm_readv() to work if and only if the
++ * vsyscall page is readable.
++ */
++ printf("[%s]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", vsyscall_map_r ? "FAIL" : "OK", ret, errno);
++ return vsyscall_map_r ? 1 : 0;
+ }
+
+ if (vsyscall_map_r) {
+@@ -488,6 +503,9 @@ static int test_process_vm_readv(void)
+ printf("[FAIL]\tIt worked but returned incorrect data\n");
+ return 1;
+ }
++ } else {
++ printf("[FAIL]\tprocess_rm_readv() succeeded, but it should have failed in this configuration\n");
++ return 1;
+ }
+ #endif
+