Contents of /trunk/kernel-alx/patches-5.4/0162-5.4.63-all-fixes.patch
Parent Directory | Revision Log
Revision 3624 -
(show annotations)
(download)
Mon Sep 7 06:16:14 2020 UTC (3 years, 9 months ago) by niro
File size: 31978 byte(s)
Mon Sep 7 06:16:14 2020 UTC (3 years, 9 months ago) by niro
File size: 31978 byte(s)
-linux-5.4.63
1 | diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt |
2 | index 2cf3affa1be70..96c0b1440c9c5 100644 |
3 | --- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt |
4 | +++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt |
5 | @@ -15,8 +15,15 @@ Required properties: |
6 | - "nvidia,tegra210-sdhci": for Tegra210 |
7 | - "nvidia,tegra186-sdhci": for Tegra186 |
8 | - "nvidia,tegra194-sdhci": for Tegra194 |
9 | -- clocks : Must contain one entry, for the module clock. |
10 | - See ../clocks/clock-bindings.txt for details. |
11 | +- clocks: For Tegra210, Tegra186 and Tegra194 must contain two entries. |
12 | + One for the module clock and one for the timeout clock. |
13 | + For all other Tegra devices, must contain a single entry for |
14 | + the module clock. See ../clocks/clock-bindings.txt for details. |
15 | +- clock-names: For Tegra210, Tegra186 and Tegra194 must contain the |
16 | + strings 'sdhci' and 'tmclk' to represent the module and |
17 | + the timeout clocks, respectively. |
18 | + For all other Tegra devices must contain the string 'sdhci' |
19 | + to represent the module clock. |
20 | - resets : Must contain an entry for each entry in reset-names. |
21 | See ../reset/reset.txt for details. |
22 | - reset-names : Must include the following entries: |
23 | @@ -99,7 +106,7 @@ Optional properties for Tegra210, Tegra186 and Tegra194: |
24 | |
25 | Example: |
26 | sdhci@700b0000 { |
27 | - compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; |
28 | + compatible = "nvidia,tegra124-sdhci"; |
29 | reg = <0x0 0x700b0000 0x0 0x200>; |
30 | interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; |
31 | clocks = <&tegra_car TEGRA210_CLK_SDMMC1>; |
32 | @@ -115,3 +122,22 @@ sdhci@700b0000 { |
33 | nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>; |
34 | status = "disabled"; |
35 | }; |
36 | + |
37 | +sdhci@700b0000 { |
38 | + compatible = "nvidia,tegra210-sdhci"; |
39 | + reg = <0x0 0x700b0000 0x0 0x200>; |
40 | + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; |
41 | + clocks = <&tegra_car TEGRA210_CLK_SDMMC1>, |
42 | + <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; |
43 | + clock-names = "sdhci", "tmclk"; |
44 | + resets = <&tegra_car 14>; |
45 | + reset-names = "sdhci"; |
46 | + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; |
47 | + pinctrl-0 = <&sdmmc1_3v3>; |
48 | + pinctrl-1 = <&sdmmc1_1v8>; |
49 | + nvidia,pad-autocal-pull-up-offset-3v3 = <0x00>; |
50 | + nvidia,pad-autocal-pull-down-offset-3v3 = <0x7d>; |
51 | + nvidia,pad-autocal-pull-up-offset-1v8 = <0x7b>; |
52 | + nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>; |
53 | + status = "disabled"; |
54 | +}; |
55 | diff --git a/Makefile b/Makefile |
56 | index aece56450bd9d..418814b108ae6 100644 |
57 | --- a/Makefile |
58 | +++ b/Makefile |
59 | @@ -1,7 +1,7 @@ |
60 | # SPDX-License-Identifier: GPL-2.0 |
61 | VERSION = 5 |
62 | PATCHLEVEL = 4 |
63 | -SUBLEVEL = 62 |
64 | +SUBLEVEL = 63 |
65 | EXTRAVERSION = |
66 | NAME = Kleptomaniac Octopus |
67 | |
68 | diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi |
69 | index 47cd831fcf445..9abf0cb1dd67f 100644 |
70 | --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi |
71 | +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi |
72 | @@ -309,8 +309,9 @@ |
73 | compatible = "nvidia,tegra186-sdhci"; |
74 | reg = <0x0 0x03400000 0x0 0x10000>; |
75 | interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; |
76 | - clocks = <&bpmp TEGRA186_CLK_SDMMC1>; |
77 | - clock-names = "sdhci"; |
78 | + clocks = <&bpmp TEGRA186_CLK_SDMMC1>, |
79 | + <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; |
80 | + clock-names = "sdhci", "tmclk"; |
81 | resets = <&bpmp TEGRA186_RESET_SDMMC1>; |
82 | reset-names = "sdhci"; |
83 | iommus = <&smmu TEGRA186_SID_SDMMC1>; |
84 | @@ -335,8 +336,9 @@ |
85 | compatible = "nvidia,tegra186-sdhci"; |
86 | reg = <0x0 0x03420000 0x0 0x10000>; |
87 | interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>; |
88 | - clocks = <&bpmp TEGRA186_CLK_SDMMC2>; |
89 | - clock-names = "sdhci"; |
90 | + clocks = <&bpmp TEGRA186_CLK_SDMMC2>, |
91 | + <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; |
92 | + clock-names = "sdhci", "tmclk"; |
93 | resets = <&bpmp TEGRA186_RESET_SDMMC2>; |
94 | reset-names = "sdhci"; |
95 | iommus = <&smmu TEGRA186_SID_SDMMC2>; |
96 | @@ -356,8 +358,9 @@ |
97 | compatible = "nvidia,tegra186-sdhci"; |
98 | reg = <0x0 0x03440000 0x0 0x10000>; |
99 | interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; |
100 | - clocks = <&bpmp TEGRA186_CLK_SDMMC3>; |
101 | - clock-names = "sdhci"; |
102 | + clocks = <&bpmp TEGRA186_CLK_SDMMC3>, |
103 | + <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; |
104 | + clock-names = "sdhci", "tmclk"; |
105 | resets = <&bpmp TEGRA186_RESET_SDMMC3>; |
106 | reset-names = "sdhci"; |
107 | iommus = <&smmu TEGRA186_SID_SDMMC3>; |
108 | @@ -379,8 +382,9 @@ |
109 | compatible = "nvidia,tegra186-sdhci"; |
110 | reg = <0x0 0x03460000 0x0 0x10000>; |
111 | interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; |
112 | - clocks = <&bpmp TEGRA186_CLK_SDMMC4>; |
113 | - clock-names = "sdhci"; |
114 | + clocks = <&bpmp TEGRA186_CLK_SDMMC4>, |
115 | + <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; |
116 | + clock-names = "sdhci", "tmclk"; |
117 | assigned-clocks = <&bpmp TEGRA186_CLK_SDMMC4>, |
118 | <&bpmp TEGRA186_CLK_PLLC4_VCO>; |
119 | assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLC4_VCO>; |
120 | diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi |
121 | index 2f3926719434a..5728255bd0c1a 100644 |
122 | --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi |
123 | +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi |
124 | @@ -403,8 +403,9 @@ |
125 | compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci"; |
126 | reg = <0x03400000 0x10000>; |
127 | interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; |
128 | - clocks = <&bpmp TEGRA194_CLK_SDMMC1>; |
129 | - clock-names = "sdhci"; |
130 | + clocks = <&bpmp TEGRA194_CLK_SDMMC1>, |
131 | + <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>; |
132 | + clock-names = "sdhci", "tmclk"; |
133 | resets = <&bpmp TEGRA194_RESET_SDMMC1>; |
134 | reset-names = "sdhci"; |
135 | nvidia,pad-autocal-pull-up-offset-3v3-timeout = |
136 | @@ -425,8 +426,9 @@ |
137 | compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci"; |
138 | reg = <0x03440000 0x10000>; |
139 | interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; |
140 | - clocks = <&bpmp TEGRA194_CLK_SDMMC3>; |
141 | - clock-names = "sdhci"; |
142 | + clocks = <&bpmp TEGRA194_CLK_SDMMC3>, |
143 | + <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>; |
144 | + clock-names = "sdhci", "tmclk"; |
145 | resets = <&bpmp TEGRA194_RESET_SDMMC3>; |
146 | reset-names = "sdhci"; |
147 | nvidia,pad-autocal-pull-up-offset-1v8 = <0x00>; |
148 | @@ -448,8 +450,9 @@ |
149 | compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci"; |
150 | reg = <0x03460000 0x10000>; |
151 | interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; |
152 | - clocks = <&bpmp TEGRA194_CLK_SDMMC4>; |
153 | - clock-names = "sdhci"; |
154 | + clocks = <&bpmp TEGRA194_CLK_SDMMC4>, |
155 | + <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>; |
156 | + clock-names = "sdhci", "tmclk"; |
157 | assigned-clocks = <&bpmp TEGRA194_CLK_SDMMC4>, |
158 | <&bpmp TEGRA194_CLK_PLLC4>; |
159 | assigned-clock-parents = |
160 | diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi |
161 | index 659753118e96f..078d2506365c0 100644 |
162 | --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi |
163 | +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi |
164 | @@ -1116,8 +1116,9 @@ |
165 | compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; |
166 | reg = <0x0 0x700b0000 0x0 0x200>; |
167 | interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; |
168 | - clocks = <&tegra_car TEGRA210_CLK_SDMMC1>; |
169 | - clock-names = "sdhci"; |
170 | + clocks = <&tegra_car TEGRA210_CLK_SDMMC1>, |
171 | + <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; |
172 | + clock-names = "sdhci", "tmclk"; |
173 | resets = <&tegra_car 14>; |
174 | reset-names = "sdhci"; |
175 | pinctrl-names = "sdmmc-3v3", "sdmmc-1v8", |
176 | @@ -1144,8 +1145,9 @@ |
177 | compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; |
178 | reg = <0x0 0x700b0200 0x0 0x200>; |
179 | interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; |
180 | - clocks = <&tegra_car TEGRA210_CLK_SDMMC2>; |
181 | - clock-names = "sdhci"; |
182 | + clocks = <&tegra_car TEGRA210_CLK_SDMMC2>, |
183 | + <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; |
184 | + clock-names = "sdhci", "tmclk"; |
185 | resets = <&tegra_car 9>; |
186 | reset-names = "sdhci"; |
187 | pinctrl-names = "sdmmc-1v8-drv"; |
188 | @@ -1161,8 +1163,9 @@ |
189 | compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; |
190 | reg = <0x0 0x700b0400 0x0 0x200>; |
191 | interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; |
192 | - clocks = <&tegra_car TEGRA210_CLK_SDMMC3>; |
193 | - clock-names = "sdhci"; |
194 | + clocks = <&tegra_car TEGRA210_CLK_SDMMC3>, |
195 | + <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; |
196 | + clock-names = "sdhci", "tmclk"; |
197 | resets = <&tegra_car 69>; |
198 | reset-names = "sdhci"; |
199 | pinctrl-names = "sdmmc-3v3", "sdmmc-1v8", |
200 | @@ -1184,8 +1187,9 @@ |
201 | compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; |
202 | reg = <0x0 0x700b0600 0x0 0x200>; |
203 | interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; |
204 | - clocks = <&tegra_car TEGRA210_CLK_SDMMC4>; |
205 | - clock-names = "sdhci"; |
206 | + clocks = <&tegra_car TEGRA210_CLK_SDMMC4>, |
207 | + <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; |
208 | + clock-names = "sdhci", "tmclk"; |
209 | resets = <&tegra_car 15>; |
210 | reset-names = "sdhci"; |
211 | pinctrl-names = "sdmmc-3v3-drv", "sdmmc-1v8-drv"; |
212 | diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h |
213 | index ddf9d762ac622..a4ffd9b55e72c 100644 |
214 | --- a/arch/arm64/include/asm/kvm_arm.h |
215 | +++ b/arch/arm64/include/asm/kvm_arm.h |
216 | @@ -72,11 +72,12 @@ |
217 | * IMO: Override CPSR.I and enable signaling with VI |
218 | * FMO: Override CPSR.F and enable signaling with VF |
219 | * SWIO: Turn set/way invalidates into set/way clean+invalidate |
220 | + * PTW: Take a stage2 fault if a stage1 walk steps in device memory |
221 | */ |
222 | #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ |
223 | HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \ |
224 | HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \ |
225 | - HCR_FMO | HCR_IMO) |
226 | + HCR_FMO | HCR_IMO | HCR_PTW ) |
227 | #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF) |
228 | #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK) |
229 | #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) |
230 | diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h |
231 | index 44a243754c1b8..64d79b2884344 100644 |
232 | --- a/arch/arm64/include/asm/kvm_asm.h |
233 | +++ b/arch/arm64/include/asm/kvm_asm.h |
234 | @@ -88,6 +88,34 @@ extern u32 __kvm_get_mdcr_el2(void); |
235 | *__hyp_this_cpu_ptr(sym); \ |
236 | }) |
237 | |
238 | +#define __KVM_EXTABLE(from, to) \ |
239 | + " .pushsection __kvm_ex_table, \"a\"\n" \ |
240 | + " .align 3\n" \ |
241 | + " .long (" #from " - .), (" #to " - .)\n" \ |
242 | + " .popsection\n" |
243 | + |
244 | + |
245 | +#define __kvm_at(at_op, addr) \ |
246 | +( { \ |
247 | + int __kvm_at_err = 0; \ |
248 | + u64 spsr, elr; \ |
249 | + asm volatile( \ |
250 | + " mrs %1, spsr_el2\n" \ |
251 | + " mrs %2, elr_el2\n" \ |
252 | + "1: at "at_op", %3\n" \ |
253 | + " isb\n" \ |
254 | + " b 9f\n" \ |
255 | + "2: msr spsr_el2, %1\n" \ |
256 | + " msr elr_el2, %2\n" \ |
257 | + " mov %w0, %4\n" \ |
258 | + "9:\n" \ |
259 | + __KVM_EXTABLE(1b, 2b) \ |
260 | + : "+r" (__kvm_at_err), "=&r" (spsr), "=&r" (elr) \ |
261 | + : "r" (addr), "i" (-EFAULT)); \ |
262 | + __kvm_at_err; \ |
263 | +} ) |
264 | + |
265 | + |
266 | #else /* __ASSEMBLY__ */ |
267 | |
268 | .macro hyp_adr_this_cpu reg, sym, tmp |
269 | @@ -113,6 +141,21 @@ extern u32 __kvm_get_mdcr_el2(void); |
270 | kern_hyp_va \vcpu |
271 | .endm |
272 | |
273 | +/* |
274 | + * KVM extable for unexpected exceptions. |
275 | + * In the same format _asm_extable, but output to a different section so that |
276 | + * it can be mapped to EL2. The KVM version is not sorted. The caller must |
277 | + * ensure: |
278 | + * x18 has the hypervisor value to allow any Shadow-Call-Stack instrumented |
279 | + * code to write to it, and that SPSR_EL2 and ELR_EL2 are restored by the fixup. |
280 | + */ |
281 | +.macro _kvm_extable, from, to |
282 | + .pushsection __kvm_ex_table, "a" |
283 | + .align 3 |
284 | + .long (\from - .), (\to - .) |
285 | + .popsection |
286 | +.endm |
287 | + |
288 | #endif |
289 | |
290 | #endif /* __ARM_KVM_ASM_H__ */ |
291 | diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S |
292 | index 8d0374ffdd2d6..4f77de8ce1384 100644 |
293 | --- a/arch/arm64/kernel/vmlinux.lds.S |
294 | +++ b/arch/arm64/kernel/vmlinux.lds.S |
295 | @@ -24,6 +24,13 @@ ENTRY(_text) |
296 | |
297 | jiffies = jiffies_64; |
298 | |
299 | + |
300 | +#define HYPERVISOR_EXTABLE \ |
301 | + . = ALIGN(SZ_8); \ |
302 | + __start___kvm_ex_table = .; \ |
303 | + *(__kvm_ex_table) \ |
304 | + __stop___kvm_ex_table = .; |
305 | + |
306 | #define HYPERVISOR_TEXT \ |
307 | /* \ |
308 | * Align to 4 KB so that \ |
309 | @@ -39,6 +46,7 @@ jiffies = jiffies_64; |
310 | __hyp_idmap_text_end = .; \ |
311 | __hyp_text_start = .; \ |
312 | *(.hyp.text) \ |
313 | + HYPERVISOR_EXTABLE \ |
314 | __hyp_text_end = .; |
315 | |
316 | #define IDMAP_TEXT \ |
317 | diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S |
318 | index e5cc8d66bf537..dc3d7bc2292fd 100644 |
319 | --- a/arch/arm64/kvm/hyp/entry.S |
320 | +++ b/arch/arm64/kvm/hyp/entry.S |
321 | @@ -173,20 +173,23 @@ alternative_endif |
322 | // This is our single instruction exception window. A pending |
323 | // SError is guaranteed to occur at the earliest when we unmask |
324 | // it, and at the latest just after the ISB. |
325 | - .global abort_guest_exit_start |
326 | abort_guest_exit_start: |
327 | |
328 | isb |
329 | |
330 | - .global abort_guest_exit_end |
331 | abort_guest_exit_end: |
332 | |
333 | msr daifset, #4 // Mask aborts |
334 | + ret |
335 | + |
336 | + _kvm_extable abort_guest_exit_start, 9997f |
337 | + _kvm_extable abort_guest_exit_end, 9997f |
338 | +9997: |
339 | + msr daifset, #4 // Mask aborts |
340 | + mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT) |
341 | |
342 | - // If the exception took place, restore the EL1 exception |
343 | - // context so that we can report some information. |
344 | - // Merge the exception code with the SError pending bit. |
345 | - tbz x0, #ARM_EXIT_WITH_SERROR_BIT, 1f |
346 | + // restore the EL1 exception context so that we can report some |
347 | + // information. Merge the exception code with the SError pending bit. |
348 | msr elr_el2, x2 |
349 | msr esr_el2, x3 |
350 | msr spsr_el2, x4 |
351 | diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S |
352 | index ffa68d5713f1d..f36aad0f207bb 100644 |
353 | --- a/arch/arm64/kvm/hyp/hyp-entry.S |
354 | +++ b/arch/arm64/kvm/hyp/hyp-entry.S |
355 | @@ -15,6 +15,30 @@ |
356 | #include <asm/kvm_mmu.h> |
357 | #include <asm/mmu.h> |
358 | |
359 | +.macro save_caller_saved_regs_vect |
360 | + /* x0 and x1 were saved in the vector entry */ |
361 | + stp x2, x3, [sp, #-16]! |
362 | + stp x4, x5, [sp, #-16]! |
363 | + stp x6, x7, [sp, #-16]! |
364 | + stp x8, x9, [sp, #-16]! |
365 | + stp x10, x11, [sp, #-16]! |
366 | + stp x12, x13, [sp, #-16]! |
367 | + stp x14, x15, [sp, #-16]! |
368 | + stp x16, x17, [sp, #-16]! |
369 | +.endm |
370 | + |
371 | +.macro restore_caller_saved_regs_vect |
372 | + ldp x16, x17, [sp], #16 |
373 | + ldp x14, x15, [sp], #16 |
374 | + ldp x12, x13, [sp], #16 |
375 | + ldp x10, x11, [sp], #16 |
376 | + ldp x8, x9, [sp], #16 |
377 | + ldp x6, x7, [sp], #16 |
378 | + ldp x4, x5, [sp], #16 |
379 | + ldp x2, x3, [sp], #16 |
380 | + ldp x0, x1, [sp], #16 |
381 | +.endm |
382 | + |
383 | .text |
384 | .pushsection .hyp.text, "ax" |
385 | |
386 | @@ -142,13 +166,19 @@ el1_error: |
387 | b __guest_exit |
388 | |
389 | el2_sync: |
390 | - /* Check for illegal exception return, otherwise panic */ |
391 | + /* Check for illegal exception return */ |
392 | mrs x0, spsr_el2 |
393 | + tbnz x0, #20, 1f |
394 | |
395 | - /* if this was something else, then panic! */ |
396 | - tst x0, #PSR_IL_BIT |
397 | - b.eq __hyp_panic |
398 | + save_caller_saved_regs_vect |
399 | + stp x29, x30, [sp, #-16]! |
400 | + bl kvm_unexpected_el2_exception |
401 | + ldp x29, x30, [sp], #16 |
402 | + restore_caller_saved_regs_vect |
403 | |
404 | + eret |
405 | + |
406 | +1: |
407 | /* Let's attempt a recovery from the illegal exception return */ |
408 | get_vcpu_ptr x1, x0 |
409 | mov x0, #ARM_EXCEPTION_IL |
410 | @@ -156,27 +186,14 @@ el2_sync: |
411 | |
412 | |
413 | el2_error: |
414 | - ldp x0, x1, [sp], #16 |
415 | + save_caller_saved_regs_vect |
416 | + stp x29, x30, [sp, #-16]! |
417 | + |
418 | + bl kvm_unexpected_el2_exception |
419 | + |
420 | + ldp x29, x30, [sp], #16 |
421 | + restore_caller_saved_regs_vect |
422 | |
423 | - /* |
424 | - * Only two possibilities: |
425 | - * 1) Either we come from the exit path, having just unmasked |
426 | - * PSTATE.A: change the return code to an EL2 fault, and |
427 | - * carry on, as we're already in a sane state to handle it. |
428 | - * 2) Or we come from anywhere else, and that's a bug: we panic. |
429 | - * |
430 | - * For (1), x0 contains the original return code and x1 doesn't |
431 | - * contain anything meaningful at that stage. We can reuse them |
432 | - * as temp registers. |
433 | - * For (2), who cares? |
434 | - */ |
435 | - mrs x0, elr_el2 |
436 | - adr x1, abort_guest_exit_start |
437 | - cmp x0, x1 |
438 | - adr x1, abort_guest_exit_end |
439 | - ccmp x0, x1, #4, ne |
440 | - b.ne __hyp_panic |
441 | - mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT) |
442 | eret |
443 | sb |
444 | |
445 | diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c |
446 | index 6f4838b475d0d..65660b6144740 100644 |
447 | --- a/arch/arm64/kvm/hyp/switch.c |
448 | +++ b/arch/arm64/kvm/hyp/switch.c |
449 | @@ -14,6 +14,7 @@ |
450 | |
451 | #include <asm/arch_gicv3.h> |
452 | #include <asm/cpufeature.h> |
453 | +#include <asm/extable.h> |
454 | #include <asm/kprobes.h> |
455 | #include <asm/kvm_asm.h> |
456 | #include <asm/kvm_emulate.h> |
457 | @@ -25,6 +26,9 @@ |
458 | #include <asm/processor.h> |
459 | #include <asm/thread_info.h> |
460 | |
461 | +extern struct exception_table_entry __start___kvm_ex_table; |
462 | +extern struct exception_table_entry __stop___kvm_ex_table; |
463 | + |
464 | /* Check whether the FP regs were dirtied while in the host-side run loop: */ |
465 | static bool __hyp_text update_fp_enabled(struct kvm_vcpu *vcpu) |
466 | { |
467 | @@ -257,10 +261,10 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar) |
468 | * saved the guest context yet, and we may return early... |
469 | */ |
470 | par = read_sysreg(par_el1); |
471 | - asm volatile("at s1e1r, %0" : : "r" (far)); |
472 | - isb(); |
473 | - |
474 | - tmp = read_sysreg(par_el1); |
475 | + if (!__kvm_at("s1e1r", far)) |
476 | + tmp = read_sysreg(par_el1); |
477 | + else |
478 | + tmp = SYS_PAR_EL1_F; /* back to the guest */ |
479 | write_sysreg(par, par_el1); |
480 | |
481 | if (unlikely(tmp & SYS_PAR_EL1_F)) |
482 | @@ -791,3 +795,30 @@ void __hyp_text __noreturn hyp_panic(struct kvm_cpu_context *host_ctxt) |
483 | |
484 | unreachable(); |
485 | } |
486 | + |
487 | +asmlinkage void __hyp_text kvm_unexpected_el2_exception(void) |
488 | +{ |
489 | + unsigned long addr, fixup; |
490 | + struct kvm_cpu_context *host_ctxt; |
491 | + struct exception_table_entry *entry, *end; |
492 | + unsigned long elr_el2 = read_sysreg(elr_el2); |
493 | + |
494 | + entry = hyp_symbol_addr(__start___kvm_ex_table); |
495 | + end = hyp_symbol_addr(__stop___kvm_ex_table); |
496 | + host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt; |
497 | + |
498 | + while (entry < end) { |
499 | + addr = (unsigned long)&entry->insn + entry->insn; |
500 | + fixup = (unsigned long)&entry->fixup + entry->fixup; |
501 | + |
502 | + if (addr != elr_el2) { |
503 | + entry++; |
504 | + continue; |
505 | + } |
506 | + |
507 | + write_sysreg(fixup, elr_el2); |
508 | + return; |
509 | + } |
510 | + |
511 | + hyp_panic(host_ctxt); |
512 | +} |
513 | diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c |
514 | index 7e4e2959bf4f7..0c9c40720ca9a 100644 |
515 | --- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c |
516 | +++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c |
517 | @@ -12,6 +12,7 @@ |
518 | |
519 | #include "common.xml.h" |
520 | #include "state.xml.h" |
521 | +#include "state_blt.xml.h" |
522 | #include "state_hi.xml.h" |
523 | #include "state_3d.xml.h" |
524 | #include "cmdstream.xml.h" |
525 | @@ -233,6 +234,8 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu) |
526 | struct etnaviv_cmdbuf *buffer = &gpu->buffer; |
527 | unsigned int waitlink_offset = buffer->user_size - 16; |
528 | u32 link_target, flush = 0; |
529 | + bool has_blt = !!(gpu->identity.minor_features5 & |
530 | + chipMinorFeatures5_BLT_ENGINE); |
531 | |
532 | lockdep_assert_held(&gpu->lock); |
533 | |
534 | @@ -248,16 +251,38 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu) |
535 | if (flush) { |
536 | unsigned int dwords = 7; |
537 | |
538 | + if (has_blt) |
539 | + dwords += 10; |
540 | + |
541 | link_target = etnaviv_buffer_reserve(gpu, buffer, dwords); |
542 | |
543 | CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); |
544 | CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); |
545 | + if (has_blt) { |
546 | + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); |
547 | + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); |
548 | + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); |
549 | + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); |
550 | + } |
551 | CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush); |
552 | - if (gpu->exec_state == ETNA_PIPE_3D) |
553 | - CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, |
554 | - VIVS_TS_FLUSH_CACHE_FLUSH); |
555 | + if (gpu->exec_state == ETNA_PIPE_3D) { |
556 | + if (has_blt) { |
557 | + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); |
558 | + CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1); |
559 | + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); |
560 | + } else { |
561 | + CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, |
562 | + VIVS_TS_FLUSH_CACHE_FLUSH); |
563 | + } |
564 | + } |
565 | CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); |
566 | CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); |
567 | + if (has_blt) { |
568 | + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); |
569 | + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); |
570 | + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); |
571 | + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); |
572 | + } |
573 | CMD_END(buffer); |
574 | |
575 | etnaviv_buffer_replace_wait(buffer, waitlink_offset, |
576 | @@ -323,6 +348,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, |
577 | bool switch_mmu_context = gpu->mmu_context != mmu_context; |
578 | unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq); |
579 | bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq; |
580 | + bool has_blt = !!(gpu->identity.minor_features5 & |
581 | + chipMinorFeatures5_BLT_ENGINE); |
582 | |
583 | lockdep_assert_held(&gpu->lock); |
584 | |
585 | @@ -433,6 +460,15 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, |
586 | * 2 semaphore stall + 1 event + 1 wait + 1 link. |
587 | */ |
588 | return_dwords = 7; |
589 | + |
590 | + /* |
591 | + * When the BLT engine is present we need 6 more dwords in the return |
592 | + * target: 3 enable/flush/disable + 4 enable/semaphore stall/disable, |
593 | + * but we don't need the normal TS flush state. |
594 | + */ |
595 | + if (has_blt) |
596 | + return_dwords += 6; |
597 | + |
598 | return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords); |
599 | CMD_LINK(cmdbuf, return_dwords, return_target); |
600 | |
601 | @@ -447,11 +483,25 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, |
602 | CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, |
603 | VIVS_GL_FLUSH_CACHE_DEPTH | |
604 | VIVS_GL_FLUSH_CACHE_COLOR); |
605 | - CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, |
606 | - VIVS_TS_FLUSH_CACHE_FLUSH); |
607 | + if (has_blt) { |
608 | + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); |
609 | + CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1); |
610 | + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); |
611 | + } else { |
612 | + CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, |
613 | + VIVS_TS_FLUSH_CACHE_FLUSH); |
614 | + } |
615 | } |
616 | CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); |
617 | CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); |
618 | + |
619 | + if (has_blt) { |
620 | + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); |
621 | + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); |
622 | + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); |
623 | + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); |
624 | + } |
625 | + |
626 | CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) | |
627 | VIVS_GL_EVENT_FROM_PE); |
628 | CMD_WAIT(buffer); |
629 | diff --git a/drivers/gpu/drm/etnaviv/state_blt.xml.h b/drivers/gpu/drm/etnaviv/state_blt.xml.h |
630 | index daae55995def0..0e8bcf9dcc93b 100644 |
631 | --- a/drivers/gpu/drm/etnaviv/state_blt.xml.h |
632 | +++ b/drivers/gpu/drm/etnaviv/state_blt.xml.h |
633 | @@ -46,6 +46,8 @@ DEALINGS IN THE SOFTWARE. |
634 | |
635 | /* This is a cut-down version of the state_blt.xml.h file */ |
636 | |
637 | +#define VIVS_BLT_SET_COMMAND 0x000140ac |
638 | + |
639 | #define VIVS_BLT_ENABLE 0x000140b8 |
640 | #define VIVS_BLT_ENABLE_ENABLE 0x00000001 |
641 | |
642 | diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c |
643 | index dfb29e6eeff1e..30c5ddd6d081c 100644 |
644 | --- a/drivers/gpu/drm/scheduler/sched_main.c |
645 | +++ b/drivers/gpu/drm/scheduler/sched_main.c |
646 | @@ -496,8 +496,10 @@ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched) |
647 | fence = sched->ops->run_job(s_job); |
648 | |
649 | if (IS_ERR_OR_NULL(fence)) { |
650 | + if (IS_ERR(fence)) |
651 | + dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); |
652 | + |
653 | s_job->s_fence->parent = NULL; |
654 | - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); |
655 | } else { |
656 | s_job->s_fence->parent = fence; |
657 | } |
658 | @@ -748,8 +750,9 @@ static int drm_sched_main(void *param) |
659 | r); |
660 | dma_fence_put(fence); |
661 | } else { |
662 | + if (IS_ERR(fence)) |
663 | + dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); |
664 | |
665 | - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); |
666 | drm_sched_process_job(NULL, &sched_job->cb); |
667 | } |
668 | |
669 | diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c |
670 | index 359616e3efbbb..d2ecc9c452554 100644 |
671 | --- a/drivers/hid/hid-core.c |
672 | +++ b/drivers/hid/hid-core.c |
673 | @@ -1597,6 +1597,17 @@ static void hid_output_field(const struct hid_device *hid, |
674 | } |
675 | } |
676 | |
677 | +/* |
678 | + * Compute the size of a report. |
679 | + */ |
680 | +static size_t hid_compute_report_size(struct hid_report *report) |
681 | +{ |
682 | + if (report->size) |
683 | + return ((report->size - 1) >> 3) + 1; |
684 | + |
685 | + return 0; |
686 | +} |
687 | + |
688 | /* |
689 | * Create a report. 'data' has to be allocated using |
690 | * hid_alloc_report_buf() so that it has proper size. |
691 | @@ -1609,7 +1620,7 @@ void hid_output_report(struct hid_report *report, __u8 *data) |
692 | if (report->id > 0) |
693 | *data++ = report->id; |
694 | |
695 | - memset(data, 0, ((report->size - 1) >> 3) + 1); |
696 | + memset(data, 0, hid_compute_report_size(report)); |
697 | for (n = 0; n < report->maxfield; n++) |
698 | hid_output_field(report->device, report->field[n], data); |
699 | } |
700 | @@ -1739,7 +1750,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, |
701 | csize--; |
702 | } |
703 | |
704 | - rsize = ((report->size - 1) >> 3) + 1; |
705 | + rsize = hid_compute_report_size(report); |
706 | |
707 | if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) |
708 | rsize = HID_MAX_BUFFER_SIZE - 1; |
709 | diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c |
710 | index e8641ce677e47..e3d475f4baf66 100644 |
711 | --- a/drivers/hid/hid-input.c |
712 | +++ b/drivers/hid/hid-input.c |
713 | @@ -1132,6 +1132,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel |
714 | } |
715 | |
716 | mapped: |
717 | + /* Mapping failed, bail out */ |
718 | + if (!bit) |
719 | + return; |
720 | + |
721 | if (device->driver->input_mapped && |
722 | device->driver->input_mapped(device, hidinput, field, usage, |
723 | &bit, &max) < 0) { |
724 | diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c |
725 | index 39e4da7468e11..128d8f4319b9f 100644 |
726 | --- a/drivers/hid/hid-multitouch.c |
727 | +++ b/drivers/hid/hid-multitouch.c |
728 | @@ -864,6 +864,8 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
729 | code = BTN_0 + ((usage->hid - 1) & HID_USAGE); |
730 | |
731 | hid_map_usage(hi, usage, bit, max, EV_KEY, code); |
732 | + if (!*bit) |
733 | + return -1; |
734 | input_set_capability(hi->input, EV_KEY, code); |
735 | return 1; |
736 | |
737 | diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c |
738 | index a25c3a4d3f6cb..e37d271ca9636 100644 |
739 | --- a/drivers/mmc/host/sdhci-tegra.c |
740 | +++ b/drivers/mmc/host/sdhci-tegra.c |
741 | @@ -1370,7 +1370,6 @@ static const struct sdhci_ops tegra210_sdhci_ops = { |
742 | |
743 | static const struct sdhci_pltfm_data sdhci_tegra210_pdata = { |
744 | .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | |
745 | - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | |
746 | SDHCI_QUIRK_SINGLE_POWER_WRITE | |
747 | SDHCI_QUIRK_NO_HISPD_BIT | |
748 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | |
749 | @@ -1407,7 +1406,6 @@ static const struct sdhci_ops tegra186_sdhci_ops = { |
750 | |
751 | static const struct sdhci_pltfm_data sdhci_tegra186_pdata = { |
752 | .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | |
753 | - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | |
754 | SDHCI_QUIRK_SINGLE_POWER_WRITE | |
755 | SDHCI_QUIRK_NO_HISPD_BIT | |
756 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | |
757 | diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c |
758 | index 8888cdf3eead9..ea925b102b322 100644 |
759 | --- a/drivers/target/target_core_user.c |
760 | +++ b/drivers/target/target_core_user.c |
761 | @@ -676,8 +676,10 @@ static void scatter_data_area(struct tcmu_dev *udev, |
762 | from = kmap_atomic(sg_page(sg)) + sg->offset; |
763 | while (sg_remaining > 0) { |
764 | if (block_remaining == 0) { |
765 | - if (to) |
766 | + if (to) { |
767 | + flush_dcache_page(page); |
768 | kunmap_atomic(to); |
769 | + } |
770 | |
771 | block_remaining = DATA_BLOCK_SIZE; |
772 | dbi = tcmu_cmd_get_dbi(tcmu_cmd); |
773 | @@ -722,7 +724,6 @@ static void scatter_data_area(struct tcmu_dev *udev, |
774 | memcpy(to + offset, |
775 | from + sg->length - sg_remaining, |
776 | copy_bytes); |
777 | - tcmu_flush_dcache_range(to, copy_bytes); |
778 | } |
779 | |
780 | sg_remaining -= copy_bytes; |
781 | @@ -731,8 +732,10 @@ static void scatter_data_area(struct tcmu_dev *udev, |
782 | kunmap_atomic(from - sg->offset); |
783 | } |
784 | |
785 | - if (to) |
786 | + if (to) { |
787 | + flush_dcache_page(page); |
788 | kunmap_atomic(to); |
789 | + } |
790 | } |
791 | |
792 | static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd, |
793 | @@ -778,13 +781,13 @@ static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd, |
794 | dbi = tcmu_cmd_get_dbi(cmd); |
795 | page = tcmu_get_block_page(udev, dbi); |
796 | from = kmap_atomic(page); |
797 | + flush_dcache_page(page); |
798 | } |
799 | copy_bytes = min_t(size_t, sg_remaining, |
800 | block_remaining); |
801 | if (read_len < copy_bytes) |
802 | copy_bytes = read_len; |
803 | offset = DATA_BLOCK_SIZE - block_remaining; |
804 | - tcmu_flush_dcache_range(from, copy_bytes); |
805 | memcpy(to + sg->length - sg_remaining, from + offset, |
806 | copy_bytes); |
807 | |
808 | @@ -1007,7 +1010,7 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) |
809 | entry->hdr.cmd_id = 0; /* not used for PAD */ |
810 | entry->hdr.kflags = 0; |
811 | entry->hdr.uflags = 0; |
812 | - tcmu_flush_dcache_range(entry, sizeof(*entry)); |
813 | + tcmu_flush_dcache_range(entry, sizeof(entry->hdr)); |
814 | |
815 | UPDATE_HEAD(mb->cmd_head, pad_size, udev->cmdr_size); |
816 | tcmu_flush_dcache_range(mb, sizeof(*mb)); |
817 | @@ -1072,7 +1075,7 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) |
818 | cdb_off = CMDR_OFF + cmd_head + base_command_size; |
819 | memcpy((void *) mb + cdb_off, se_cmd->t_task_cdb, scsi_command_size(se_cmd->t_task_cdb)); |
820 | entry->req.cdb_off = cdb_off; |
821 | - tcmu_flush_dcache_range(entry, sizeof(*entry)); |
822 | + tcmu_flush_dcache_range(entry, command_size); |
823 | |
824 | UPDATE_HEAD(mb->cmd_head, command_size, udev->cmdr_size); |
825 | tcmu_flush_dcache_range(mb, sizeof(*mb)); |
826 | diff --git a/include/linux/hid.h b/include/linux/hid.h |
827 | index 875f71132b142..c7044a14200ea 100644 |
828 | --- a/include/linux/hid.h |
829 | +++ b/include/linux/hid.h |
830 | @@ -959,34 +959,49 @@ static inline void hid_device_io_stop(struct hid_device *hid) { |
831 | * @max: maximal valid usage->code to consider later (out parameter) |
832 | * @type: input event type (EV_KEY, EV_REL, ...) |
833 | * @c: code which corresponds to this usage and type |
834 | + * |
835 | + * The value pointed to by @bit will be set to NULL if either @type is |
836 | + * an unhandled event type, or if @c is out of range for @type. This |
837 | + * can be used as an error condition. |
838 | */ |
839 | static inline void hid_map_usage(struct hid_input *hidinput, |
840 | struct hid_usage *usage, unsigned long **bit, int *max, |
841 | - __u8 type, __u16 c) |
842 | + __u8 type, unsigned int c) |
843 | { |
844 | struct input_dev *input = hidinput->input; |
845 | - |
846 | - usage->type = type; |
847 | - usage->code = c; |
848 | + unsigned long *bmap = NULL; |
849 | + unsigned int limit = 0; |
850 | |
851 | switch (type) { |
852 | case EV_ABS: |
853 | - *bit = input->absbit; |
854 | - *max = ABS_MAX; |
855 | + bmap = input->absbit; |
856 | + limit = ABS_MAX; |
857 | break; |
858 | case EV_REL: |
859 | - *bit = input->relbit; |
860 | - *max = REL_MAX; |
861 | + bmap = input->relbit; |
862 | + limit = REL_MAX; |
863 | break; |
864 | case EV_KEY: |
865 | - *bit = input->keybit; |
866 | - *max = KEY_MAX; |
867 | + bmap = input->keybit; |
868 | + limit = KEY_MAX; |
869 | break; |
870 | case EV_LED: |
871 | - *bit = input->ledbit; |
872 | - *max = LED_MAX; |
873 | + bmap = input->ledbit; |
874 | + limit = LED_MAX; |
875 | break; |
876 | } |
877 | + |
878 | + if (unlikely(c > limit || !bmap)) { |
879 | + pr_warn_ratelimited("%s: Invalid code %d type %d\n", |
880 | + input->name, c, type); |
881 | + *bit = NULL; |
882 | + return; |
883 | + } |
884 | + |
885 | + usage->type = type; |
886 | + usage->code = c; |
887 | + *max = limit; |
888 | + *bit = bmap; |
889 | } |
890 | |
891 | /** |
892 | @@ -1000,7 +1015,8 @@ static inline void hid_map_usage_clear(struct hid_input *hidinput, |
893 | __u8 type, __u16 c) |
894 | { |
895 | hid_map_usage(hidinput, usage, bit, max, type, c); |
896 | - clear_bit(c, *bit); |
897 | + if (*bit) |
898 | + clear_bit(usage->code, *bit); |
899 | } |
900 | |
901 | /** |
902 | diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt |
903 | index c6f9f31b60398..15fd108afbe63 100644 |
904 | --- a/tools/perf/Documentation/perf-record.txt |
905 | +++ b/tools/perf/Documentation/perf-record.txt |
906 | @@ -33,6 +33,10 @@ OPTIONS |
907 | - a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a |
908 | hexadecimal event descriptor. |
909 | |
910 | + - a symbolic or raw PMU event followed by an optional colon |
911 | + and a list of event modifiers, e.g., cpu-cycles:p. See the |
912 | + linkperf:perf-list[1] man page for details on event modifiers. |
913 | + |
914 | - a symbolically formed PMU event like 'pmu/param1=0x3,param2/' where |
915 | 'param1', 'param2', etc are defined as formats for the PMU in |
916 | /sys/bus/event_source/devices/<pmu>/format/*. |
917 | diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt |
918 | index 930c51c01201a..9abf1cf217e28 100644 |
919 | --- a/tools/perf/Documentation/perf-stat.txt |
920 | +++ b/tools/perf/Documentation/perf-stat.txt |
921 | @@ -39,6 +39,10 @@ report:: |
922 | - a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a |
923 | hexadecimal event descriptor. |
924 | |
925 | + - a symbolic or raw PMU event followed by an optional colon |
926 | + and a list of event modifiers, e.g., cpu-cycles:p. See the |
927 | + linkperf:perf-list[1] man page for details on event modifiers. |
928 | + |
929 | - a symbolically formed event like 'pmu/param1=0x3,param2/' where |
930 | param1 and param2 are defined as formats for the PMU in |
931 | /sys/bus/event_source/devices/<pmu>/format/* |