diff options
80 files changed, 3364 insertions, 588 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 16501334b99f..498741737055 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu | |||
@@ -340,3 +340,13 @@ Description: POWERNV CPUFreq driver's frequency throttle stats directory and | |||
340 | 'policyX/throttle_stats' directory and all the attributes are same as | 340 | 'policyX/throttle_stats' directory and all the attributes are same as |
341 | the /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats directory and | 341 | the /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats directory and |
342 | attributes which give the frequency throttle information of the chip. | 342 | attributes which give the frequency throttle information of the chip. |
343 | |||
344 | What: /sys/devices/system/cpu/cpuX/regs/ | ||
345 | /sys/devices/system/cpu/cpuX/regs/identification/ | ||
346 | /sys/devices/system/cpu/cpuX/regs/identification/midr_el1 | ||
347 | /sys/devices/system/cpu/cpuX/regs/identification/revidr_el1 | ||
348 | Date: June 2016 | ||
349 | Contact: Linux ARM Kernel Mailing list <linux-arm-kernel@lists.infradead.org> | ||
350 | Description: AArch64 CPU registers | ||
351 | 'identification' directory exposes the CPU ID registers for | ||
352 | identifying model and revision of the CPU. | ||
diff --git a/Documentation/arm64/acpi_object_usage.txt b/Documentation/arm64/acpi_object_usage.txt index a6e1a1805e51..c77010c5c1f0 100644 --- a/Documentation/arm64/acpi_object_usage.txt +++ b/Documentation/arm64/acpi_object_usage.txt | |||
@@ -13,14 +13,14 @@ For ACPI on arm64, tables also fall into the following categories: | |||
13 | 13 | ||
14 | -- Required: DSDT, FADT, GTDT, MADT, MCFG, RSDP, SPCR, XSDT | 14 | -- Required: DSDT, FADT, GTDT, MADT, MCFG, RSDP, SPCR, XSDT |
15 | 15 | ||
16 | -- Recommended: BERT, EINJ, ERST, HEST, SSDT | 16 | -- Recommended: BERT, EINJ, ERST, HEST, PCCT, SSDT |
17 | 17 | ||
18 | -- Optional: BGRT, CPEP, CSRT, DRTM, ECDT, FACS, FPDT, MCHI, MPST, | 18 | -- Optional: BGRT, CPEP, CSRT, DBG2, DRTM, ECDT, FACS, FPDT, IORT, |
19 | MSCT, RASF, SBST, SLIT, SPMI, SRAT, TCPA, TPM2, UEFI | 19 | MCHI, MPST, MSCT, NFIT, PMTT, RASF, SBST, SLIT, SPMI, SRAT, STAO, |
20 | 20 | TCPA, TPM2, UEFI, XENV | |
21 | -- Not supported: BOOT, DBG2, DBGP, DMAR, ETDT, HPET, IBFT, IVRS, | ||
22 | LPIT, MSDM, RSDT, SLIC, WAET, WDAT, WDRT, WPBT | ||
23 | 21 | ||
22 | -- Not supported: BOOT, DBGP, DMAR, ETDT, HPET, IBFT, IVRS, LPIT, | ||
23 | MSDM, OEMx, PSDT, RSDT, SLIC, WAET, WDAT, WDRT, WPBT | ||
24 | 24 | ||
25 | Table Usage for ARMv8 Linux | 25 | Table Usage for ARMv8 Linux |
26 | ----- ---------------------------------------------------------------- | 26 | ----- ---------------------------------------------------------------- |
@@ -50,7 +50,8 @@ CSRT Signature Reserved (signature == "CSRT") | |||
50 | 50 | ||
51 | DBG2 Signature Reserved (signature == "DBG2") | 51 | DBG2 Signature Reserved (signature == "DBG2") |
52 | == DeBuG port table 2 == | 52 | == DeBuG port table 2 == |
53 | Microsoft only table, will not be supported. | 53 | License has changed and should be usable. Optional if used instead |
54 | of earlycon=<device> on the command line. | ||
54 | 55 | ||
55 | DBGP Signature Reserved (signature == "DBGP") | 56 | DBGP Signature Reserved (signature == "DBGP") |
56 | == DeBuG Port table == | 57 | == DeBuG Port table == |
@@ -133,10 +134,11 @@ GTDT Section 5.2.24 (signature == "GTDT") | |||
133 | 134 | ||
134 | HEST Section 18.3.2 (signature == "HEST") | 135 | HEST Section 18.3.2 (signature == "HEST") |
135 | == Hardware Error Source Table == | 136 | == Hardware Error Source Table == |
136 | Until further error source types are defined, use only types 6 (AER | 137 | ARM-specific error sources have been defined; please use those or the |
137 | Root Port), 7 (AER Endpoint), 8 (AER Bridge), or 9 (Generic Hardware | 138 | PCI types such as type 6 (AER Root Port), 7 (AER Endpoint), or 8 (AER |
138 | Error Source). Firmware first error handling is possible if and only | 139 | Bridge), or use type 9 (Generic Hardware Error Source). Firmware first |
139 | if Trusted Firmware is being used on arm64. | 140 | error handling is possible if and only if Trusted Firmware is being |
141 | used on arm64. | ||
140 | 142 | ||
141 | Must be supplied if RAS support is provided by the platform. It | 143 | Must be supplied if RAS support is provided by the platform. It |
142 | is recommended this table be supplied. | 144 | is recommended this table be supplied. |
@@ -149,20 +151,30 @@ IBFT Signature Reserved (signature == "IBFT") | |||
149 | == iSCSI Boot Firmware Table == | 151 | == iSCSI Boot Firmware Table == |
150 | Microsoft defined table, support TBD. | 152 | Microsoft defined table, support TBD. |
151 | 153 | ||
154 | IORT Signature Reserved (signature == "IORT") | ||
155 | == Input Output Remapping Table == | ||
156 | arm64 only table, required in order to describe IO topology, SMMUs, | ||
157 | and GIC ITSs, and how those various components are connected together, | ||
158 | such as identifying which components are behind which SMMUs/ITSs. | ||
159 | This table will only be required on certain SBSA platforms (e.g., | ||
160 | when using GICv3-ITS and an SMMU); on SBSA Level 0 platforms, it | ||
161 | remains optional. | ||
162 | |||
152 | IVRS Signature Reserved (signature == "IVRS") | 163 | IVRS Signature Reserved (signature == "IVRS") |
153 | == I/O Virtualization Reporting Structure == | 164 | == I/O Virtualization Reporting Structure == |
154 | x86_64 (AMD) only table, will not be supported. | 165 | x86_64 (AMD) only table, will not be supported. |
155 | 166 | ||
156 | LPIT Signature Reserved (signature == "LPIT") | 167 | LPIT Signature Reserved (signature == "LPIT") |
157 | == Low Power Idle Table == | 168 | == Low Power Idle Table == |
158 | x86 only table as of ACPI 5.1; future versions have been adapted for | 169 | x86 only table as of ACPI 5.1; starting with ACPI 6.0, processor |
159 | use with ARM and will be recommended in order to support ACPI power | 170 | descriptions and power states on ARM platforms should use the DSDT |
160 | management. | 171 | and define processor container devices (_HID ACPI0010, Section 8.4, |
172 | and more specifically 8.4.3 and and 8.4.4). | ||
161 | 173 | ||
162 | MADT Section 5.2.12 (signature == "APIC") | 174 | MADT Section 5.2.12 (signature == "APIC") |
163 | == Multiple APIC Description Table == | 175 | == Multiple APIC Description Table == |
164 | Required for arm64. Only the GIC interrupt controller structures | 176 | Required for arm64. Only the GIC interrupt controller structures |
165 | should be used (types 0xA - 0xE). | 177 | should be used (types 0xA - 0xF). |
166 | 178 | ||
167 | MCFG Signature Reserved (signature == "MCFG") | 179 | MCFG Signature Reserved (signature == "MCFG") |
168 | == Memory-mapped ConFiGuration space == | 180 | == Memory-mapped ConFiGuration space == |
@@ -176,14 +188,38 @@ MPST Section 5.2.21 (signature == "MPST") | |||
176 | == Memory Power State Table == | 188 | == Memory Power State Table == |
177 | Optional, not currently supported. | 189 | Optional, not currently supported. |
178 | 190 | ||
191 | MSCT Section 5.2.19 (signature == "MSCT") | ||
192 | == Maximum System Characteristic Table == | ||
193 | Optional, not currently supported. | ||
194 | |||
179 | MSDM Signature Reserved (signature == "MSDM") | 195 | MSDM Signature Reserved (signature == "MSDM") |
180 | == Microsoft Data Management table == | 196 | == Microsoft Data Management table == |
181 | Microsoft only table, will not be supported. | 197 | Microsoft only table, will not be supported. |
182 | 198 | ||
183 | MSCT Section 5.2.19 (signature == "MSCT") | 199 | NFIT Section 5.2.25 (signature == "NFIT") |
184 | == Maximum System Characteristic Table == | 200 | == NVDIMM Firmware Interface Table == |
201 | Optional, not currently supported. | ||
202 | |||
203 | OEMx Signature of "OEMx" only | ||
204 | == OEM Specific Tables == | ||
205 | All tables starting with a signature of "OEM" are reserved for OEM | ||
206 | use. Since these are not meant to be of general use but are limited | ||
207 | to very specific end users, they are not recommended for use and are | ||
208 | not supported by the kernel for arm64. | ||
209 | |||
210 | PCCT Section 14.1 (signature == "PCCT) | ||
211 | == Platform Communications Channel Table == | ||
212 | Recommend for use on arm64; use of PCC is recommended when using CPPC | ||
213 | to control performance and power for platform processors. | ||
214 | |||
215 | PMTT Section 5.2.21.12 (signature == "PMTT") | ||
216 | == Platform Memory Topology Table == | ||
185 | Optional, not currently supported. | 217 | Optional, not currently supported. |
186 | 218 | ||
219 | PSDT Section 5.2.11.3 (signature == "PSDT") | ||
220 | == Persistent System Description Table == | ||
221 | Obsolete table, will not be supported. | ||
222 | |||
187 | RASF Section 5.2.20 (signature == "RASF") | 223 | RASF Section 5.2.20 (signature == "RASF") |
188 | == RAS Feature table == | 224 | == RAS Feature table == |
189 | Optional, not currently supported. | 225 | Optional, not currently supported. |
@@ -195,7 +231,7 @@ RSDP Section 5.2.5 (signature == "RSD PTR") | |||
195 | RSDT Section 5.2.7 (signature == "RSDT") | 231 | RSDT Section 5.2.7 (signature == "RSDT") |
196 | == Root System Description Table == | 232 | == Root System Description Table == |
197 | Since this table can only provide 32-bit addresses, it is deprecated | 233 | Since this table can only provide 32-bit addresses, it is deprecated |
198 | on arm64, and will not be used. | 234 | on arm64, and will not be used. If provided, it will be ignored. |
199 | 235 | ||
200 | SBST Section 5.2.14 (signature == "SBST") | 236 | SBST Section 5.2.14 (signature == "SBST") |
201 | == Smart Battery Subsystem Table == | 237 | == Smart Battery Subsystem Table == |
@@ -220,7 +256,7 @@ SPMI Signature Reserved (signature == "SPMI") | |||
220 | SRAT Section 5.2.16 (signature == "SRAT") | 256 | SRAT Section 5.2.16 (signature == "SRAT") |
221 | == System Resource Affinity Table == | 257 | == System Resource Affinity Table == |
222 | Optional, but if used, only the GICC Affinity structures are read. | 258 | Optional, but if used, only the GICC Affinity structures are read. |
223 | To support NUMA, this table is required. | 259 | To support arm64 NUMA, this table is required. |
224 | 260 | ||
225 | SSDT Section 5.2.11.2 (signature == "SSDT") | 261 | SSDT Section 5.2.11.2 (signature == "SSDT") |
226 | == Secondary System Description Table == | 262 | == Secondary System Description Table == |
@@ -235,6 +271,11 @@ SSDT Section 5.2.11.2 (signature == "SSDT") | |||
235 | These tables are optional, however. ACPI tables should contain only | 271 | These tables are optional, however. ACPI tables should contain only |
236 | one DSDT but can contain many SSDTs. | 272 | one DSDT but can contain many SSDTs. |
237 | 273 | ||
274 | STAO Signature Reserved (signature == "STAO") | ||
275 | == _STA Override table == | ||
276 | Optional, but only necessary in virtualized environments in order to | ||
277 | hide devices from guest OSs. | ||
278 | |||
238 | TCPA Signature Reserved (signature == "TCPA") | 279 | TCPA Signature Reserved (signature == "TCPA") |
239 | == Trusted Computing Platform Alliance table == | 280 | == Trusted Computing Platform Alliance table == |
240 | Optional, not currently supported, and may need changes to fully | 281 | Optional, not currently supported, and may need changes to fully |
@@ -266,6 +307,10 @@ WPBT Signature Reserved (signature == "WPBT") | |||
266 | == Windows Platform Binary Table == | 307 | == Windows Platform Binary Table == |
267 | Microsoft only table, will not be supported. | 308 | Microsoft only table, will not be supported. |
268 | 309 | ||
310 | XENV Signature Reserved (signature == "XENV") | ||
311 | == Xen project table == | ||
312 | Optional, used only by Xen at present. | ||
313 | |||
269 | XSDT Section 5.2.8 (signature == "XSDT") | 314 | XSDT Section 5.2.8 (signature == "XSDT") |
270 | == eXtended System Description Table == | 315 | == eXtended System Description Table == |
271 | Required for arm64. | 316 | Required for arm64. |
@@ -273,44 +318,46 @@ XSDT Section 5.2.8 (signature == "XSDT") | |||
273 | 318 | ||
274 | ACPI Objects | 319 | ACPI Objects |
275 | ------------ | 320 | ------------ |
276 | The expectations on individual ACPI objects are discussed in the list that | 321 | The expectations on individual ACPI objects that are likely to be used are |
277 | follows: | 322 | shown in the list that follows; any object not explicitly mentioned below |
323 | should be used as needed for a particular platform or particular subsystem, | ||
324 | such as power management or PCI. | ||
278 | 325 | ||
279 | Name Section Usage for ARMv8 Linux | 326 | Name Section Usage for ARMv8 Linux |
280 | ---- ------------ ------------------------------------------------- | 327 | ---- ------------ ------------------------------------------------- |
281 | _ADR 6.1.1 Use as needed. | 328 | _CCA 6.2.17 This method must be defined for all bus masters |
282 | 329 | on arm64 -- there are no assumptions made about | |
283 | _BBN 6.5.5 Use as needed; PCI-specific. | 330 | whether such devices are cache coherent or not. |
331 | The _CCA value is inherited by all descendants of | ||
332 | these devices so it does not need to be repeated. | ||
333 | Without _CCA on arm64, the kernel does not know what | ||
334 | to do about setting up DMA for the device. | ||
284 | 335 | ||
285 | _BDN 6.5.3 Optional; not likely to be used on arm64. | 336 | NB: this method provides default cache coherency |
337 | attributes; the presence of an SMMU can be used to | ||
338 | modify that, however. For example, a master could | ||
339 | default to non-coherent, but be made coherent with | ||
340 | the appropriate SMMU configuration (see Table 17 of | ||
341 | the IORT specification, ARM Document DEN 0049B). | ||
286 | 342 | ||
287 | _CCA 6.2.17 This method should be defined for all bus masters | 343 | _CID 6.1.2 Use as needed, see also _HID. |
288 | on arm64. While cache coherency is assumed, making | ||
289 | it explicit ensures the kernel will set up DMA as | ||
290 | it should. | ||
291 | 344 | ||
292 | _CDM 6.2.1 Optional, to be used only for processor devices. | 345 | _CLS 6.1.3 Use as needed, see also _HID. |
293 | 346 | ||
294 | _CID 6.1.2 Use as needed. | 347 | _CPC 8.4.7.1 Use as needed, power management specific. CPPC is |
295 | 348 | recommended on arm64. | |
296 | _CLS 6.1.3 Use as needed. | ||
297 | 349 | ||
298 | _CRS 6.2.2 Required on arm64. | 350 | _CRS 6.2.2 Required on arm64. |
299 | 351 | ||
300 | _DCK 6.5.2 Optional; not likely to be used on arm64. | 352 | _CSD 8.4.2.2 Use as needed, used only in conjunction with _CST. |
353 | |||
354 | _CST 8.4.2.1 Low power idle states (8.4.4) are recommended instead | ||
355 | of C-states. | ||
301 | 356 | ||
302 | _DDN 6.1.4 This field can be used for a device name. However, | 357 | _DDN 6.1.4 This field can be used for a device name. However, |
303 | it is meant for DOS device names (e.g., COM1), so be | 358 | it is meant for DOS device names (e.g., COM1), so be |
304 | careful of its use across OSes. | 359 | careful of its use across OSes. |
305 | 360 | ||
306 | _DEP 6.5.8 Use as needed. | ||
307 | |||
308 | _DIS 6.2.3 Optional, for power management use. | ||
309 | |||
310 | _DLM 5.7.5 Optional. | ||
311 | |||
312 | _DMA 6.2.4 Optional. | ||
313 | |||
314 | _DSD 6.2.5 To be used with caution. If this object is used, try | 361 | _DSD 6.2.5 To be used with caution. If this object is used, try |
315 | to use it within the constraints already defined by the | 362 | to use it within the constraints already defined by the |
316 | Device Properties UUID. Only in rare circumstances | 363 | Device Properties UUID. Only in rare circumstances |
@@ -325,20 +372,10 @@ _DSD 6.2.5 To be used with caution. If this object is used, try | |||
325 | with the UEFI Forum; this may cause some iteration as | 372 | with the UEFI Forum; this may cause some iteration as |
326 | more than one OS will be registering entries. | 373 | more than one OS will be registering entries. |
327 | 374 | ||
328 | _DSM Do not use this method. It is not standardized, the | 375 | _DSM 9.1.1 Do not use this method. It is not standardized, the |
329 | return values are not well documented, and it is | 376 | return values are not well documented, and it is |
330 | currently a frequent source of error. | 377 | currently a frequent source of error. |
331 | 378 | ||
332 | _DSW 7.2.1 Use as needed; power management specific. | ||
333 | |||
334 | _EDL 6.3.1 Optional. | ||
335 | |||
336 | _EJD 6.3.2 Optional. | ||
337 | |||
338 | _EJx 6.3.3 Optional. | ||
339 | |||
340 | _FIX 6.2.7 x86 specific, not used on arm64. | ||
341 | |||
342 | \_GL 5.7.1 This object is not to be used in hardware reduced | 379 | \_GL 5.7.1 This object is not to be used in hardware reduced |
343 | mode, and therefore should not be used on arm64. | 380 | mode, and therefore should not be used on arm64. |
344 | 381 | ||
@@ -349,35 +386,22 @@ _GLK 6.5.7 This object requires a global lock be defined; there | |||
349 | \_GPE 5.3.1 This namespace is for x86 use only. Do not use it | 386 | \_GPE 5.3.1 This namespace is for x86 use only. Do not use it |
350 | on arm64. | 387 | on arm64. |
351 | 388 | ||
352 | _GSB 6.2.7 Optional. | 389 | _HID 6.1.5 This is the primary object to use in device probing, |
353 | 390 | though _CID and _CLS may also be used. | |
354 | _HID 6.1.5 Use as needed. This is the primary object to use in | ||
355 | device probing, though _CID and _CLS may also be used. | ||
356 | |||
357 | _HPP 6.2.8 Optional, PCI specific. | ||
358 | |||
359 | _HPX 6.2.9 Optional, PCI specific. | ||
360 | |||
361 | _HRV 6.1.6 Optional, use as needed to clarify device behavior; in | ||
362 | some cases, this may be easier to use than _DSD. | ||
363 | 391 | ||
364 | _INI 6.5.1 Not required, but can be useful in setting up devices | 392 | _INI 6.5.1 Not required, but can be useful in setting up devices |
365 | when UEFI leaves them in a state that may not be what | 393 | when UEFI leaves them in a state that may not be what |
366 | the driver expects before it starts probing. | 394 | the driver expects before it starts probing. |
367 | 395 | ||
368 | _IRC 7.2.15 Use as needed; power management specific. | 396 | _LPI 8.4.4.3 Recommended for use with processor definitions (_HID |
369 | 397 | ACPI0010) on arm64. See also _RDI. | |
370 | _LCK 6.3.4 Optional. | ||
371 | |||
372 | _MAT 6.2.10 Optional; see also the MADT. | ||
373 | 398 | ||
374 | _MLS 6.1.7 Optional, but highly recommended for use in | 399 | _MLS 6.1.7 Highly recommended for use in internationalization. |
375 | internationalization. | ||
376 | 400 | ||
377 | _OFF 7.1.2 It is recommended to define this method for any device | 401 | _OFF 7.2.2 It is recommended to define this method for any device |
378 | that can be turned on or off. | 402 | that can be turned on or off. |
379 | 403 | ||
380 | _ON 7.1.3 It is recommended to define this method for any device | 404 | _ON 7.2.3 It is recommended to define this method for any device |
381 | that can be turned on or off. | 405 | that can be turned on or off. |
382 | 406 | ||
383 | \_OS 5.7.3 This method will return "Linux" by default (this is | 407 | \_OS 5.7.3 This method will return "Linux" by default (this is |
@@ -398,122 +422,107 @@ _OSC 6.2.11 This method can be a global method in ACPI (i.e., | |||
398 | by the kernel community, then register it with the | 422 | by the kernel community, then register it with the |
399 | UEFI Forum. | 423 | UEFI Forum. |
400 | 424 | ||
401 | \_OSI 5.7.2 Deprecated on ARM64. Any invocation of this method | 425 | \_OSI 5.7.2 Deprecated on ARM64. As far as ACPI firmware is |
402 | will print a warning on the console and return false. | 426 | concerned, _OSI is not to be used to determine what |
403 | That is, as far as ACPI firmware is concerned, _OSI | 427 | sort of system is being used or what functionality |
404 | cannot be used to determine what sort of system is | 428 | is provided. The _OSC method is to be used instead. |
405 | being used or what functionality is provided. The | ||
406 | _OSC method is to be used instead. | ||
407 | |||
408 | _OST 6.3.5 Optional. | ||
409 | 429 | ||
410 | _PDC 8.4.1 Deprecated, do not use on arm64. | 430 | _PDC 8.4.1 Deprecated, do not use on arm64. |
411 | 431 | ||
412 | \_PIC 5.8.1 The method should not be used. On arm64, the only | 432 | \_PIC 5.8.1 The method should not be used. On arm64, the only |
413 | interrupt model available is GIC. | 433 | interrupt model available is GIC. |
414 | 434 | ||
415 | _PLD 6.1.8 Optional. | ||
416 | |||
417 | \_PR 5.3.1 This namespace is for x86 use only on legacy systems. | 435 | \_PR 5.3.1 This namespace is for x86 use only on legacy systems. |
418 | Do not use it on arm64. | 436 | Do not use it on arm64. |
419 | 437 | ||
420 | _PRS 6.2.12 Optional. | ||
421 | |||
422 | _PRT 6.2.13 Required as part of the definition of all PCI root | 438 | _PRT 6.2.13 Required as part of the definition of all PCI root |
423 | devices. | 439 | devices. |
424 | 440 | ||
425 | _PRW 7.2.13 Use as needed; power management specific. | 441 | _PRx 7.3.8-11 Use as needed; power management specific. If _PR0 is |
426 | |||
427 | _PRx 7.2.8-11 Use as needed; power management specific. If _PR0 is | ||
428 | defined, _PR3 must also be defined. | 442 | defined, _PR3 must also be defined. |
429 | 443 | ||
430 | _PSC 7.2.6 Use as needed; power management specific. | 444 | _PSx 7.3.2-5 Use as needed; power management specific. If _PS0 is |
431 | |||
432 | _PSE 7.2.7 Use as needed; power management specific. | ||
433 | |||
434 | _PSW 7.2.14 Use as needed; power management specific. | ||
435 | |||
436 | _PSx 7.2.2-5 Use as needed; power management specific. If _PS0 is | ||
437 | defined, _PS3 must also be defined. If clocks or | 445 | defined, _PS3 must also be defined. If clocks or |
438 | regulators need adjusting to be consistent with power | 446 | regulators need adjusting to be consistent with power |
439 | usage, change them in these methods. | 447 | usage, change them in these methods. |
440 | 448 | ||
441 | \_PTS 7.3.1 Use as needed; power management specific. | 449 | _RDI 8.4.4.4 Recommended for use with processor definitions (_HID |
442 | 450 | ACPI0010) on arm64. This should only be used in | |
443 | _PXM 6.2.14 Optional. | 451 | conjunction with _LPI. |
444 | |||
445 | _REG 6.5.4 Use as needed. | ||
446 | 452 | ||
447 | \_REV 5.7.4 Always returns the latest version of ACPI supported. | 453 | \_REV 5.7.4 Always returns the latest version of ACPI supported. |
448 | 454 | ||
449 | _RMV 6.3.6 Optional. | ||
450 | |||
451 | \_SB 5.3.1 Required on arm64; all devices must be defined in this | 455 | \_SB 5.3.1 Required on arm64; all devices must be defined in this |
452 | namespace. | 456 | namespace. |
453 | 457 | ||
454 | _SEG 6.5.6 Use as needed; PCI-specific. | 458 | _SLI 6.2.15 Use is recommended when SLIT table is in use. |
455 | |||
456 | \_SI 5.3.1, Optional. | ||
457 | 9.1 | ||
458 | |||
459 | _SLI 6.2.15 Optional; recommended when SLIT table is in use. | ||
460 | 459 | ||
461 | _STA 6.3.7, It is recommended to define this method for any device | 460 | _STA 6.3.7, It is recommended to define this method for any device |
462 | 7.1.4 that can be turned on or off. | 461 | 7.2.4 that can be turned on or off. See also the STAO table |
462 | that provides overrides to hide devices in virtualized | ||
463 | environments. | ||
463 | 464 | ||
464 | _SRS 6.2.16 Optional; see also _PRS. | 465 | _SRS 6.2.16 Use as needed; see also _PRS. |
465 | 466 | ||
466 | _STR 6.1.10 Recommended for conveying device names to end users; | 467 | _STR 6.1.10 Recommended for conveying device names to end users; |
467 | this is preferred over using _DDN. | 468 | this is preferred over using _DDN. |
468 | 469 | ||
469 | _SUB 6.1.9 Use as needed; _HID or _CID are preferred. | 470 | _SUB 6.1.9 Use as needed; _HID or _CID are preferred. |
470 | 471 | ||
471 | _SUN 6.1.11 Optional. | 472 | _SUN 6.1.11 Use as needed, but recommended. |
472 | |||
473 | \_Sx 7.3.2 Use as needed; power management specific. | ||
474 | |||
475 | _SxD 7.2.16-19 Use as needed; power management specific. | ||
476 | |||
477 | _SxW 7.2.20-24 Use as needed; power management specific. | ||
478 | 473 | ||
479 | _SWS 7.3.3 Use as needed; power management specific; this may | 474 | _SWS 7.4.3 Use as needed; power management specific; this may |
480 | require specification changes for use on arm64. | 475 | require specification changes for use on arm64. |
481 | 476 | ||
482 | \_TTS 7.3.4 Use as needed; power management specific. | ||
483 | |||
484 | \_TZ 5.3.1 Optional. | ||
485 | |||
486 | _UID 6.1.12 Recommended for distinguishing devices of the same | 477 | _UID 6.1.12 Recommended for distinguishing devices of the same |
487 | class; define it if at all possible. | 478 | class; define it if at all possible. |
488 | 479 | ||
489 | \_WAK 7.3.5 Use as needed; power management specific. | 480 | |
490 | 481 | ||
491 | 482 | ||
492 | ACPI Event Model | 483 | ACPI Event Model |
493 | ---------------- | 484 | ---------------- |
494 | Do not use GPE block devices; these are not supported in the hardware reduced | 485 | Do not use GPE block devices; these are not supported in the hardware reduced |
495 | profile used by arm64. Since there are no GPE blocks defined for use on ARM | 486 | profile used by arm64. Since there are no GPE blocks defined for use on ARM |
496 | platforms, GPIO-signaled interrupts should be used for creating system events. | 487 | platforms, ACPI events must be signaled differently. |
488 | |||
489 | There are two options: GPIO-signaled interrupts (Section 5.6.5), and | ||
490 | interrupt-signaled events (Section 5.6.9). Interrupt-signaled events are a | ||
491 | new feature in the ACPI 6.1 specification. Either -- or both -- can be used | ||
492 | on a given platform, and which to use may be dependent of limitations in any | ||
493 | given SoC. If possible, interrupt-signaled events are recommended. | ||
497 | 494 | ||
498 | 495 | ||
499 | ACPI Processor Control | 496 | ACPI Processor Control |
500 | ---------------------- | 497 | ---------------------- |
501 | Section 8 of the ACPI specification is currently undergoing change that | 498 | Section 8 of the ACPI specification changed significantly in version 6.0. |
502 | should be completed in the 6.0 version of the specification. Processor | 499 | Processors should now be defined as Device objects with _HID ACPI0007; do |
503 | performance control will be handled differently for arm64 at that point | 500 | not use the deprecated Processor statement in ASL. All multiprocessor systems |
504 | in time. Processor aggregator devices (section 8.5) will not be used, | 501 | should also define a hierarchy of processors, done with Processor Container |
505 | for example, but another similar mechanism instead. | 502 | Devices (see Section 8.4.3.1, _HID ACPI0010); do not use processor aggregator |
506 | 503 | devices (Section 8.5) to describe processor topology. Section 8.4 of the | |
507 | While UEFI constrains what we can say until the release of 6.0, it is | 504 | specification describes the semantics of these object definitions and how |
508 | recommended that CPPC (8.4.5) be used as the primary model. This will | 505 | they interrelate. |
509 | still be useful into the future. C-states and P-states will still be | 506 | |
510 | provided, but most of the current design work appears to favor CPPC. | 507 | Most importantly, the processor hierarchy defined also defines the low power |
508 | idle states that are available to the platform, along with the rules for | ||
509 | determining which processors can be turned on or off and the circumstances | ||
510 | that control that. Without this information, the processors will run in | ||
511 | whatever power state they were left in by UEFI. | ||
512 | |||
513 | Note too, that the processor Device objects defined and the entries in the | ||
514 | MADT for GICs are expected to be in synchronization. The _UID of the Device | ||
515 | object must correspond to processor IDs used in the MADT. | ||
516 | |||
517 | It is recommended that CPPC (8.4.5) be used as the primary model for processor | ||
518 | performance control on arm64. C-states and P-states may become available at | ||
519 | some point in the future, but most current design work appears to favor CPPC. | ||
511 | 520 | ||
512 | Further, it is essential that the ARMv8 SoC provide a fully functional | 521 | Further, it is essential that the ARMv8 SoC provide a fully functional |
513 | implementation of PSCI; this will be the only mechanism supported by ACPI | 522 | implementation of PSCI; this will be the only mechanism supported by ACPI |
514 | to control CPU power state (including secondary CPU booting). | 523 | to control CPU power state. Booting of secondary CPUs using the ACPI |
515 | 524 | parking protocol is possible, but discouraged, since only PSCI is supported | |
516 | More details will be provided on the release of the ACPI 6.0 specification. | 525 | for ARM servers. |
517 | 526 | ||
518 | 527 | ||
519 | ACPI System Address Map Interfaces | 528 | ACPI System Address Map Interfaces |
@@ -535,21 +544,25 @@ used to indicate fatal errors that cannot be corrected, and require immediate | |||
535 | attention. | 544 | attention. |
536 | 545 | ||
537 | Since there is no direct equivalent of the x86 SCI or NMI, arm64 handles | 546 | Since there is no direct equivalent of the x86 SCI or NMI, arm64 handles |
538 | these slightly differently. The SCI is handled as a normal GPIO-signaled | 547 | these slightly differently. The SCI is handled as a high priority interrupt; |
539 | interrupt; given that these are corrected (or correctable) errors being | 548 | given that these are corrected (or correctable) errors being reported, this |
540 | reported, this is sufficient. The NMI is emulated as the highest priority | 549 | is sufficient. The NMI is emulated as the highest priority interrupt |
541 | GPIO-signaled interrupt possible. This implies some caution must be used | 550 | possible. This implies some caution must be used since there could be |
542 | since there could be interrupts at higher privilege levels or even interrupts | 551 | interrupts at higher privilege levels or even interrupts at the same priority |
543 | at the same priority as the emulated NMI. In Linux, this should not be the | 552 | as the emulated NMI. In Linux, this should not be the case but one should |
544 | case but one should be aware it could happen. | 553 | be aware it could happen. |
545 | 554 | ||
546 | 555 | ||
547 | ACPI Objects Not Supported on ARM64 | 556 | ACPI Objects Not Supported on ARM64 |
548 | ----------------------------------- | 557 | ----------------------------------- |
549 | While this may change in the future, there are several classes of objects | 558 | While this may change in the future, there are several classes of objects |
550 | that can be defined, but are not currently of general interest to ARM servers. | 559 | that can be defined, but are not currently of general interest to ARM servers. |
560 | Some of these objects have x86 equivalents, and may actually make sense in ARM | ||
561 | servers. However, there is either no hardware available at present, or there | ||
562 | may not even be a non-ARM implementation yet. Hence, they are not currently | ||
563 | supported. | ||
551 | 564 | ||
552 | These are not supported: | 565 | The following classes of objects are not supported: |
553 | 566 | ||
554 | -- Section 9.2: ambient light sensor devices | 567 | -- Section 9.2: ambient light sensor devices |
555 | 568 | ||
@@ -571,16 +584,6 @@ These are not supported: | |||
571 | 584 | ||
572 | -- Section 9.18: time and alarm devices (see 9.15) | 585 | -- Section 9.18: time and alarm devices (see 9.15) |
573 | 586 | ||
574 | |||
575 | ACPI Objects Not Yet Implemented | ||
576 | -------------------------------- | ||
577 | While these objects have x86 equivalents, and they do make some sense in ARM | ||
578 | servers, there is either no hardware available at present, or in some cases | ||
579 | there may not yet be a non-ARM implementation. Hence, they are currently not | ||
580 | implemented though that may change in the future. | ||
581 | |||
582 | Not yet implemented are: | ||
583 | |||
584 | -- Section 10: power source and power meter devices | 587 | -- Section 10: power source and power meter devices |
585 | 588 | ||
586 | -- Section 11: thermal management | 589 | -- Section 11: thermal management |
@@ -589,5 +592,31 @@ Not yet implemented are: | |||
589 | 592 | ||
590 | -- Section 13: SMBus interfaces | 593 | -- Section 13: SMBus interfaces |
591 | 594 | ||
592 | -- Section 17: NUMA support (prototypes have been submitted for | 595 | |
593 | review) | 596 | This also means that there is no support for the following objects: |
597 | |||
598 | Name Section Name Section | ||
599 | ---- ------------ ---- ------------ | ||
600 | _ALC 9.3.4 _FDM 9.10.3 | ||
601 | _ALI 9.3.2 _FIX 6.2.7 | ||
602 | _ALP 9.3.6 _GAI 10.4.5 | ||
603 | _ALR 9.3.5 _GHL 10.4.7 | ||
604 | _ALT 9.3.3 _GTM 9.9.2.1.1 | ||
605 | _BCT 10.2.2.10 _LID 9.5.1 | ||
606 | _BDN 6.5.3 _PAI 10.4.4 | ||
607 | _BIF 10.2.2.1 _PCL 10.3.2 | ||
608 | _BIX 10.2.2.1 _PIF 10.3.3 | ||
609 | _BLT 9.2.3 _PMC 10.4.1 | ||
610 | _BMA 10.2.2.4 _PMD 10.4.8 | ||
611 | _BMC 10.2.2.12 _PMM 10.4.3 | ||
612 | _BMD 10.2.2.11 _PRL 10.3.4 | ||
613 | _BMS 10.2.2.5 _PSR 10.3.1 | ||
614 | _BST 10.2.2.6 _PTP 10.4.2 | ||
615 | _BTH 10.2.2.7 _SBS 10.1.3 | ||
616 | _BTM 10.2.2.9 _SHL 10.4.6 | ||
617 | _BTP 10.2.2.8 _STM 9.9.2.1.1 | ||
618 | _DCK 6.5.2 _UPD 9.16.1 | ||
619 | _EC 12.12 _UPP 9.16.2 | ||
620 | _FDE 9.10.1 _WPC 10.5.2 | ||
621 | _FDI 9.10.2 _WPP 10.5.3 | ||
622 | |||
diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt index 570a4f8e1a01..1a74a041a443 100644 --- a/Documentation/arm64/arm-acpi.txt +++ b/Documentation/arm64/arm-acpi.txt | |||
@@ -34,7 +34,7 @@ of the summary text almost directly, to be honest. | |||
34 | 34 | ||
35 | The short form of the rationale for ACPI on ARM is: | 35 | The short form of the rationale for ACPI on ARM is: |
36 | 36 | ||
37 | -- ACPI’s bytecode (AML) allows the platform to encode hardware behavior, | 37 | -- ACPI’s byte code (AML) allows the platform to encode hardware behavior, |
38 | while DT explicitly does not support this. For hardware vendors, being | 38 | while DT explicitly does not support this. For hardware vendors, being |
39 | able to encode behavior is a key tool used in supporting operating | 39 | able to encode behavior is a key tool used in supporting operating |
40 | system releases on new hardware. | 40 | system releases on new hardware. |
@@ -57,11 +57,11 @@ The short form of the rationale for ACPI on ARM is: | |||
57 | 57 | ||
58 | -- The new ACPI governance process works well and Linux is now at the same | 58 | -- The new ACPI governance process works well and Linux is now at the same |
59 | table as hardware vendors and other OS vendors. In fact, there is no | 59 | table as hardware vendors and other OS vendors. In fact, there is no |
60 | longer any reason to feel that ACPI is only belongs to Windows or that | 60 | longer any reason to feel that ACPI only belongs to Windows or that |
61 | Linux is in any way secondary to Microsoft in this arena. The move of | 61 | Linux is in any way secondary to Microsoft in this arena. The move of |
62 | ACPI governance into the UEFI forum has significantly opened up the | 62 | ACPI governance into the UEFI forum has significantly opened up the |
63 | specification development process, and currently, a large portion of the | 63 | specification development process, and currently, a large portion of the |
64 | changes being made to ACPI is being driven by Linux. | 64 | changes being made to ACPI are being driven by Linux. |
65 | 65 | ||
66 | Key to the use of ACPI is the support model. For servers in general, the | 66 | Key to the use of ACPI is the support model. For servers in general, the |
67 | responsibility for hardware behaviour cannot solely be the domain of the | 67 | responsibility for hardware behaviour cannot solely be the domain of the |
@@ -110,7 +110,7 @@ ACPI support in drivers and subsystems for ARMv8 should never be mutually | |||
110 | exclusive with DT support at compile time. | 110 | exclusive with DT support at compile time. |
111 | 111 | ||
112 | At boot time the kernel will only use one description method depending on | 112 | At boot time the kernel will only use one description method depending on |
113 | parameters passed from the bootloader (including kernel bootargs). | 113 | parameters passed from the boot loader (including kernel bootargs). |
114 | 114 | ||
115 | Regardless of whether DT or ACPI is used, the kernel must always be capable | 115 | Regardless of whether DT or ACPI is used, the kernel must always be capable |
116 | of booting with either scheme (in kernels with both schemes enabled at compile | 116 | of booting with either scheme (in kernels with both schemes enabled at compile |
@@ -159,7 +159,7 @@ Further, the ACPI core will only use the 64-bit address fields in the FADT | |||
159 | (Fixed ACPI Description Table). Any 32-bit address fields in the FADT will | 159 | (Fixed ACPI Description Table). Any 32-bit address fields in the FADT will |
160 | be ignored on arm64. | 160 | be ignored on arm64. |
161 | 161 | ||
162 | Hardware reduced mode (see Section 4.1 of the ACPI 5.1 specification) will | 162 | Hardware reduced mode (see Section 4.1 of the ACPI 6.1 specification) will |
163 | be enforced by the ACPI core on arm64. Doing so allows the ACPI core to | 163 | be enforced by the ACPI core on arm64. Doing so allows the ACPI core to |
164 | run less complex code since it no longer has to provide support for legacy | 164 | run less complex code since it no longer has to provide support for legacy |
165 | hardware from other architectures. Any fields that are not to be used for | 165 | hardware from other architectures. Any fields that are not to be used for |
@@ -167,7 +167,7 @@ hardware reduced mode must be set to zero. | |||
167 | 167 | ||
168 | For the ACPI core to operate properly, and in turn provide the information | 168 | For the ACPI core to operate properly, and in turn provide the information |
169 | the kernel needs to configure devices, it expects to find the following | 169 | the kernel needs to configure devices, it expects to find the following |
170 | tables (all section numbers refer to the ACPI 5.1 specfication): | 170 | tables (all section numbers refer to the ACPI 6.1 specification): |
171 | 171 | ||
172 | -- RSDP (Root System Description Pointer), section 5.2.5 | 172 | -- RSDP (Root System Description Pointer), section 5.2.5 |
173 | 173 | ||
@@ -185,9 +185,23 @@ tables (all section numbers refer to the ACPI 5.1 specfication): | |||
185 | -- If PCI is supported, the MCFG (Memory mapped ConFiGuration | 185 | -- If PCI is supported, the MCFG (Memory mapped ConFiGuration |
186 | Table), section 5.2.6, specifically Table 5-31. | 186 | Table), section 5.2.6, specifically Table 5-31. |
187 | 187 | ||
188 | -- If booting without a console=<device> kernel parameter is | ||
189 | supported, the SPCR (Serial Port Console Redirection table), | ||
190 | section 5.2.6, specifically Table 5-31. | ||
191 | |||
192 | -- If necessary to describe the I/O topology, SMMUs and GIC ITSs, | ||
193 | the IORT (Input Output Remapping Table, section 5.2.6, specifically | ||
194 | Table 5-31). | ||
195 | |||
196 | -- If NUMA is supported, the SRAT (System Resource Affinity Table) | ||
197 | and SLIT (System Locality distance Information Table), sections | ||
198 | 5.2.16 and 5.2.17, respectively. | ||
199 | |||
188 | If the above tables are not all present, the kernel may or may not be | 200 | If the above tables are not all present, the kernel may or may not be |
189 | able to boot properly since it may not be able to configure all of the | 201 | able to boot properly since it may not be able to configure all of the |
190 | devices available. | 202 | devices available. This list of tables is not meant to be all inclusive; |
203 | in some environments other tables may be needed (e.g., any of the APEI | ||
204 | tables from section 18) to support specific functionality. | ||
191 | 205 | ||
192 | 206 | ||
193 | ACPI Detection | 207 | ACPI Detection |
@@ -198,7 +212,7 @@ the device structure. This is detailed further in the "Driver | |||
198 | Recommendations" section. | 212 | Recommendations" section. |
199 | 213 | ||
200 | In non-driver code, if the presence of ACPI needs to be detected at | 214 | In non-driver code, if the presence of ACPI needs to be detected at |
201 | runtime, then check the value of acpi_disabled. If CONFIG_ACPI is not | 215 | run time, then check the value of acpi_disabled. If CONFIG_ACPI is not |
202 | set, acpi_disabled will always be 1. | 216 | set, acpi_disabled will always be 1. |
203 | 217 | ||
204 | 218 | ||
@@ -233,7 +247,7 @@ that looks like this: Name(KEY0, "value0"). An ACPI device driver would | |||
233 | then retrieve the value of the property by evaluating the KEY0 object. | 247 | then retrieve the value of the property by evaluating the KEY0 object. |
234 | However, using Name() this way has multiple problems: (1) ACPI limits | 248 | However, using Name() this way has multiple problems: (1) ACPI limits |
235 | names ("KEY0") to four characters unlike DT; (2) there is no industry | 249 | names ("KEY0") to four characters unlike DT; (2) there is no industry |
236 | wide registry that maintains a list of names, minimzing re-use; (3) | 250 | wide registry that maintains a list of names, minimizing re-use; (3) |
237 | there is also no registry for the definition of property values ("value0"), | 251 | there is also no registry for the definition of property values ("value0"), |
238 | again making re-use difficult; and (4) how does one maintain backward | 252 | again making re-use difficult; and (4) how does one maintain backward |
239 | compatibility as new hardware comes out? The _DSD method was created | 253 | compatibility as new hardware comes out? The _DSD method was created |
@@ -434,7 +448,8 @@ The ACPI specification changes regularly. During the year 2014, for instance, | |||
434 | version 5.1 was released and version 6.0 substantially completed, with most of | 448 | version 5.1 was released and version 6.0 substantially completed, with most of |
435 | the changes being driven by ARM-specific requirements. Proposed changes are | 449 | the changes being driven by ARM-specific requirements. Proposed changes are |
436 | presented and discussed in the ASWG (ACPI Specification Working Group) which | 450 | presented and discussed in the ASWG (ACPI Specification Working Group) which |
437 | is a part of the UEFI Forum. | 451 | is a part of the UEFI Forum. The current version of the ACPI specification |
452 | is 6.1 release in January 2016. | ||
438 | 453 | ||
439 | Participation in this group is open to all UEFI members. Please see | 454 | Participation in this group is open to all UEFI members. Please see |
440 | http://www.uefi.org/workinggroup for details on group membership. | 455 | http://www.uefi.org/workinggroup for details on group membership. |
@@ -443,7 +458,7 @@ It is the intent of the ARMv8 ACPI kernel code to follow the ACPI specification | |||
443 | as closely as possible, and to only implement functionality that complies with | 458 | as closely as possible, and to only implement functionality that complies with |
444 | the released standards from UEFI ASWG. As a practical matter, there will be | 459 | the released standards from UEFI ASWG. As a practical matter, there will be |
445 | vendors that provide bad ACPI tables or violate the standards in some way. | 460 | vendors that provide bad ACPI tables or violate the standards in some way. |
446 | If this is because of errors, quirks and fixups may be necessary, but will | 461 | If this is because of errors, quirks and fix-ups may be necessary, but will |
447 | be avoided if possible. If there are features missing from ACPI that preclude | 462 | be avoided if possible. If there are features missing from ACPI that preclude |
448 | it from being used on a platform, ECRs (Engineering Change Requests) should be | 463 | it from being used on a platform, ECRs (Engineering Change Requests) should be |
449 | submitted to ASWG and go through the normal approval process; for those that | 464 | submitted to ASWG and go through the normal approval process; for those that |
@@ -480,8 +495,7 @@ References | |||
480 | Software on ARM Platforms", dated 16 Aug 2014 | 495 | Software on ARM Platforms", dated 16 Aug 2014 |
481 | 496 | ||
482 | [2] http://www.secretlab.ca/archives/151, 10 Jan 2015, Copyright (c) 2015, | 497 | [2] http://www.secretlab.ca/archives/151, 10 Jan 2015, Copyright (c) 2015, |
483 | Linaro Ltd., written by Grant Likely. A copy of the verbatim text (apart | 498 | Linaro Ltd., written by Grant Likely. |
484 | from formatting) is also in Documentation/arm64/why_use_acpi.txt. | ||
485 | 499 | ||
486 | [3] AMD ACPI for Seattle platform documentation: | 500 | [3] AMD ACPI for Seattle platform documentation: |
487 | http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Seattle_ACPI_Guide.pdf | 501 | http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Seattle_ACPI_Guide.pdf |
diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt index 74d5417d0410..61c8b4620415 100644 --- a/Documentation/devicetree/bindings/arm/pmu.txt +++ b/Documentation/devicetree/bindings/arm/pmu.txt | |||
@@ -39,7 +39,9 @@ Optional properties: | |||
39 | When using a PPI, specifies a list of phandles to CPU | 39 | When using a PPI, specifies a list of phandles to CPU |
40 | nodes corresponding to the set of CPUs which have | 40 | nodes corresponding to the set of CPUs which have |
41 | a PMU of this type signalling the PPI listed in the | 41 | a PMU of this type signalling the PPI listed in the |
42 | interrupts property. | 42 | interrupts property, unless this is already specified |
43 | by the PPI interrupt specifier itself (in which case | ||
44 | the interrupt-affinity property shouldn't be present). | ||
43 | 45 | ||
44 | This property should be present when there is more than | 46 | This property should be present when there is more than |
45 | a single SPI. | 47 | a single SPI. |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 20d5a60530b1..9f8b99e20557 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -8,6 +8,7 @@ config ARM64 | |||
8 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 8 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
9 | select ARCH_HAS_ELF_RANDOMIZE | 9 | select ARCH_HAS_ELF_RANDOMIZE |
10 | select ARCH_HAS_GCOV_PROFILE_ALL | 10 | select ARCH_HAS_GCOV_PROFILE_ALL |
11 | select ARCH_HAS_KCOV | ||
11 | select ARCH_HAS_SG_CHAIN | 12 | select ARCH_HAS_SG_CHAIN |
12 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST | 13 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST |
13 | select ARCH_USE_CMPXCHG_LOCKREF | 14 | select ARCH_USE_CMPXCHG_LOCKREF |
@@ -86,8 +87,11 @@ config ARM64 | |||
86 | select HAVE_PERF_EVENTS | 87 | select HAVE_PERF_EVENTS |
87 | select HAVE_PERF_REGS | 88 | select HAVE_PERF_REGS |
88 | select HAVE_PERF_USER_STACK_DUMP | 89 | select HAVE_PERF_USER_STACK_DUMP |
90 | select HAVE_REGS_AND_STACK_ACCESS_API | ||
89 | select HAVE_RCU_TABLE_FREE | 91 | select HAVE_RCU_TABLE_FREE |
90 | select HAVE_SYSCALL_TRACEPOINTS | 92 | select HAVE_SYSCALL_TRACEPOINTS |
93 | select HAVE_KPROBES | ||
94 | select HAVE_KRETPROBES if HAVE_KPROBES | ||
91 | select IOMMU_DMA if IOMMU_SUPPORT | 95 | select IOMMU_DMA if IOMMU_SUPPORT |
92 | select IRQ_DOMAIN | 96 | select IRQ_DOMAIN |
93 | select IRQ_FORCED_THREADING | 97 | select IRQ_FORCED_THREADING |
@@ -665,6 +669,16 @@ config PARAVIRT_TIME_ACCOUNTING | |||
665 | 669 | ||
666 | If in doubt, say N here. | 670 | If in doubt, say N here. |
667 | 671 | ||
672 | config KEXEC | ||
673 | depends on PM_SLEEP_SMP | ||
674 | select KEXEC_CORE | ||
675 | bool "kexec system call" | ||
676 | ---help--- | ||
677 | kexec is a system call that implements the ability to shutdown your | ||
678 | current kernel, and to start another kernel. It is like a reboot | ||
679 | but it is independent of the system firmware. And like a reboot | ||
680 | you can start any kernel with it, not just Linux. | ||
681 | |||
668 | config XEN_DOM0 | 682 | config XEN_DOM0 |
669 | def_bool y | 683 | def_bool y |
670 | depends on XEN | 684 | depends on XEN |
@@ -873,7 +887,7 @@ config RELOCATABLE | |||
873 | 887 | ||
874 | config RANDOMIZE_BASE | 888 | config RANDOMIZE_BASE |
875 | bool "Randomize the address of the kernel image" | 889 | bool "Randomize the address of the kernel image" |
876 | select ARM64_MODULE_PLTS | 890 | select ARM64_MODULE_PLTS if MODULES |
877 | select RELOCATABLE | 891 | select RELOCATABLE |
878 | help | 892 | help |
879 | Randomizes the virtual address at which the kernel image is | 893 | Randomizes the virtual address at which the kernel image is |
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 648a32c89541..d59b6908a21a 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | LDFLAGS_vmlinux :=-p --no-undefined -X | 13 | LDFLAGS_vmlinux :=-p --no-undefined -X |
14 | CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) | 14 | CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) |
15 | OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S | ||
16 | GZFLAGS :=-9 | 15 | GZFLAGS :=-9 |
17 | 16 | ||
18 | ifneq ($(CONFIG_RELOCATABLE),) | 17 | ifneq ($(CONFIG_RELOCATABLE),) |
@@ -121,6 +120,16 @@ archclean: | |||
121 | $(Q)$(MAKE) $(clean)=$(boot) | 120 | $(Q)$(MAKE) $(clean)=$(boot) |
122 | $(Q)$(MAKE) $(clean)=$(boot)/dts | 121 | $(Q)$(MAKE) $(clean)=$(boot)/dts |
123 | 122 | ||
123 | # We need to generate vdso-offsets.h before compiling certain files in kernel/. | ||
124 | # In order to do that, we should use the archprepare target, but we can't since | ||
125 | # asm-offsets.h is included in some files used to generate vdso-offsets.h, and | ||
126 | # asm-offsets.h is built in prepare0, for which archprepare is a dependency. | ||
127 | # Therefore we need to generate the header after prepare0 has been made, hence | ||
128 | # this hack. | ||
129 | prepare: vdso_prepare | ||
130 | vdso_prepare: prepare0 | ||
131 | $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h | ||
132 | |||
124 | define archhelp | 133 | define archhelp |
125 | echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)' | 134 | echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)' |
126 | echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)' | 135 | echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)' |
diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile index 305c552b5ec1..1f012c506434 100644 --- a/arch/arm64/boot/Makefile +++ b/arch/arm64/boot/Makefile | |||
@@ -14,6 +14,8 @@ | |||
14 | # Based on the ia64 boot/Makefile. | 14 | # Based on the ia64 boot/Makefile. |
15 | # | 15 | # |
16 | 16 | ||
17 | OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S | ||
18 | |||
17 | targets := Image Image.gz | 19 | targets := Image Image.gz |
18 | 20 | ||
19 | $(obj)/Image: vmlinux FORCE | 21 | $(obj)/Image: vmlinux FORCE |
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index fd2d74d0491e..4ed4756dfa97 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig | |||
@@ -70,6 +70,7 @@ CONFIG_KSM=y | |||
70 | CONFIG_TRANSPARENT_HUGEPAGE=y | 70 | CONFIG_TRANSPARENT_HUGEPAGE=y |
71 | CONFIG_CMA=y | 71 | CONFIG_CMA=y |
72 | CONFIG_XEN=y | 72 | CONFIG_XEN=y |
73 | CONFIG_KEXEC=y | ||
73 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 74 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
74 | CONFIG_COMPAT=y | 75 | CONFIG_COMPAT=y |
75 | CONFIG_CPU_IDLE=y | 76 | CONFIG_CPU_IDLE=y |
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index cff532a6744e..f43d2c44c765 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild | |||
@@ -1,6 +1,5 @@ | |||
1 | generic-y += bug.h | 1 | generic-y += bug.h |
2 | generic-y += bugs.h | 2 | generic-y += bugs.h |
3 | generic-y += checksum.h | ||
4 | generic-y += clkdev.h | 3 | generic-y += clkdev.h |
5 | generic-y += cputime.h | 4 | generic-y += cputime.h |
6 | generic-y += current.h | 5 | generic-y += current.h |
diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h index beccbdefa106..8746ff6abd77 100644 --- a/arch/arm64/include/asm/alternative.h +++ b/arch/arm64/include/asm/alternative.h | |||
@@ -95,13 +95,11 @@ void apply_alternatives(void *start, size_t length); | |||
95 | * The code that follows this macro will be assembled and linked as | 95 | * The code that follows this macro will be assembled and linked as |
96 | * normal. There are no restrictions on this code. | 96 | * normal. There are no restrictions on this code. |
97 | */ | 97 | */ |
98 | .macro alternative_if_not cap, enable = 1 | 98 | .macro alternative_if_not cap |
99 | .if \enable | ||
100 | .pushsection .altinstructions, "a" | 99 | .pushsection .altinstructions, "a" |
101 | altinstruction_entry 661f, 663f, \cap, 662f-661f, 664f-663f | 100 | altinstruction_entry 661f, 663f, \cap, 662f-661f, 664f-663f |
102 | .popsection | 101 | .popsection |
103 | 661: | 102 | 661: |
104 | .endif | ||
105 | .endm | 103 | .endm |
106 | 104 | ||
107 | /* | 105 | /* |
@@ -118,27 +116,27 @@ void apply_alternatives(void *start, size_t length); | |||
118 | * alternative sequence it is defined in (branches into an | 116 | * alternative sequence it is defined in (branches into an |
119 | * alternative sequence are not fixed up). | 117 | * alternative sequence are not fixed up). |
120 | */ | 118 | */ |
121 | .macro alternative_else, enable = 1 | 119 | .macro alternative_else |
122 | .if \enable | ||
123 | 662: .pushsection .altinstr_replacement, "ax" | 120 | 662: .pushsection .altinstr_replacement, "ax" |
124 | 663: | 121 | 663: |
125 | .endif | ||
126 | .endm | 122 | .endm |
127 | 123 | ||
128 | /* | 124 | /* |
129 | * Complete an alternative code sequence. | 125 | * Complete an alternative code sequence. |
130 | */ | 126 | */ |
131 | .macro alternative_endif, enable = 1 | 127 | .macro alternative_endif |
132 | .if \enable | ||
133 | 664: .popsection | 128 | 664: .popsection |
134 | .org . - (664b-663b) + (662b-661b) | 129 | .org . - (664b-663b) + (662b-661b) |
135 | .org . - (662b-661b) + (664b-663b) | 130 | .org . - (662b-661b) + (664b-663b) |
136 | .endif | ||
137 | .endm | 131 | .endm |
138 | 132 | ||
139 | #define _ALTERNATIVE_CFG(insn1, insn2, cap, cfg, ...) \ | 133 | #define _ALTERNATIVE_CFG(insn1, insn2, cap, cfg, ...) \ |
140 | alternative_insn insn1, insn2, cap, IS_ENABLED(cfg) | 134 | alternative_insn insn1, insn2, cap, IS_ENABLED(cfg) |
141 | 135 | ||
136 | .macro user_alt, label, oldinstr, newinstr, cond | ||
137 | 9999: alternative_insn "\oldinstr", "\newinstr", \cond | ||
138 | _ASM_EXTABLE 9999b, \label | ||
139 | .endm | ||
142 | 140 | ||
143 | /* | 141 | /* |
144 | * Generate the assembly for UAO alternatives with exception table entries. | 142 | * Generate the assembly for UAO alternatives with exception table entries. |
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 10b017c4bdd8..d5025c69ca81 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define __ASM_ASSEMBLER_H | 24 | #define __ASM_ASSEMBLER_H |
25 | 25 | ||
26 | #include <asm/asm-offsets.h> | 26 | #include <asm/asm-offsets.h> |
27 | #include <asm/cpufeature.h> | ||
27 | #include <asm/page.h> | 28 | #include <asm/page.h> |
28 | #include <asm/pgtable-hwdef.h> | 29 | #include <asm/pgtable-hwdef.h> |
29 | #include <asm/ptrace.h> | 30 | #include <asm/ptrace.h> |
@@ -261,7 +262,16 @@ lr .req x30 // link register | |||
261 | add \size, \kaddr, \size | 262 | add \size, \kaddr, \size |
262 | sub \tmp2, \tmp1, #1 | 263 | sub \tmp2, \tmp1, #1 |
263 | bic \kaddr, \kaddr, \tmp2 | 264 | bic \kaddr, \kaddr, \tmp2 |
264 | 9998: dc \op, \kaddr | 265 | 9998: |
266 | .if (\op == cvau || \op == cvac) | ||
267 | alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE | ||
268 | dc \op, \kaddr | ||
269 | alternative_else | ||
270 | dc civac, \kaddr | ||
271 | alternative_endif | ||
272 | .else | ||
273 | dc \op, \kaddr | ||
274 | .endif | ||
265 | add \kaddr, \kaddr, \tmp1 | 275 | add \kaddr, \kaddr, \tmp1 |
266 | cmp \kaddr, \size | 276 | cmp \kaddr, \size |
267 | b.lo 9998b | 277 | b.lo 9998b |
diff --git a/arch/arm64/include/asm/checksum.h b/arch/arm64/include/asm/checksum.h new file mode 100644 index 000000000000..09f65339d66d --- /dev/null +++ b/arch/arm64/include/asm/checksum.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 ARM Ltd. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | #ifndef __ASM_CHECKSUM_H | ||
17 | #define __ASM_CHECKSUM_H | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | |||
21 | static inline __sum16 csum_fold(__wsum csum) | ||
22 | { | ||
23 | u32 sum = (__force u32)csum; | ||
24 | sum += (sum >> 16) | (sum << 16); | ||
25 | return ~(__force __sum16)(sum >> 16); | ||
26 | } | ||
27 | #define csum_fold csum_fold | ||
28 | |||
29 | static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) | ||
30 | { | ||
31 | __uint128_t tmp; | ||
32 | u64 sum; | ||
33 | |||
34 | tmp = *(const __uint128_t *)iph; | ||
35 | iph += 16; | ||
36 | ihl -= 4; | ||
37 | tmp += ((tmp >> 64) | (tmp << 64)); | ||
38 | sum = tmp >> 64; | ||
39 | do { | ||
40 | sum += *(const u32 *)iph; | ||
41 | iph += 4; | ||
42 | } while (--ihl); | ||
43 | |||
44 | sum += ((sum >> 32) | (sum << 32)); | ||
45 | return csum_fold(sum >> 32); | ||
46 | } | ||
47 | #define ip_fast_csum ip_fast_csum | ||
48 | |||
49 | #include <asm-generic/checksum.h> | ||
50 | |||
51 | #endif /* __ASM_CHECKSUM_H */ | ||
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h index 13a6103130cd..889226b4c6e1 100644 --- a/arch/arm64/include/asm/cpu.h +++ b/arch/arm64/include/asm/cpu.h | |||
@@ -25,10 +25,12 @@ | |||
25 | */ | 25 | */ |
26 | struct cpuinfo_arm64 { | 26 | struct cpuinfo_arm64 { |
27 | struct cpu cpu; | 27 | struct cpu cpu; |
28 | struct kobject kobj; | ||
28 | u32 reg_ctr; | 29 | u32 reg_ctr; |
29 | u32 reg_cntfrq; | 30 | u32 reg_cntfrq; |
30 | u32 reg_dczid; | 31 | u32 reg_dczid; |
31 | u32 reg_midr; | 32 | u32 reg_midr; |
33 | u32 reg_revidr; | ||
32 | 34 | ||
33 | u64 reg_id_aa64dfr0; | 35 | u64 reg_id_aa64dfr0; |
34 | u64 reg_id_aa64dfr1; | 36 | u64 reg_id_aa64dfr1; |
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 224efe730e46..49dd1bd3ea50 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h | |||
@@ -191,7 +191,9 @@ void __init setup_cpu_features(void); | |||
191 | 191 | ||
192 | void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps, | 192 | void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps, |
193 | const char *info); | 193 | const char *info); |
194 | void enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps); | ||
194 | void check_local_cpu_errata(void); | 195 | void check_local_cpu_errata(void); |
196 | void __init enable_errata_workarounds(void); | ||
195 | 197 | ||
196 | void verify_local_cpu_errata(void); | 198 | void verify_local_cpu_errata(void); |
197 | void verify_local_cpu_capabilities(void); | 199 | void verify_local_cpu_capabilities(void); |
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h index 2fcb9b7c876c..4b6b3f72a215 100644 --- a/arch/arm64/include/asm/debug-monitors.h +++ b/arch/arm64/include/asm/debug-monitors.h | |||
@@ -66,6 +66,11 @@ | |||
66 | 66 | ||
67 | #define CACHE_FLUSH_IS_SAFE 1 | 67 | #define CACHE_FLUSH_IS_SAFE 1 |
68 | 68 | ||
69 | /* kprobes BRK opcodes with ESR encoding */ | ||
70 | #define BRK64_ESR_MASK 0xFFFF | ||
71 | #define BRK64_ESR_KPROBES 0x0004 | ||
72 | #define BRK64_OPCODE_KPROBES (AARCH64_BREAK_MON | (BRK64_ESR_KPROBES << 5)) | ||
73 | |||
69 | /* AArch32 */ | 74 | /* AArch32 */ |
70 | #define DBG_ESR_EVT_BKPT 0x4 | 75 | #define DBG_ESR_EVT_BKPT 0x4 |
71 | #define DBG_ESR_EVT_VECC 0x5 | 76 | #define DBG_ESR_EVT_VECC 0x5 |
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index bd887663689b..a9e54aad15ef 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h | |||
@@ -14,8 +14,7 @@ extern void efi_init(void); | |||
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); | 16 | int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); |
17 | 17 | int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); | |
18 | #define efi_set_mapping_permissions efi_create_mapping | ||
19 | 18 | ||
20 | #define arch_efi_call_virt_setup() \ | 19 | #define arch_efi_call_virt_setup() \ |
21 | ({ \ | 20 | ({ \ |
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 77eeb2cc648f..f772e15c4766 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h | |||
@@ -74,6 +74,7 @@ | |||
74 | 74 | ||
75 | #define ESR_ELx_EC_SHIFT (26) | 75 | #define ESR_ELx_EC_SHIFT (26) |
76 | #define ESR_ELx_EC_MASK (UL(0x3F) << ESR_ELx_EC_SHIFT) | 76 | #define ESR_ELx_EC_MASK (UL(0x3F) << ESR_ELx_EC_SHIFT) |
77 | #define ESR_ELx_EC(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT) | ||
77 | 78 | ||
78 | #define ESR_ELx_IL (UL(1) << 25) | 79 | #define ESR_ELx_IL (UL(1) << 25) |
79 | #define ESR_ELx_ISS_MASK (ESR_ELx_IL - 1) | 80 | #define ESR_ELx_ISS_MASK (ESR_ELx_IL - 1) |
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h index 30e50eb54a67..1dbaa901d7e5 100644 --- a/arch/arm64/include/asm/insn.h +++ b/arch/arm64/include/asm/insn.h | |||
@@ -120,6 +120,29 @@ enum aarch64_insn_register { | |||
120 | AARCH64_INSN_REG_SP = 31 /* Stack pointer: as load/store base reg */ | 120 | AARCH64_INSN_REG_SP = 31 /* Stack pointer: as load/store base reg */ |
121 | }; | 121 | }; |
122 | 122 | ||
123 | enum aarch64_insn_special_register { | ||
124 | AARCH64_INSN_SPCLREG_SPSR_EL1 = 0xC200, | ||
125 | AARCH64_INSN_SPCLREG_ELR_EL1 = 0xC201, | ||
126 | AARCH64_INSN_SPCLREG_SP_EL0 = 0xC208, | ||
127 | AARCH64_INSN_SPCLREG_SPSEL = 0xC210, | ||
128 | AARCH64_INSN_SPCLREG_CURRENTEL = 0xC212, | ||
129 | AARCH64_INSN_SPCLREG_DAIF = 0xDA11, | ||
130 | AARCH64_INSN_SPCLREG_NZCV = 0xDA10, | ||
131 | AARCH64_INSN_SPCLREG_FPCR = 0xDA20, | ||
132 | AARCH64_INSN_SPCLREG_DSPSR_EL0 = 0xDA28, | ||
133 | AARCH64_INSN_SPCLREG_DLR_EL0 = 0xDA29, | ||
134 | AARCH64_INSN_SPCLREG_SPSR_EL2 = 0xE200, | ||
135 | AARCH64_INSN_SPCLREG_ELR_EL2 = 0xE201, | ||
136 | AARCH64_INSN_SPCLREG_SP_EL1 = 0xE208, | ||
137 | AARCH64_INSN_SPCLREG_SPSR_INQ = 0xE218, | ||
138 | AARCH64_INSN_SPCLREG_SPSR_ABT = 0xE219, | ||
139 | AARCH64_INSN_SPCLREG_SPSR_UND = 0xE21A, | ||
140 | AARCH64_INSN_SPCLREG_SPSR_FIQ = 0xE21B, | ||
141 | AARCH64_INSN_SPCLREG_SPSR_EL3 = 0xF200, | ||
142 | AARCH64_INSN_SPCLREG_ELR_EL3 = 0xF201, | ||
143 | AARCH64_INSN_SPCLREG_SP_EL2 = 0xF210 | ||
144 | }; | ||
145 | |||
123 | enum aarch64_insn_variant { | 146 | enum aarch64_insn_variant { |
124 | AARCH64_INSN_VARIANT_32BIT, | 147 | AARCH64_INSN_VARIANT_32BIT, |
125 | AARCH64_INSN_VARIANT_64BIT | 148 | AARCH64_INSN_VARIANT_64BIT |
@@ -223,8 +246,15 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \ | |||
223 | static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \ | 246 | static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \ |
224 | { return (val); } | 247 | { return (val); } |
225 | 248 | ||
249 | __AARCH64_INSN_FUNCS(adr_adrp, 0x1F000000, 0x10000000) | ||
250 | __AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000) | ||
226 | __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800) | 251 | __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800) |
227 | __AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800) | 252 | __AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800) |
253 | __AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000) | ||
254 | __AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000) | ||
255 | __AARCH64_INSN_FUNCS(exclusive, 0x3F800000, 0x08000000) | ||
256 | __AARCH64_INSN_FUNCS(load_ex, 0x3F400000, 0x08400000) | ||
257 | __AARCH64_INSN_FUNCS(store_ex, 0x3F400000, 0x08000000) | ||
228 | __AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000) | 258 | __AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000) |
229 | __AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000) | 259 | __AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000) |
230 | __AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000) | 260 | __AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000) |
@@ -273,10 +303,15 @@ __AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001) | |||
273 | __AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002) | 303 | __AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002) |
274 | __AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003) | 304 | __AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003) |
275 | __AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000) | 305 | __AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000) |
306 | __AARCH64_INSN_FUNCS(exception, 0xFF000000, 0xD4000000) | ||
276 | __AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F) | 307 | __AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F) |
277 | __AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000) | 308 | __AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000) |
278 | __AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000) | 309 | __AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000) |
279 | __AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000) | 310 | __AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000) |
311 | __AARCH64_INSN_FUNCS(eret, 0xFFFFFFFF, 0xD69F03E0) | ||
312 | __AARCH64_INSN_FUNCS(mrs, 0xFFF00000, 0xD5300000) | ||
313 | __AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F01F, 0xD500401F) | ||
314 | __AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000) | ||
280 | 315 | ||
281 | #undef __AARCH64_INSN_FUNCS | 316 | #undef __AARCH64_INSN_FUNCS |
282 | 317 | ||
@@ -286,6 +321,8 @@ bool aarch64_insn_is_branch_imm(u32 insn); | |||
286 | int aarch64_insn_read(void *addr, u32 *insnp); | 321 | int aarch64_insn_read(void *addr, u32 *insnp); |
287 | int aarch64_insn_write(void *addr, u32 insn); | 322 | int aarch64_insn_write(void *addr, u32 insn); |
288 | enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn); | 323 | enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn); |
324 | bool aarch64_insn_uses_literal(u32 insn); | ||
325 | bool aarch64_insn_is_branch(u32 insn); | ||
289 | u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn); | 326 | u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn); |
290 | u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, | 327 | u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, |
291 | u32 insn, u64 imm); | 328 | u32 insn, u64 imm); |
@@ -367,9 +404,13 @@ bool aarch32_insn_is_wide(u32 insn); | |||
367 | #define A32_RT_OFFSET 12 | 404 | #define A32_RT_OFFSET 12 |
368 | #define A32_RT2_OFFSET 0 | 405 | #define A32_RT2_OFFSET 0 |
369 | 406 | ||
407 | u32 aarch64_insn_extract_system_reg(u32 insn); | ||
370 | u32 aarch32_insn_extract_reg_num(u32 insn, int offset); | 408 | u32 aarch32_insn_extract_reg_num(u32 insn, int offset); |
371 | u32 aarch32_insn_mcr_extract_opc2(u32 insn); | 409 | u32 aarch32_insn_mcr_extract_opc2(u32 insn); |
372 | u32 aarch32_insn_mcr_extract_crm(u32 insn); | 410 | u32 aarch32_insn_mcr_extract_crm(u32 insn); |
411 | |||
412 | typedef bool (pstate_check_t)(unsigned long); | ||
413 | extern pstate_check_t * const aarch32_opcode_cond_checks[16]; | ||
373 | #endif /* __ASSEMBLY__ */ | 414 | #endif /* __ASSEMBLY__ */ |
374 | 415 | ||
375 | #endif /* __ASM_INSN_H */ | 416 | #endif /* __ASM_INSN_H */ |
diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h index 11cc941bd107..8c581281fa12 100644 --- a/arch/arm64/include/asm/irqflags.h +++ b/arch/arm64/include/asm/irqflags.h | |||
@@ -110,8 +110,5 @@ static inline int arch_irqs_disabled_flags(unsigned long flags) | |||
110 | : : "r" (flags) : "memory"); \ | 110 | : : "r" (flags) : "memory"); \ |
111 | } while (0) | 111 | } while (0) |
112 | 112 | ||
113 | #define local_dbg_enable() asm("msr daifclr, #8" : : : "memory") | ||
114 | #define local_dbg_disable() asm("msr daifset, #8" : : : "memory") | ||
115 | |||
116 | #endif | 113 | #endif |
117 | #endif | 114 | #endif |
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h new file mode 100644 index 000000000000..04744dc5fb61 --- /dev/null +++ b/arch/arm64/include/asm/kexec.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * kexec for arm64 | ||
3 | * | ||
4 | * Copyright (C) Linaro. | ||
5 | * Copyright (C) Huawei Futurewei Technologies. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _ARM64_KEXEC_H | ||
13 | #define _ARM64_KEXEC_H | ||
14 | |||
15 | /* Maximum physical address we can use pages from */ | ||
16 | |||
17 | #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) | ||
18 | |||
19 | /* Maximum address we can reach in physical address mode */ | ||
20 | |||
21 | #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) | ||
22 | |||
23 | /* Maximum address we can use for the control code buffer */ | ||
24 | |||
25 | #define KEXEC_CONTROL_MEMORY_LIMIT (-1UL) | ||
26 | |||
27 | #define KEXEC_CONTROL_PAGE_SIZE 4096 | ||
28 | |||
29 | #define KEXEC_ARCH KEXEC_ARCH_AARCH64 | ||
30 | |||
31 | #ifndef __ASSEMBLY__ | ||
32 | |||
33 | /** | ||
34 | * crash_setup_regs() - save registers for the panic kernel | ||
35 | * | ||
36 | * @newregs: registers are saved here | ||
37 | * @oldregs: registers to be saved (may be %NULL) | ||
38 | */ | ||
39 | |||
40 | static inline void crash_setup_regs(struct pt_regs *newregs, | ||
41 | struct pt_regs *oldregs) | ||
42 | { | ||
43 | /* Empty routine needed to avoid build errors. */ | ||
44 | } | ||
45 | |||
46 | #endif /* __ASSEMBLY__ */ | ||
47 | |||
48 | #endif | ||
diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h new file mode 100644 index 000000000000..61b49150dfa3 --- /dev/null +++ b/arch/arm64/include/asm/kprobes.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * arch/arm64/include/asm/kprobes.h | ||
3 | * | ||
4 | * Copyright (C) 2013 Linaro Limited | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef _ARM_KPROBES_H | ||
17 | #define _ARM_KPROBES_H | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/ptrace.h> | ||
21 | #include <linux/percpu.h> | ||
22 | |||
23 | #define __ARCH_WANT_KPROBES_INSN_SLOT | ||
24 | #define MAX_INSN_SIZE 1 | ||
25 | #define MAX_STACK_SIZE 128 | ||
26 | |||
27 | #define flush_insn_slot(p) do { } while (0) | ||
28 | #define kretprobe_blacklist_size 0 | ||
29 | |||
30 | #include <asm/probes.h> | ||
31 | |||
32 | struct prev_kprobe { | ||
33 | struct kprobe *kp; | ||
34 | unsigned int status; | ||
35 | }; | ||
36 | |||
37 | /* Single step context for kprobe */ | ||
38 | struct kprobe_step_ctx { | ||
39 | unsigned long ss_pending; | ||
40 | unsigned long match_addr; | ||
41 | }; | ||
42 | |||
43 | /* per-cpu kprobe control block */ | ||
44 | struct kprobe_ctlblk { | ||
45 | unsigned int kprobe_status; | ||
46 | unsigned long saved_irqflag; | ||
47 | struct prev_kprobe prev_kprobe; | ||
48 | struct kprobe_step_ctx ss_ctx; | ||
49 | struct pt_regs jprobe_saved_regs; | ||
50 | char jprobes_stack[MAX_STACK_SIZE]; | ||
51 | }; | ||
52 | |||
53 | void arch_remove_kprobe(struct kprobe *); | ||
54 | int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); | ||
55 | int kprobe_exceptions_notify(struct notifier_block *self, | ||
56 | unsigned long val, void *data); | ||
57 | int kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr); | ||
58 | int kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr); | ||
59 | void kretprobe_trampoline(void); | ||
60 | void __kprobes *trampoline_probe_handler(struct pt_regs *regs); | ||
61 | |||
62 | #endif /* _ARM_KPROBES_H */ | ||
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 40bc1681b6d5..4cdeae3b17c6 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h | |||
@@ -210,7 +210,7 @@ static inline bool kvm_vcpu_trap_il_is32bit(const struct kvm_vcpu *vcpu) | |||
210 | 210 | ||
211 | static inline u8 kvm_vcpu_trap_get_class(const struct kvm_vcpu *vcpu) | 211 | static inline u8 kvm_vcpu_trap_get_class(const struct kvm_vcpu *vcpu) |
212 | { | 212 | { |
213 | return kvm_vcpu_get_hsr(vcpu) >> ESR_ELx_EC_SHIFT; | 213 | return ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu)); |
214 | } | 214 | } |
215 | 215 | ||
216 | static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu) | 216 | static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu) |
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index 97b1d8f26b9c..8d9fce037b2f 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h | |||
@@ -34,7 +34,7 @@ extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt); | |||
34 | extern void init_mem_pgprot(void); | 34 | extern void init_mem_pgprot(void); |
35 | extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, | 35 | extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, |
36 | unsigned long virt, phys_addr_t size, | 36 | unsigned long virt, phys_addr_t size, |
37 | pgprot_t prot); | 37 | pgprot_t prot, bool allow_block_mappings); |
38 | extern void *fixmap_remap_fdt(phys_addr_t dt_phys); | 38 | extern void *fixmap_remap_fdt(phys_addr_t dt_phys); |
39 | 39 | ||
40 | #endif | 40 | #endif |
diff --git a/arch/arm64/include/asm/probes.h b/arch/arm64/include/asm/probes.h new file mode 100644 index 000000000000..5af574d632fa --- /dev/null +++ b/arch/arm64/include/asm/probes.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * arch/arm64/include/asm/probes.h | ||
3 | * | ||
4 | * Copyright (C) 2013 Linaro Limited | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | #ifndef _ARM_PROBES_H | ||
16 | #define _ARM_PROBES_H | ||
17 | |||
18 | #include <asm/opcodes.h> | ||
19 | |||
20 | struct kprobe; | ||
21 | struct arch_specific_insn; | ||
22 | |||
23 | typedef u32 kprobe_opcode_t; | ||
24 | typedef void (kprobes_handler_t) (u32 opcode, long addr, struct pt_regs *); | ||
25 | |||
26 | /* architecture specific copy of original instruction */ | ||
27 | struct arch_specific_insn { | ||
28 | kprobe_opcode_t *insn; | ||
29 | pstate_check_t *pstate_cc; | ||
30 | kprobes_handler_t *handler; | ||
31 | /* restore address after step xol */ | ||
32 | unsigned long restore; | ||
33 | }; | ||
34 | |||
35 | #endif | ||
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index cef1cf398356..ace0a96e7d6e 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h | |||
@@ -192,5 +192,6 @@ static inline void spin_lock_prefetch(const void *ptr) | |||
192 | 192 | ||
193 | void cpu_enable_pan(void *__unused); | 193 | void cpu_enable_pan(void *__unused); |
194 | void cpu_enable_uao(void *__unused); | 194 | void cpu_enable_uao(void *__unused); |
195 | void cpu_enable_cache_maint_trap(void *__unused); | ||
195 | 196 | ||
196 | #endif /* __ASM_PROCESSOR_H */ | 197 | #endif /* __ASM_PROCESSOR_H */ |
diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h new file mode 100644 index 000000000000..07b8ed037dee --- /dev/null +++ b/arch/arm64/include/asm/ptdump.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 ARM Ltd. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | #ifndef __ASM_PTDUMP_H | ||
17 | #define __ASM_PTDUMP_H | ||
18 | |||
19 | #ifdef CONFIG_ARM64_PTDUMP | ||
20 | |||
21 | #include <linux/mm_types.h> | ||
22 | |||
23 | struct addr_marker { | ||
24 | unsigned long start_address; | ||
25 | char *name; | ||
26 | }; | ||
27 | |||
28 | struct ptdump_info { | ||
29 | struct mm_struct *mm; | ||
30 | const struct addr_marker *markers; | ||
31 | unsigned long base_addr; | ||
32 | unsigned long max_addr; | ||
33 | }; | ||
34 | |||
35 | int ptdump_register(struct ptdump_info *info, const char *name); | ||
36 | |||
37 | #else | ||
38 | static inline int ptdump_register(struct ptdump_info *info, const char *name) | ||
39 | { | ||
40 | return 0; | ||
41 | } | ||
42 | #endif /* CONFIG_ARM64_PTDUMP */ | ||
43 | |||
44 | #endif /* __ASM_PTDUMP_H */ | ||
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 7f94755089e2..ada08b5b036d 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h | |||
@@ -46,7 +46,6 @@ | |||
46 | #define COMPAT_PSR_MODE_UND 0x0000001b | 46 | #define COMPAT_PSR_MODE_UND 0x0000001b |
47 | #define COMPAT_PSR_MODE_SYS 0x0000001f | 47 | #define COMPAT_PSR_MODE_SYS 0x0000001f |
48 | #define COMPAT_PSR_T_BIT 0x00000020 | 48 | #define COMPAT_PSR_T_BIT 0x00000020 |
49 | #define COMPAT_PSR_E_BIT 0x00000200 | ||
50 | #define COMPAT_PSR_F_BIT 0x00000040 | 49 | #define COMPAT_PSR_F_BIT 0x00000040 |
51 | #define COMPAT_PSR_I_BIT 0x00000080 | 50 | #define COMPAT_PSR_I_BIT 0x00000080 |
52 | #define COMPAT_PSR_A_BIT 0x00000100 | 51 | #define COMPAT_PSR_A_BIT 0x00000100 |
@@ -74,6 +73,7 @@ | |||
74 | #define COMPAT_PT_DATA_ADDR 0x10004 | 73 | #define COMPAT_PT_DATA_ADDR 0x10004 |
75 | #define COMPAT_PT_TEXT_END_ADDR 0x10008 | 74 | #define COMPAT_PT_TEXT_END_ADDR 0x10008 |
76 | #ifndef __ASSEMBLY__ | 75 | #ifndef __ASSEMBLY__ |
76 | #include <linux/bug.h> | ||
77 | 77 | ||
78 | /* sizeof(struct user) for AArch32 */ | 78 | /* sizeof(struct user) for AArch32 */ |
79 | #define COMPAT_USER_SZ 296 | 79 | #define COMPAT_USER_SZ 296 |
@@ -121,6 +121,8 @@ struct pt_regs { | |||
121 | u64 unused; // maintain 16 byte alignment | 121 | u64 unused; // maintain 16 byte alignment |
122 | }; | 122 | }; |
123 | 123 | ||
124 | #define MAX_REG_OFFSET offsetof(struct pt_regs, pstate) | ||
125 | |||
124 | #define arch_has_single_step() (1) | 126 | #define arch_has_single_step() (1) |
125 | 127 | ||
126 | #ifdef CONFIG_COMPAT | 128 | #ifdef CONFIG_COMPAT |
@@ -146,9 +148,58 @@ struct pt_regs { | |||
146 | #define fast_interrupts_enabled(regs) \ | 148 | #define fast_interrupts_enabled(regs) \ |
147 | (!((regs)->pstate & PSR_F_BIT)) | 149 | (!((regs)->pstate & PSR_F_BIT)) |
148 | 150 | ||
149 | #define user_stack_pointer(regs) \ | 151 | #define GET_USP(regs) \ |
150 | (!compat_user_mode(regs) ? (regs)->sp : (regs)->compat_sp) | 152 | (!compat_user_mode(regs) ? (regs)->sp : (regs)->compat_sp) |
151 | 153 | ||
154 | #define SET_USP(ptregs, value) \ | ||
155 | (!compat_user_mode(regs) ? ((regs)->sp = value) : ((regs)->compat_sp = value)) | ||
156 | |||
157 | extern int regs_query_register_offset(const char *name); | ||
158 | extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, | ||
159 | unsigned int n); | ||
160 | |||
161 | /** | ||
162 | * regs_get_register() - get register value from its offset | ||
163 | * @regs: pt_regs from which register value is gotten | ||
164 | * @offset: offset of the register. | ||
165 | * | ||
166 | * regs_get_register returns the value of a register whose offset from @regs. | ||
167 | * The @offset is the offset of the register in struct pt_regs. | ||
168 | * If @offset is bigger than MAX_REG_OFFSET, this returns 0. | ||
169 | */ | ||
170 | static inline u64 regs_get_register(struct pt_regs *regs, unsigned int offset) | ||
171 | { | ||
172 | u64 val = 0; | ||
173 | |||
174 | WARN_ON(offset & 7); | ||
175 | |||
176 | offset >>= 3; | ||
177 | switch (offset) { | ||
178 | case 0 ... 30: | ||
179 | val = regs->regs[offset]; | ||
180 | break; | ||
181 | case offsetof(struct pt_regs, sp) >> 3: | ||
182 | val = regs->sp; | ||
183 | break; | ||
184 | case offsetof(struct pt_regs, pc) >> 3: | ||
185 | val = regs->pc; | ||
186 | break; | ||
187 | case offsetof(struct pt_regs, pstate) >> 3: | ||
188 | val = regs->pstate; | ||
189 | break; | ||
190 | default: | ||
191 | val = 0; | ||
192 | } | ||
193 | |||
194 | return val; | ||
195 | } | ||
196 | |||
197 | /* Valid only for Kernel mode traps. */ | ||
198 | static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) | ||
199 | { | ||
200 | return regs->sp; | ||
201 | } | ||
202 | |||
152 | static inline unsigned long regs_return_value(struct pt_regs *regs) | 203 | static inline unsigned long regs_return_value(struct pt_regs *regs) |
153 | { | 204 | { |
154 | return regs->regs[0]; | 205 | return regs->regs[0]; |
@@ -158,8 +209,15 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) | |||
158 | struct task_struct; | 209 | struct task_struct; |
159 | int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task); | 210 | int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task); |
160 | 211 | ||
161 | #define instruction_pointer(regs) ((unsigned long)(regs)->pc) | 212 | #define GET_IP(regs) ((unsigned long)(regs)->pc) |
213 | #define SET_IP(regs, value) ((regs)->pc = ((u64) (value))) | ||
214 | |||
215 | #define GET_FP(ptregs) ((unsigned long)(ptregs)->regs[29]) | ||
216 | #define SET_FP(ptregs, value) ((ptregs)->regs[29] = ((u64) (value))) | ||
217 | |||
218 | #include <asm-generic/ptrace.h> | ||
162 | 219 | ||
220 | #undef profile_pc | ||
163 | extern unsigned long profile_pc(struct pt_regs *regs); | 221 | extern unsigned long profile_pc(struct pt_regs *regs); |
164 | 222 | ||
165 | #endif /* __ASSEMBLY__ */ | 223 | #endif /* __ASSEMBLY__ */ |
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 751e901c8d37..cc06794b7346 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h | |||
@@ -98,11 +98,11 @@ | |||
98 | SCTLR_ELx_SA | SCTLR_ELx_I) | 98 | SCTLR_ELx_SA | SCTLR_ELx_I) |
99 | 99 | ||
100 | /* SCTLR_EL1 specific flags. */ | 100 | /* SCTLR_EL1 specific flags. */ |
101 | #define SCTLR_EL1_UCI (1 << 26) | ||
101 | #define SCTLR_EL1_SPAN (1 << 23) | 102 | #define SCTLR_EL1_SPAN (1 << 23) |
102 | #define SCTLR_EL1_SED (1 << 8) | 103 | #define SCTLR_EL1_SED (1 << 8) |
103 | #define SCTLR_EL1_CP15BEN (1 << 5) | 104 | #define SCTLR_EL1_CP15BEN (1 << 5) |
104 | 105 | ||
105 | |||
106 | /* id_aa64isar0 */ | 106 | /* id_aa64isar0 */ |
107 | #define ID_AA64ISAR0_RDM_SHIFT 28 | 107 | #define ID_AA64ISAR0_RDM_SHIFT 28 |
108 | #define ID_AA64ISAR0_ATOMICS_SHIFT 20 | 108 | #define ID_AA64ISAR0_ATOMICS_SHIFT 20 |
diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h index 0cc2f29bf9da..9cd03f3e812f 100644 --- a/arch/arm64/include/asm/traps.h +++ b/arch/arm64/include/asm/traps.h | |||
@@ -34,6 +34,8 @@ struct undef_hook { | |||
34 | void register_undef_hook(struct undef_hook *hook); | 34 | void register_undef_hook(struct undef_hook *hook); |
35 | void unregister_undef_hook(struct undef_hook *hook); | 35 | void unregister_undef_hook(struct undef_hook *hook); |
36 | 36 | ||
37 | void arm64_notify_segfault(struct pt_regs *regs, unsigned long addr); | ||
38 | |||
37 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 39 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
38 | static inline int __in_irqentry_text(unsigned long ptr) | 40 | static inline int __in_irqentry_text(unsigned long ptr) |
39 | { | 41 | { |
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index 9e397a542756..5e834d10b291 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h | |||
@@ -21,6 +21,7 @@ | |||
21 | /* | 21 | /* |
22 | * User space memory access functions | 22 | * User space memory access functions |
23 | */ | 23 | */ |
24 | #include <linux/kasan-checks.h> | ||
24 | #include <linux/string.h> | 25 | #include <linux/string.h> |
25 | #include <linux/thread_info.h> | 26 | #include <linux/thread_info.h> |
26 | 27 | ||
@@ -256,15 +257,29 @@ do { \ | |||
256 | -EFAULT; \ | 257 | -EFAULT; \ |
257 | }) | 258 | }) |
258 | 259 | ||
259 | extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n); | 260 | extern unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n); |
260 | extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n); | 261 | extern unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n); |
261 | extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n); | 262 | extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n); |
262 | extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); | 263 | extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); |
263 | 264 | ||
265 | static inline unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n) | ||
266 | { | ||
267 | kasan_check_write(to, n); | ||
268 | return __arch_copy_from_user(to, from, n); | ||
269 | } | ||
270 | |||
271 | static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n) | ||
272 | { | ||
273 | kasan_check_read(from, n); | ||
274 | return __arch_copy_to_user(to, from, n); | ||
275 | } | ||
276 | |||
264 | static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) | 277 | static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) |
265 | { | 278 | { |
279 | kasan_check_write(to, n); | ||
280 | |||
266 | if (access_ok(VERIFY_READ, from, n)) | 281 | if (access_ok(VERIFY_READ, from, n)) |
267 | n = __copy_from_user(to, from, n); | 282 | n = __arch_copy_from_user(to, from, n); |
268 | else /* security hole - plug it */ | 283 | else /* security hole - plug it */ |
269 | memset(to, 0, n); | 284 | memset(to, 0, n); |
270 | return n; | 285 | return n; |
@@ -272,8 +287,10 @@ static inline unsigned long __must_check copy_from_user(void *to, const void __u | |||
272 | 287 | ||
273 | static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) | 288 | static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) |
274 | { | 289 | { |
290 | kasan_check_read(from, n); | ||
291 | |||
275 | if (access_ok(VERIFY_WRITE, to, n)) | 292 | if (access_ok(VERIFY_WRITE, to, n)) |
276 | n = __copy_to_user(to, from, n); | 293 | n = __arch_copy_to_user(to, from, n); |
277 | return n; | 294 | return n; |
278 | } | 295 | } |
279 | 296 | ||
diff --git a/arch/arm64/include/asm/vdso_datapage.h b/arch/arm64/include/asm/vdso_datapage.h index de66199673d7..2b9a63771eda 100644 --- a/arch/arm64/include/asm/vdso_datapage.h +++ b/arch/arm64/include/asm/vdso_datapage.h | |||
@@ -22,6 +22,8 @@ | |||
22 | 22 | ||
23 | struct vdso_data { | 23 | struct vdso_data { |
24 | __u64 cs_cycle_last; /* Timebase at clocksource init */ | 24 | __u64 cs_cycle_last; /* Timebase at clocksource init */ |
25 | __u64 raw_time_sec; /* Raw time */ | ||
26 | __u64 raw_time_nsec; | ||
25 | __u64 xtime_clock_sec; /* Kernel time */ | 27 | __u64 xtime_clock_sec; /* Kernel time */ |
26 | __u64 xtime_clock_nsec; | 28 | __u64 xtime_clock_nsec; |
27 | __u64 xtime_coarse_sec; /* Coarse time */ | 29 | __u64 xtime_coarse_sec; /* Coarse time */ |
@@ -29,8 +31,10 @@ struct vdso_data { | |||
29 | __u64 wtm_clock_sec; /* Wall to monotonic time */ | 31 | __u64 wtm_clock_sec; /* Wall to monotonic time */ |
30 | __u64 wtm_clock_nsec; | 32 | __u64 wtm_clock_nsec; |
31 | __u32 tb_seq_count; /* Timebase sequence counter */ | 33 | __u32 tb_seq_count; /* Timebase sequence counter */ |
32 | __u32 cs_mult; /* Clocksource multiplier */ | 34 | /* cs_* members must be adjacent and in this order (ldp accesses) */ |
33 | __u32 cs_shift; /* Clocksource shift */ | 35 | __u32 cs_mono_mult; /* NTP-adjusted clocksource multiplier */ |
36 | __u32 cs_shift; /* Clocksource shift (mono = raw) */ | ||
37 | __u32 cs_raw_mult; /* Raw clocksource multiplier */ | ||
34 | __u32 tz_minuteswest; /* Whacky timezone stuff */ | 38 | __u32 tz_minuteswest; /* Whacky timezone stuff */ |
35 | __u32 tz_dsttime; | 39 | __u32 tz_dsttime; |
36 | __u32 use_syscall; | 40 | __u32 use_syscall; |
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h index dcbcf8dcbefb..bbc6a8cf83f1 100644 --- a/arch/arm64/include/asm/virt.h +++ b/arch/arm64/include/asm/virt.h | |||
@@ -34,6 +34,11 @@ | |||
34 | */ | 34 | */ |
35 | #define HVC_SET_VECTORS 1 | 35 | #define HVC_SET_VECTORS 1 |
36 | 36 | ||
37 | /* | ||
38 | * HVC_SOFT_RESTART - CPU soft reset, used by the cpu_soft_restart routine. | ||
39 | */ | ||
40 | #define HVC_SOFT_RESTART 2 | ||
41 | |||
37 | #define BOOT_CPU_MODE_EL1 (0xe11) | 42 | #define BOOT_CPU_MODE_EL1 (0xe11) |
38 | #define BOOT_CPU_MODE_EL2 (0xe12) | 43 | #define BOOT_CPU_MODE_EL2 (0xe12) |
39 | 44 | ||
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index a5125c6d1f87..14f7b651c787 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile | |||
@@ -26,8 +26,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE | |||
26 | $(call if_changed,objcopy) | 26 | $(call if_changed,objcopy) |
27 | 27 | ||
28 | arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ | 28 | arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ |
29 | sys_compat.o entry32.o \ | 29 | sys_compat.o entry32.o |
30 | ../../arm/kernel/opcodes.o | ||
31 | arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o | 30 | arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o |
32 | arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o | 31 | arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o |
33 | arm64-obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o | 32 | arm64-obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o |
@@ -47,12 +46,10 @@ arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o | |||
47 | arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o | 46 | arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o |
48 | arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o | 47 | arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o |
49 | arm64-obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o | 48 | arm64-obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o |
49 | arm64-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o \ | ||
50 | cpu-reset.o | ||
50 | 51 | ||
51 | obj-y += $(arm64-obj-y) vdso/ | 52 | obj-y += $(arm64-obj-y) vdso/ probes/ |
52 | obj-m += $(arm64-obj-m) | 53 | obj-m += $(arm64-obj-m) |
53 | head-y := head.o | 54 | head-y := head.o |
54 | extra-y += $(head-y) vmlinux.lds | 55 | extra-y += $(head-y) vmlinux.lds |
55 | |||
56 | # vDSO - this must be built first to generate the symbol offsets | ||
57 | $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h | ||
58 | $(obj)/vdso/vdso-offsets.h: $(obj)/vdso | ||
diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c index 678f30b05a45..78f368039c79 100644 --- a/arch/arm64/kernel/arm64ksyms.c +++ b/arch/arm64/kernel/arm64ksyms.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/arm-smccc.h> | 29 | #include <linux/arm-smccc.h> |
30 | #include <linux/kprobes.h> | ||
30 | 31 | ||
31 | #include <asm/checksum.h> | 32 | #include <asm/checksum.h> |
32 | 33 | ||
@@ -34,8 +35,8 @@ EXPORT_SYMBOL(copy_page); | |||
34 | EXPORT_SYMBOL(clear_page); | 35 | EXPORT_SYMBOL(clear_page); |
35 | 36 | ||
36 | /* user mem (segment) */ | 37 | /* user mem (segment) */ |
37 | EXPORT_SYMBOL(__copy_from_user); | 38 | EXPORT_SYMBOL(__arch_copy_from_user); |
38 | EXPORT_SYMBOL(__copy_to_user); | 39 | EXPORT_SYMBOL(__arch_copy_to_user); |
39 | EXPORT_SYMBOL(__clear_user); | 40 | EXPORT_SYMBOL(__clear_user); |
40 | EXPORT_SYMBOL(__copy_in_user); | 41 | EXPORT_SYMBOL(__copy_in_user); |
41 | 42 | ||
@@ -68,6 +69,7 @@ EXPORT_SYMBOL(test_and_change_bit); | |||
68 | 69 | ||
69 | #ifdef CONFIG_FUNCTION_TRACER | 70 | #ifdef CONFIG_FUNCTION_TRACER |
70 | EXPORT_SYMBOL(_mcount); | 71 | EXPORT_SYMBOL(_mcount); |
72 | NOKPROBE_SYMBOL(_mcount); | ||
71 | #endif | 73 | #endif |
72 | 74 | ||
73 | /* arm-smccc */ | 75 | /* arm-smccc */ |
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c index c37202c0c838..5f72475e2e3b 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c | |||
@@ -316,28 +316,6 @@ static void __init register_insn_emulation_sysctl(struct ctl_table *table) | |||
316 | */ | 316 | */ |
317 | #define TYPE_SWPB (1 << 22) | 317 | #define TYPE_SWPB (1 << 22) |
318 | 318 | ||
319 | /* | ||
320 | * Set up process info to signal segmentation fault - called on access error. | ||
321 | */ | ||
322 | static void set_segfault(struct pt_regs *regs, unsigned long addr) | ||
323 | { | ||
324 | siginfo_t info; | ||
325 | |||
326 | down_read(¤t->mm->mmap_sem); | ||
327 | if (find_vma(current->mm, addr) == NULL) | ||
328 | info.si_code = SEGV_MAPERR; | ||
329 | else | ||
330 | info.si_code = SEGV_ACCERR; | ||
331 | up_read(¤t->mm->mmap_sem); | ||
332 | |||
333 | info.si_signo = SIGSEGV; | ||
334 | info.si_errno = 0; | ||
335 | info.si_addr = (void *) instruction_pointer(regs); | ||
336 | |||
337 | pr_debug("SWP{B} emulation: access caused memory abort!\n"); | ||
338 | arm64_notify_die("Illegal memory access", regs, &info, 0); | ||
339 | } | ||
340 | |||
341 | static int emulate_swpX(unsigned int address, unsigned int *data, | 319 | static int emulate_swpX(unsigned int address, unsigned int *data, |
342 | unsigned int type) | 320 | unsigned int type) |
343 | { | 321 | { |
@@ -366,6 +344,21 @@ static int emulate_swpX(unsigned int address, unsigned int *data, | |||
366 | return res; | 344 | return res; |
367 | } | 345 | } |
368 | 346 | ||
347 | #define ARM_OPCODE_CONDITION_UNCOND 0xf | ||
348 | |||
349 | static unsigned int __kprobes aarch32_check_condition(u32 opcode, u32 psr) | ||
350 | { | ||
351 | u32 cc_bits = opcode >> 28; | ||
352 | |||
353 | if (cc_bits != ARM_OPCODE_CONDITION_UNCOND) { | ||
354 | if ((*aarch32_opcode_cond_checks[cc_bits])(psr)) | ||
355 | return ARM_OPCODE_CONDTEST_PASS; | ||
356 | else | ||
357 | return ARM_OPCODE_CONDTEST_FAIL; | ||
358 | } | ||
359 | return ARM_OPCODE_CONDTEST_UNCOND; | ||
360 | } | ||
361 | |||
369 | /* | 362 | /* |
370 | * swp_handler logs the id of calling process, dissects the instruction, sanity | 363 | * swp_handler logs the id of calling process, dissects the instruction, sanity |
371 | * checks the memory location, calls emulate_swpX for the actual operation and | 364 | * checks the memory location, calls emulate_swpX for the actual operation and |
@@ -380,7 +373,7 @@ static int swp_handler(struct pt_regs *regs, u32 instr) | |||
380 | 373 | ||
381 | type = instr & TYPE_SWPB; | 374 | type = instr & TYPE_SWPB; |
382 | 375 | ||
383 | switch (arm_check_condition(instr, regs->pstate)) { | 376 | switch (aarch32_check_condition(instr, regs->pstate)) { |
384 | case ARM_OPCODE_CONDTEST_PASS: | 377 | case ARM_OPCODE_CONDTEST_PASS: |
385 | break; | 378 | break; |
386 | case ARM_OPCODE_CONDTEST_FAIL: | 379 | case ARM_OPCODE_CONDTEST_FAIL: |
@@ -430,7 +423,8 @@ ret: | |||
430 | return 0; | 423 | return 0; |
431 | 424 | ||
432 | fault: | 425 | fault: |
433 | set_segfault(regs, address); | 426 | pr_debug("SWP{B} emulation: access caused memory abort!\n"); |
427 | arm64_notify_segfault(regs, address); | ||
434 | 428 | ||
435 | return 0; | 429 | return 0; |
436 | } | 430 | } |
@@ -461,7 +455,7 @@ static int cp15barrier_handler(struct pt_regs *regs, u32 instr) | |||
461 | { | 455 | { |
462 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc); | 456 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc); |
463 | 457 | ||
464 | switch (arm_check_condition(instr, regs->pstate)) { | 458 | switch (aarch32_check_condition(instr, regs->pstate)) { |
465 | case ARM_OPCODE_CONDTEST_PASS: | 459 | case ARM_OPCODE_CONDTEST_PASS: |
466 | break; | 460 | break; |
467 | case ARM_OPCODE_CONDTEST_FAIL: | 461 | case ARM_OPCODE_CONDTEST_FAIL: |
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 2f4ba774488a..05070b72fc28 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c | |||
@@ -51,6 +51,17 @@ int main(void) | |||
51 | DEFINE(S_X5, offsetof(struct pt_regs, regs[5])); | 51 | DEFINE(S_X5, offsetof(struct pt_regs, regs[5])); |
52 | DEFINE(S_X6, offsetof(struct pt_regs, regs[6])); | 52 | DEFINE(S_X6, offsetof(struct pt_regs, regs[6])); |
53 | DEFINE(S_X7, offsetof(struct pt_regs, regs[7])); | 53 | DEFINE(S_X7, offsetof(struct pt_regs, regs[7])); |
54 | DEFINE(S_X8, offsetof(struct pt_regs, regs[8])); | ||
55 | DEFINE(S_X10, offsetof(struct pt_regs, regs[10])); | ||
56 | DEFINE(S_X12, offsetof(struct pt_regs, regs[12])); | ||
57 | DEFINE(S_X14, offsetof(struct pt_regs, regs[14])); | ||
58 | DEFINE(S_X16, offsetof(struct pt_regs, regs[16])); | ||
59 | DEFINE(S_X18, offsetof(struct pt_regs, regs[18])); | ||
60 | DEFINE(S_X20, offsetof(struct pt_regs, regs[20])); | ||
61 | DEFINE(S_X22, offsetof(struct pt_regs, regs[22])); | ||
62 | DEFINE(S_X24, offsetof(struct pt_regs, regs[24])); | ||
63 | DEFINE(S_X26, offsetof(struct pt_regs, regs[26])); | ||
64 | DEFINE(S_X28, offsetof(struct pt_regs, regs[28])); | ||
54 | DEFINE(S_LR, offsetof(struct pt_regs, regs[30])); | 65 | DEFINE(S_LR, offsetof(struct pt_regs, regs[30])); |
55 | DEFINE(S_SP, offsetof(struct pt_regs, sp)); | 66 | DEFINE(S_SP, offsetof(struct pt_regs, sp)); |
56 | #ifdef CONFIG_COMPAT | 67 | #ifdef CONFIG_COMPAT |
@@ -78,6 +89,7 @@ int main(void) | |||
78 | BLANK(); | 89 | BLANK(); |
79 | DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); | 90 | DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); |
80 | DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); | 91 | DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); |
92 | DEFINE(CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_RAW); | ||
81 | DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); | 93 | DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); |
82 | DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); | 94 | DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); |
83 | DEFINE(CLOCK_MONOTONIC_COARSE,CLOCK_MONOTONIC_COARSE); | 95 | DEFINE(CLOCK_MONOTONIC_COARSE,CLOCK_MONOTONIC_COARSE); |
@@ -85,6 +97,8 @@ int main(void) | |||
85 | DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); | 97 | DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); |
86 | BLANK(); | 98 | BLANK(); |
87 | DEFINE(VDSO_CS_CYCLE_LAST, offsetof(struct vdso_data, cs_cycle_last)); | 99 | DEFINE(VDSO_CS_CYCLE_LAST, offsetof(struct vdso_data, cs_cycle_last)); |
100 | DEFINE(VDSO_RAW_TIME_SEC, offsetof(struct vdso_data, raw_time_sec)); | ||
101 | DEFINE(VDSO_RAW_TIME_NSEC, offsetof(struct vdso_data, raw_time_nsec)); | ||
88 | DEFINE(VDSO_XTIME_CLK_SEC, offsetof(struct vdso_data, xtime_clock_sec)); | 102 | DEFINE(VDSO_XTIME_CLK_SEC, offsetof(struct vdso_data, xtime_clock_sec)); |
89 | DEFINE(VDSO_XTIME_CLK_NSEC, offsetof(struct vdso_data, xtime_clock_nsec)); | 103 | DEFINE(VDSO_XTIME_CLK_NSEC, offsetof(struct vdso_data, xtime_clock_nsec)); |
90 | DEFINE(VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec)); | 104 | DEFINE(VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec)); |
@@ -92,7 +106,8 @@ int main(void) | |||
92 | DEFINE(VDSO_WTM_CLK_SEC, offsetof(struct vdso_data, wtm_clock_sec)); | 106 | DEFINE(VDSO_WTM_CLK_SEC, offsetof(struct vdso_data, wtm_clock_sec)); |
93 | DEFINE(VDSO_WTM_CLK_NSEC, offsetof(struct vdso_data, wtm_clock_nsec)); | 107 | DEFINE(VDSO_WTM_CLK_NSEC, offsetof(struct vdso_data, wtm_clock_nsec)); |
94 | DEFINE(VDSO_TB_SEQ_COUNT, offsetof(struct vdso_data, tb_seq_count)); | 108 | DEFINE(VDSO_TB_SEQ_COUNT, offsetof(struct vdso_data, tb_seq_count)); |
95 | DEFINE(VDSO_CS_MULT, offsetof(struct vdso_data, cs_mult)); | 109 | DEFINE(VDSO_CS_MONO_MULT, offsetof(struct vdso_data, cs_mono_mult)); |
110 | DEFINE(VDSO_CS_RAW_MULT, offsetof(struct vdso_data, cs_raw_mult)); | ||
96 | DEFINE(VDSO_CS_SHIFT, offsetof(struct vdso_data, cs_shift)); | 111 | DEFINE(VDSO_CS_SHIFT, offsetof(struct vdso_data, cs_shift)); |
97 | DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest)); | 112 | DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest)); |
98 | DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime)); | 113 | DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime)); |
diff --git a/arch/arm64/kernel/cpu-reset.S b/arch/arm64/kernel/cpu-reset.S new file mode 100644 index 000000000000..65f42d257414 --- /dev/null +++ b/arch/arm64/kernel/cpu-reset.S | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * CPU reset routines | ||
3 | * | ||
4 | * Copyright (C) 2001 Deep Blue Solutions Ltd. | ||
5 | * Copyright (C) 2012 ARM Ltd. | ||
6 | * Copyright (C) 2015 Huawei Futurewei Technologies. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/linkage.h> | ||
14 | #include <asm/assembler.h> | ||
15 | #include <asm/sysreg.h> | ||
16 | #include <asm/virt.h> | ||
17 | |||
18 | .text | ||
19 | .pushsection .idmap.text, "ax" | ||
20 | |||
21 | /* | ||
22 | * __cpu_soft_restart(el2_switch, entry, arg0, arg1, arg2) - Helper for | ||
23 | * cpu_soft_restart. | ||
24 | * | ||
25 | * @el2_switch: Flag to indicate a swich to EL2 is needed. | ||
26 | * @entry: Location to jump to for soft reset. | ||
27 | * arg0: First argument passed to @entry. | ||
28 | * arg1: Second argument passed to @entry. | ||
29 | * arg2: Third argument passed to @entry. | ||
30 | * | ||
31 | * Put the CPU into the same state as it would be if it had been reset, and | ||
32 | * branch to what would be the reset vector. It must be executed with the | ||
33 | * flat identity mapping. | ||
34 | */ | ||
35 | ENTRY(__cpu_soft_restart) | ||
36 | /* Clear sctlr_el1 flags. */ | ||
37 | mrs x12, sctlr_el1 | ||
38 | ldr x13, =SCTLR_ELx_FLAGS | ||
39 | bic x12, x12, x13 | ||
40 | msr sctlr_el1, x12 | ||
41 | isb | ||
42 | |||
43 | cbz x0, 1f // el2_switch? | ||
44 | mov x0, #HVC_SOFT_RESTART | ||
45 | hvc #0 // no return | ||
46 | |||
47 | 1: mov x18, x1 // entry | ||
48 | mov x0, x2 // arg0 | ||
49 | mov x1, x3 // arg1 | ||
50 | mov x2, x4 // arg2 | ||
51 | br x18 | ||
52 | ENDPROC(__cpu_soft_restart) | ||
53 | |||
54 | .popsection | ||
diff --git a/arch/arm64/kernel/cpu-reset.h b/arch/arm64/kernel/cpu-reset.h new file mode 100644 index 000000000000..d4e9ecb264f0 --- /dev/null +++ b/arch/arm64/kernel/cpu-reset.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * CPU reset routines | ||
3 | * | ||
4 | * Copyright (C) 2015 Huawei Futurewei Technologies. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef _ARM64_CPU_RESET_H | ||
12 | #define _ARM64_CPU_RESET_H | ||
13 | |||
14 | #include <asm/virt.h> | ||
15 | |||
16 | void __cpu_soft_restart(unsigned long el2_switch, unsigned long entry, | ||
17 | unsigned long arg0, unsigned long arg1, unsigned long arg2); | ||
18 | |||
19 | static inline void __noreturn cpu_soft_restart(unsigned long el2_switch, | ||
20 | unsigned long entry, unsigned long arg0, unsigned long arg1, | ||
21 | unsigned long arg2) | ||
22 | { | ||
23 | typeof(__cpu_soft_restart) *restart; | ||
24 | |||
25 | el2_switch = el2_switch && !is_kernel_in_hyp_mode() && | ||
26 | is_hyp_mode_available(); | ||
27 | restart = (void *)virt_to_phys(__cpu_soft_restart); | ||
28 | |||
29 | cpu_install_idmap(); | ||
30 | restart(el2_switch, entry, arg0, arg1, arg2); | ||
31 | unreachable(); | ||
32 | } | ||
33 | |||
34 | #endif | ||
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index af716b65110d..82b0fc2e637b 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c | |||
@@ -46,6 +46,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = { | |||
46 | .desc = "ARM errata 826319, 827319, 824069", | 46 | .desc = "ARM errata 826319, 827319, 824069", |
47 | .capability = ARM64_WORKAROUND_CLEAN_CACHE, | 47 | .capability = ARM64_WORKAROUND_CLEAN_CACHE, |
48 | MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x02), | 48 | MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x02), |
49 | .enable = cpu_enable_cache_maint_trap, | ||
49 | }, | 50 | }, |
50 | #endif | 51 | #endif |
51 | #ifdef CONFIG_ARM64_ERRATUM_819472 | 52 | #ifdef CONFIG_ARM64_ERRATUM_819472 |
@@ -54,6 +55,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = { | |||
54 | .desc = "ARM errata 819472", | 55 | .desc = "ARM errata 819472", |
55 | .capability = ARM64_WORKAROUND_CLEAN_CACHE, | 56 | .capability = ARM64_WORKAROUND_CLEAN_CACHE, |
56 | MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x01), | 57 | MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x01), |
58 | .enable = cpu_enable_cache_maint_trap, | ||
57 | }, | 59 | }, |
58 | #endif | 60 | #endif |
59 | #ifdef CONFIG_ARM64_ERRATUM_832075 | 61 | #ifdef CONFIG_ARM64_ERRATUM_832075 |
@@ -133,3 +135,8 @@ void check_local_cpu_errata(void) | |||
133 | { | 135 | { |
134 | update_cpu_capabilities(arm64_errata, "enabling workaround for"); | 136 | update_cpu_capabilities(arm64_errata, "enabling workaround for"); |
135 | } | 137 | } |
138 | |||
139 | void __init enable_errata_workarounds(void) | ||
140 | { | ||
141 | enable_cpu_capabilities(arm64_errata); | ||
142 | } | ||
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 811773d1c1d0..916d27ad79c1 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c | |||
@@ -913,8 +913,7 @@ void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps, | |||
913 | * Run through the enabled capabilities and enable() it on all active | 913 | * Run through the enabled capabilities and enable() it on all active |
914 | * CPUs | 914 | * CPUs |
915 | */ | 915 | */ |
916 | static void __init | 916 | void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps) |
917 | enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps) | ||
918 | { | 917 | { |
919 | for (; caps->matches; caps++) | 918 | for (; caps->matches; caps++) |
920 | if (caps->enable && cpus_have_cap(caps->capability)) | 919 | if (caps->enable && cpus_have_cap(caps->capability)) |
@@ -1036,6 +1035,7 @@ void __init setup_cpu_features(void) | |||
1036 | 1035 | ||
1037 | /* Set the CPU feature capabilies */ | 1036 | /* Set the CPU feature capabilies */ |
1038 | setup_feature_capabilities(); | 1037 | setup_feature_capabilities(); |
1038 | enable_errata_workarounds(); | ||
1039 | setup_elf_hwcaps(arm64_elf_hwcaps); | 1039 | setup_elf_hwcaps(arm64_elf_hwcaps); |
1040 | 1040 | ||
1041 | if (system_supports_32bit_el0()) | 1041 | if (system_supports_32bit_el0()) |
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index c173d329397f..ed1b84fe6925 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c | |||
@@ -183,6 +183,123 @@ const struct seq_operations cpuinfo_op = { | |||
183 | .show = c_show | 183 | .show = c_show |
184 | }; | 184 | }; |
185 | 185 | ||
186 | |||
187 | static struct kobj_type cpuregs_kobj_type = { | ||
188 | .sysfs_ops = &kobj_sysfs_ops, | ||
189 | }; | ||
190 | |||
191 | /* | ||
192 | * The ARM ARM uses the phrase "32-bit register" to describe a register | ||
193 | * whose upper 32 bits are RES0 (per C5.1.1, ARM DDI 0487A.i), however | ||
194 | * no statement is made as to whether the upper 32 bits will or will not | ||
195 | * be made use of in future, and between ARM DDI 0487A.c and ARM DDI | ||
196 | * 0487A.d CLIDR_EL1 was expanded from 32-bit to 64-bit. | ||
197 | * | ||
198 | * Thus, while both MIDR_EL1 and REVIDR_EL1 are described as 32-bit | ||
199 | * registers, we expose them both as 64 bit values to cater for possible | ||
200 | * future expansion without an ABI break. | ||
201 | */ | ||
202 | #define kobj_to_cpuinfo(kobj) container_of(kobj, struct cpuinfo_arm64, kobj) | ||
203 | #define CPUREGS_ATTR_RO(_name, _field) \ | ||
204 | static ssize_t _name##_show(struct kobject *kobj, \ | ||
205 | struct kobj_attribute *attr, char *buf) \ | ||
206 | { \ | ||
207 | struct cpuinfo_arm64 *info = kobj_to_cpuinfo(kobj); \ | ||
208 | \ | ||
209 | if (info->reg_midr) \ | ||
210 | return sprintf(buf, "0x%016x\n", info->reg_##_field); \ | ||
211 | else \ | ||
212 | return 0; \ | ||
213 | } \ | ||
214 | static struct kobj_attribute cpuregs_attr_##_name = __ATTR_RO(_name) | ||
215 | |||
216 | CPUREGS_ATTR_RO(midr_el1, midr); | ||
217 | CPUREGS_ATTR_RO(revidr_el1, revidr); | ||
218 | |||
219 | static struct attribute *cpuregs_id_attrs[] = { | ||
220 | &cpuregs_attr_midr_el1.attr, | ||
221 | &cpuregs_attr_revidr_el1.attr, | ||
222 | NULL | ||
223 | }; | ||
224 | |||
225 | static struct attribute_group cpuregs_attr_group = { | ||
226 | .attrs = cpuregs_id_attrs, | ||
227 | .name = "identification" | ||
228 | }; | ||
229 | |||
230 | static int cpuid_add_regs(int cpu) | ||
231 | { | ||
232 | int rc; | ||
233 | struct device *dev; | ||
234 | struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu); | ||
235 | |||
236 | dev = get_cpu_device(cpu); | ||
237 | if (!dev) { | ||
238 | rc = -ENODEV; | ||
239 | goto out; | ||
240 | } | ||
241 | rc = kobject_add(&info->kobj, &dev->kobj, "regs"); | ||
242 | if (rc) | ||
243 | goto out; | ||
244 | rc = sysfs_create_group(&info->kobj, &cpuregs_attr_group); | ||
245 | if (rc) | ||
246 | kobject_del(&info->kobj); | ||
247 | out: | ||
248 | return rc; | ||
249 | } | ||
250 | |||
251 | static int cpuid_remove_regs(int cpu) | ||
252 | { | ||
253 | struct device *dev; | ||
254 | struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu); | ||
255 | |||
256 | dev = get_cpu_device(cpu); | ||
257 | if (!dev) | ||
258 | return -ENODEV; | ||
259 | if (info->kobj.parent) { | ||
260 | sysfs_remove_group(&info->kobj, &cpuregs_attr_group); | ||
261 | kobject_del(&info->kobj); | ||
262 | } | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static int cpuid_callback(struct notifier_block *nb, | ||
268 | unsigned long action, void *hcpu) | ||
269 | { | ||
270 | int rc = 0; | ||
271 | unsigned long cpu = (unsigned long)hcpu; | ||
272 | |||
273 | switch (action & ~CPU_TASKS_FROZEN) { | ||
274 | case CPU_ONLINE: | ||
275 | rc = cpuid_add_regs(cpu); | ||
276 | break; | ||
277 | case CPU_DEAD: | ||
278 | rc = cpuid_remove_regs(cpu); | ||
279 | break; | ||
280 | } | ||
281 | |||
282 | return notifier_from_errno(rc); | ||
283 | } | ||
284 | |||
285 | static int __init cpuinfo_regs_init(void) | ||
286 | { | ||
287 | int cpu; | ||
288 | |||
289 | cpu_notifier_register_begin(); | ||
290 | |||
291 | for_each_possible_cpu(cpu) { | ||
292 | struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu); | ||
293 | |||
294 | kobject_init(&info->kobj, &cpuregs_kobj_type); | ||
295 | if (cpu_online(cpu)) | ||
296 | cpuid_add_regs(cpu); | ||
297 | } | ||
298 | __hotcpu_notifier(cpuid_callback, 0); | ||
299 | |||
300 | cpu_notifier_register_done(); | ||
301 | return 0; | ||
302 | } | ||
186 | static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info) | 303 | static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info) |
187 | { | 304 | { |
188 | unsigned int cpu = smp_processor_id(); | 305 | unsigned int cpu = smp_processor_id(); |
@@ -212,6 +329,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) | |||
212 | info->reg_ctr = read_cpuid_cachetype(); | 329 | info->reg_ctr = read_cpuid_cachetype(); |
213 | info->reg_dczid = read_cpuid(DCZID_EL0); | 330 | info->reg_dczid = read_cpuid(DCZID_EL0); |
214 | info->reg_midr = read_cpuid_id(); | 331 | info->reg_midr = read_cpuid_id(); |
332 | info->reg_revidr = read_cpuid(REVIDR_EL1); | ||
215 | 333 | ||
216 | info->reg_id_aa64dfr0 = read_cpuid(ID_AA64DFR0_EL1); | 334 | info->reg_id_aa64dfr0 = read_cpuid(ID_AA64DFR0_EL1); |
217 | info->reg_id_aa64dfr1 = read_cpuid(ID_AA64DFR1_EL1); | 335 | info->reg_id_aa64dfr1 = read_cpuid(ID_AA64DFR1_EL1); |
@@ -264,3 +382,5 @@ void __init cpuinfo_store_boot_cpu(void) | |||
264 | boot_cpu_data = *info; | 382 | boot_cpu_data = *info; |
265 | init_cpu_features(&boot_cpu_data); | 383 | init_cpu_features(&boot_cpu_data); |
266 | } | 384 | } |
385 | |||
386 | device_initcall(cpuinfo_regs_init); | ||
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 4fbf3c54275c..91fff48d0f57 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/hardirq.h> | 23 | #include <linux/hardirq.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
26 | #include <linux/kprobes.h> | ||
26 | #include <linux/stat.h> | 27 | #include <linux/stat.h> |
27 | #include <linux/uaccess.h> | 28 | #include <linux/uaccess.h> |
28 | 29 | ||
@@ -48,6 +49,7 @@ static void mdscr_write(u32 mdscr) | |||
48 | asm volatile("msr mdscr_el1, %0" :: "r" (mdscr)); | 49 | asm volatile("msr mdscr_el1, %0" :: "r" (mdscr)); |
49 | local_dbg_restore(flags); | 50 | local_dbg_restore(flags); |
50 | } | 51 | } |
52 | NOKPROBE_SYMBOL(mdscr_write); | ||
51 | 53 | ||
52 | static u32 mdscr_read(void) | 54 | static u32 mdscr_read(void) |
53 | { | 55 | { |
@@ -55,6 +57,7 @@ static u32 mdscr_read(void) | |||
55 | asm volatile("mrs %0, mdscr_el1" : "=r" (mdscr)); | 57 | asm volatile("mrs %0, mdscr_el1" : "=r" (mdscr)); |
56 | return mdscr; | 58 | return mdscr; |
57 | } | 59 | } |
60 | NOKPROBE_SYMBOL(mdscr_read); | ||
58 | 61 | ||
59 | /* | 62 | /* |
60 | * Allow root to disable self-hosted debug from userspace. | 63 | * Allow root to disable self-hosted debug from userspace. |
@@ -103,6 +106,7 @@ void enable_debug_monitors(enum dbg_active_el el) | |||
103 | mdscr_write(mdscr); | 106 | mdscr_write(mdscr); |
104 | } | 107 | } |
105 | } | 108 | } |
109 | NOKPROBE_SYMBOL(enable_debug_monitors); | ||
106 | 110 | ||
107 | void disable_debug_monitors(enum dbg_active_el el) | 111 | void disable_debug_monitors(enum dbg_active_el el) |
108 | { | 112 | { |
@@ -123,6 +127,7 @@ void disable_debug_monitors(enum dbg_active_el el) | |||
123 | mdscr_write(mdscr); | 127 | mdscr_write(mdscr); |
124 | } | 128 | } |
125 | } | 129 | } |
130 | NOKPROBE_SYMBOL(disable_debug_monitors); | ||
126 | 131 | ||
127 | /* | 132 | /* |
128 | * OS lock clearing. | 133 | * OS lock clearing. |
@@ -151,7 +156,6 @@ static int debug_monitors_init(void) | |||
151 | /* Clear the OS lock. */ | 156 | /* Clear the OS lock. */ |
152 | on_each_cpu(clear_os_lock, NULL, 1); | 157 | on_each_cpu(clear_os_lock, NULL, 1); |
153 | isb(); | 158 | isb(); |
154 | local_dbg_enable(); | ||
155 | 159 | ||
156 | /* Register hotplug handler. */ | 160 | /* Register hotplug handler. */ |
157 | __register_cpu_notifier(&os_lock_nb); | 161 | __register_cpu_notifier(&os_lock_nb); |
@@ -166,22 +170,15 @@ postcore_initcall(debug_monitors_init); | |||
166 | */ | 170 | */ |
167 | static void set_regs_spsr_ss(struct pt_regs *regs) | 171 | static void set_regs_spsr_ss(struct pt_regs *regs) |
168 | { | 172 | { |
169 | unsigned long spsr; | 173 | regs->pstate |= DBG_SPSR_SS; |
170 | |||
171 | spsr = regs->pstate; | ||
172 | spsr &= ~DBG_SPSR_SS; | ||
173 | spsr |= DBG_SPSR_SS; | ||
174 | regs->pstate = spsr; | ||
175 | } | 174 | } |
175 | NOKPROBE_SYMBOL(set_regs_spsr_ss); | ||
176 | 176 | ||
177 | static void clear_regs_spsr_ss(struct pt_regs *regs) | 177 | static void clear_regs_spsr_ss(struct pt_regs *regs) |
178 | { | 178 | { |
179 | unsigned long spsr; | 179 | regs->pstate &= ~DBG_SPSR_SS; |
180 | |||
181 | spsr = regs->pstate; | ||
182 | spsr &= ~DBG_SPSR_SS; | ||
183 | regs->pstate = spsr; | ||
184 | } | 180 | } |
181 | NOKPROBE_SYMBOL(clear_regs_spsr_ss); | ||
185 | 182 | ||
186 | /* EL1 Single Step Handler hooks */ | 183 | /* EL1 Single Step Handler hooks */ |
187 | static LIST_HEAD(step_hook); | 184 | static LIST_HEAD(step_hook); |
@@ -225,6 +222,7 @@ static int call_step_hook(struct pt_regs *regs, unsigned int esr) | |||
225 | 222 | ||
226 | return retval; | 223 | return retval; |
227 | } | 224 | } |
225 | NOKPROBE_SYMBOL(call_step_hook); | ||
228 | 226 | ||
229 | static void send_user_sigtrap(int si_code) | 227 | static void send_user_sigtrap(int si_code) |
230 | { | 228 | { |
@@ -266,6 +264,10 @@ static int single_step_handler(unsigned long addr, unsigned int esr, | |||
266 | */ | 264 | */ |
267 | user_rewind_single_step(current); | 265 | user_rewind_single_step(current); |
268 | } else { | 266 | } else { |
267 | #ifdef CONFIG_KPROBES | ||
268 | if (kprobe_single_step_handler(regs, esr) == DBG_HOOK_HANDLED) | ||
269 | return 0; | ||
270 | #endif | ||
269 | if (call_step_hook(regs, esr) == DBG_HOOK_HANDLED) | 271 | if (call_step_hook(regs, esr) == DBG_HOOK_HANDLED) |
270 | return 0; | 272 | return 0; |
271 | 273 | ||
@@ -279,6 +281,7 @@ static int single_step_handler(unsigned long addr, unsigned int esr, | |||
279 | 281 | ||
280 | return 0; | 282 | return 0; |
281 | } | 283 | } |
284 | NOKPROBE_SYMBOL(single_step_handler); | ||
282 | 285 | ||
283 | /* | 286 | /* |
284 | * Breakpoint handler is re-entrant as another breakpoint can | 287 | * Breakpoint handler is re-entrant as another breakpoint can |
@@ -316,19 +319,28 @@ static int call_break_hook(struct pt_regs *regs, unsigned int esr) | |||
316 | 319 | ||
317 | return fn ? fn(regs, esr) : DBG_HOOK_ERROR; | 320 | return fn ? fn(regs, esr) : DBG_HOOK_ERROR; |
318 | } | 321 | } |
322 | NOKPROBE_SYMBOL(call_break_hook); | ||
319 | 323 | ||
320 | static int brk_handler(unsigned long addr, unsigned int esr, | 324 | static int brk_handler(unsigned long addr, unsigned int esr, |
321 | struct pt_regs *regs) | 325 | struct pt_regs *regs) |
322 | { | 326 | { |
323 | if (user_mode(regs)) { | 327 | if (user_mode(regs)) { |
324 | send_user_sigtrap(TRAP_BRKPT); | 328 | send_user_sigtrap(TRAP_BRKPT); |
325 | } else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) { | 329 | } |
326 | pr_warning("Unexpected kernel BRK exception at EL1\n"); | 330 | #ifdef CONFIG_KPROBES |
331 | else if ((esr & BRK64_ESR_MASK) == BRK64_ESR_KPROBES) { | ||
332 | if (kprobe_breakpoint_handler(regs, esr) != DBG_HOOK_HANDLED) | ||
333 | return -EFAULT; | ||
334 | } | ||
335 | #endif | ||
336 | else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) { | ||
337 | pr_warn("Unexpected kernel BRK exception at EL1\n"); | ||
327 | return -EFAULT; | 338 | return -EFAULT; |
328 | } | 339 | } |
329 | 340 | ||
330 | return 0; | 341 | return 0; |
331 | } | 342 | } |
343 | NOKPROBE_SYMBOL(brk_handler); | ||
332 | 344 | ||
333 | int aarch32_break_handler(struct pt_regs *regs) | 345 | int aarch32_break_handler(struct pt_regs *regs) |
334 | { | 346 | { |
@@ -365,6 +377,7 @@ int aarch32_break_handler(struct pt_regs *regs) | |||
365 | send_user_sigtrap(TRAP_BRKPT); | 377 | send_user_sigtrap(TRAP_BRKPT); |
366 | return 0; | 378 | return 0; |
367 | } | 379 | } |
380 | NOKPROBE_SYMBOL(aarch32_break_handler); | ||
368 | 381 | ||
369 | static int __init debug_traps_init(void) | 382 | static int __init debug_traps_init(void) |
370 | { | 383 | { |
@@ -386,6 +399,7 @@ void user_rewind_single_step(struct task_struct *task) | |||
386 | if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP)) | 399 | if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP)) |
387 | set_regs_spsr_ss(task_pt_regs(task)); | 400 | set_regs_spsr_ss(task_pt_regs(task)); |
388 | } | 401 | } |
402 | NOKPROBE_SYMBOL(user_rewind_single_step); | ||
389 | 403 | ||
390 | void user_fastforward_single_step(struct task_struct *task) | 404 | void user_fastforward_single_step(struct task_struct *task) |
391 | { | 405 | { |
@@ -401,6 +415,7 @@ void kernel_enable_single_step(struct pt_regs *regs) | |||
401 | mdscr_write(mdscr_read() | DBG_MDSCR_SS); | 415 | mdscr_write(mdscr_read() | DBG_MDSCR_SS); |
402 | enable_debug_monitors(DBG_ACTIVE_EL1); | 416 | enable_debug_monitors(DBG_ACTIVE_EL1); |
403 | } | 417 | } |
418 | NOKPROBE_SYMBOL(kernel_enable_single_step); | ||
404 | 419 | ||
405 | void kernel_disable_single_step(void) | 420 | void kernel_disable_single_step(void) |
406 | { | 421 | { |
@@ -408,12 +423,14 @@ void kernel_disable_single_step(void) | |||
408 | mdscr_write(mdscr_read() & ~DBG_MDSCR_SS); | 423 | mdscr_write(mdscr_read() & ~DBG_MDSCR_SS); |
409 | disable_debug_monitors(DBG_ACTIVE_EL1); | 424 | disable_debug_monitors(DBG_ACTIVE_EL1); |
410 | } | 425 | } |
426 | NOKPROBE_SYMBOL(kernel_disable_single_step); | ||
411 | 427 | ||
412 | int kernel_active_single_step(void) | 428 | int kernel_active_single_step(void) |
413 | { | 429 | { |
414 | WARN_ON(!irqs_disabled()); | 430 | WARN_ON(!irqs_disabled()); |
415 | return mdscr_read() & DBG_MDSCR_SS; | 431 | return mdscr_read() & DBG_MDSCR_SS; |
416 | } | 432 | } |
433 | NOKPROBE_SYMBOL(kernel_active_single_step); | ||
417 | 434 | ||
418 | /* ptrace API */ | 435 | /* ptrace API */ |
419 | void user_enable_single_step(struct task_struct *task) | 436 | void user_enable_single_step(struct task_struct *task) |
@@ -421,8 +438,10 @@ void user_enable_single_step(struct task_struct *task) | |||
421 | set_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP); | 438 | set_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP); |
422 | set_regs_spsr_ss(task_pt_regs(task)); | 439 | set_regs_spsr_ss(task_pt_regs(task)); |
423 | } | 440 | } |
441 | NOKPROBE_SYMBOL(user_enable_single_step); | ||
424 | 442 | ||
425 | void user_disable_single_step(struct task_struct *task) | 443 | void user_disable_single_step(struct task_struct *task) |
426 | { | 444 | { |
427 | clear_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP); | 445 | clear_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP); |
428 | } | 446 | } |
447 | NOKPROBE_SYMBOL(user_disable_single_step); | ||
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 78f52488f9ff..ba9bee389fd5 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c | |||
@@ -62,13 +62,61 @@ struct screen_info screen_info __section(.data); | |||
62 | int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) | 62 | int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) |
63 | { | 63 | { |
64 | pteval_t prot_val = create_mapping_protection(md); | 64 | pteval_t prot_val = create_mapping_protection(md); |
65 | bool allow_block_mappings = (md->type != EFI_RUNTIME_SERVICES_CODE && | ||
66 | md->type != EFI_RUNTIME_SERVICES_DATA); | ||
67 | |||
68 | if (!PAGE_ALIGNED(md->phys_addr) || | ||
69 | !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT)) { | ||
70 | /* | ||
71 | * If the end address of this region is not aligned to page | ||
72 | * size, the mapping is rounded up, and may end up sharing a | ||
73 | * page frame with the next UEFI memory region. If we create | ||
74 | * a block entry now, we may need to split it again when mapping | ||
75 | * the next region, and support for that is going to be removed | ||
76 | * from the MMU routines. So avoid block mappings altogether in | ||
77 | * that case. | ||
78 | */ | ||
79 | allow_block_mappings = false; | ||
80 | } | ||
65 | 81 | ||
66 | create_pgd_mapping(mm, md->phys_addr, md->virt_addr, | 82 | create_pgd_mapping(mm, md->phys_addr, md->virt_addr, |
67 | md->num_pages << EFI_PAGE_SHIFT, | 83 | md->num_pages << EFI_PAGE_SHIFT, |
68 | __pgprot(prot_val | PTE_NG)); | 84 | __pgprot(prot_val | PTE_NG), allow_block_mappings); |
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int __init set_permissions(pte_t *ptep, pgtable_t token, | ||
89 | unsigned long addr, void *data) | ||
90 | { | ||
91 | efi_memory_desc_t *md = data; | ||
92 | pte_t pte = *ptep; | ||
93 | |||
94 | if (md->attribute & EFI_MEMORY_RO) | ||
95 | pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); | ||
96 | if (md->attribute & EFI_MEMORY_XP) | ||
97 | pte = set_pte_bit(pte, __pgprot(PTE_PXN)); | ||
98 | set_pte(ptep, pte); | ||
69 | return 0; | 99 | return 0; |
70 | } | 100 | } |
71 | 101 | ||
102 | int __init efi_set_mapping_permissions(struct mm_struct *mm, | ||
103 | efi_memory_desc_t *md) | ||
104 | { | ||
105 | BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE && | ||
106 | md->type != EFI_RUNTIME_SERVICES_DATA); | ||
107 | |||
108 | /* | ||
109 | * Calling apply_to_page_range() is only safe on regions that are | ||
110 | * guaranteed to be mapped down to pages. Since we are only called | ||
111 | * for regions that have been mapped using efi_create_mapping() above | ||
112 | * (and this is checked by the generic Memory Attributes table parsing | ||
113 | * routines), there is no need to check that again here. | ||
114 | */ | ||
115 | return apply_to_page_range(mm, md->virt_addr, | ||
116 | md->num_pages << EFI_PAGE_SHIFT, | ||
117 | set_permissions, md); | ||
118 | } | ||
119 | |||
72 | static int __init arm64_dmi_init(void) | 120 | static int __init arm64_dmi_init(void) |
73 | { | 121 | { |
74 | /* | 122 | /* |
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 6c3b7345a6c4..96e4a2b64cc1 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S | |||
@@ -258,6 +258,7 @@ tsk .req x28 // current thread_info | |||
258 | /* | 258 | /* |
259 | * Exception vectors. | 259 | * Exception vectors. |
260 | */ | 260 | */ |
261 | .pushsection ".entry.text", "ax" | ||
261 | 262 | ||
262 | .align 11 | 263 | .align 11 |
263 | ENTRY(vectors) | 264 | ENTRY(vectors) |
@@ -466,7 +467,7 @@ el0_sync: | |||
466 | cmp x24, #ESR_ELx_EC_FP_EXC64 // FP/ASIMD exception | 467 | cmp x24, #ESR_ELx_EC_FP_EXC64 // FP/ASIMD exception |
467 | b.eq el0_fpsimd_exc | 468 | b.eq el0_fpsimd_exc |
468 | cmp x24, #ESR_ELx_EC_SYS64 // configurable trap | 469 | cmp x24, #ESR_ELx_EC_SYS64 // configurable trap |
469 | b.eq el0_undef | 470 | b.eq el0_sys |
470 | cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception | 471 | cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception |
471 | b.eq el0_sp_pc | 472 | b.eq el0_sp_pc |
472 | cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception | 473 | cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception |
@@ -547,7 +548,7 @@ el0_ia: | |||
547 | enable_dbg_and_irq | 548 | enable_dbg_and_irq |
548 | ct_user_exit | 549 | ct_user_exit |
549 | mov x0, x26 | 550 | mov x0, x26 |
550 | orr x1, x25, #1 << 24 // use reserved ISS bit for instruction aborts | 551 | mov x1, x25 |
551 | mov x2, sp | 552 | mov x2, sp |
552 | bl do_mem_abort | 553 | bl do_mem_abort |
553 | b ret_to_user | 554 | b ret_to_user |
@@ -594,6 +595,16 @@ el0_undef: | |||
594 | mov x0, sp | 595 | mov x0, sp |
595 | bl do_undefinstr | 596 | bl do_undefinstr |
596 | b ret_to_user | 597 | b ret_to_user |
598 | el0_sys: | ||
599 | /* | ||
600 | * System instructions, for trapped cache maintenance instructions | ||
601 | */ | ||
602 | enable_dbg_and_irq | ||
603 | ct_user_exit | ||
604 | mov x0, x25 | ||
605 | mov x1, sp | ||
606 | bl do_sysinstr | ||
607 | b ret_to_user | ||
597 | el0_dbg: | 608 | el0_dbg: |
598 | /* | 609 | /* |
599 | * Debug exception handling | 610 | * Debug exception handling |
@@ -789,6 +800,8 @@ __ni_sys_trace: | |||
789 | bl do_ni_syscall | 800 | bl do_ni_syscall |
790 | b __sys_trace_return | 801 | b __sys_trace_return |
791 | 802 | ||
803 | .popsection // .entry.text | ||
804 | |||
792 | /* | 805 | /* |
793 | * Special system call wrappers. | 806 | * Special system call wrappers. |
794 | */ | 807 | */ |
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c index ce21aa88263f..26a6bf77d272 100644 --- a/arch/arm64/kernel/hw_breakpoint.c +++ b/arch/arm64/kernel/hw_breakpoint.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/cpu_pm.h> | 24 | #include <linux/cpu_pm.h> |
25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
26 | #include <linux/hw_breakpoint.h> | 26 | #include <linux/hw_breakpoint.h> |
27 | #include <linux/kprobes.h> | ||
27 | #include <linux/perf_event.h> | 28 | #include <linux/perf_event.h> |
28 | #include <linux/ptrace.h> | 29 | #include <linux/ptrace.h> |
29 | #include <linux/smp.h> | 30 | #include <linux/smp.h> |
@@ -127,6 +128,7 @@ static u64 read_wb_reg(int reg, int n) | |||
127 | 128 | ||
128 | return val; | 129 | return val; |
129 | } | 130 | } |
131 | NOKPROBE_SYMBOL(read_wb_reg); | ||
130 | 132 | ||
131 | static void write_wb_reg(int reg, int n, u64 val) | 133 | static void write_wb_reg(int reg, int n, u64 val) |
132 | { | 134 | { |
@@ -140,6 +142,7 @@ static void write_wb_reg(int reg, int n, u64 val) | |||
140 | } | 142 | } |
141 | isb(); | 143 | isb(); |
142 | } | 144 | } |
145 | NOKPROBE_SYMBOL(write_wb_reg); | ||
143 | 146 | ||
144 | /* | 147 | /* |
145 | * Convert a breakpoint privilege level to the corresponding exception | 148 | * Convert a breakpoint privilege level to the corresponding exception |
@@ -157,6 +160,7 @@ static enum dbg_active_el debug_exception_level(int privilege) | |||
157 | return -EINVAL; | 160 | return -EINVAL; |
158 | } | 161 | } |
159 | } | 162 | } |
163 | NOKPROBE_SYMBOL(debug_exception_level); | ||
160 | 164 | ||
161 | enum hw_breakpoint_ops { | 165 | enum hw_breakpoint_ops { |
162 | HW_BREAKPOINT_INSTALL, | 166 | HW_BREAKPOINT_INSTALL, |
@@ -575,6 +579,7 @@ static void toggle_bp_registers(int reg, enum dbg_active_el el, int enable) | |||
575 | write_wb_reg(reg, i, ctrl); | 579 | write_wb_reg(reg, i, ctrl); |
576 | } | 580 | } |
577 | } | 581 | } |
582 | NOKPROBE_SYMBOL(toggle_bp_registers); | ||
578 | 583 | ||
579 | /* | 584 | /* |
580 | * Debug exception handlers. | 585 | * Debug exception handlers. |
@@ -654,6 +659,7 @@ unlock: | |||
654 | 659 | ||
655 | return 0; | 660 | return 0; |
656 | } | 661 | } |
662 | NOKPROBE_SYMBOL(breakpoint_handler); | ||
657 | 663 | ||
658 | static int watchpoint_handler(unsigned long addr, unsigned int esr, | 664 | static int watchpoint_handler(unsigned long addr, unsigned int esr, |
659 | struct pt_regs *regs) | 665 | struct pt_regs *regs) |
@@ -756,6 +762,7 @@ unlock: | |||
756 | 762 | ||
757 | return 0; | 763 | return 0; |
758 | } | 764 | } |
765 | NOKPROBE_SYMBOL(watchpoint_handler); | ||
759 | 766 | ||
760 | /* | 767 | /* |
761 | * Handle single-step exception. | 768 | * Handle single-step exception. |
@@ -813,6 +820,7 @@ int reinstall_suspended_bps(struct pt_regs *regs) | |||
813 | 820 | ||
814 | return !handled_exception; | 821 | return !handled_exception; |
815 | } | 822 | } |
823 | NOKPROBE_SYMBOL(reinstall_suspended_bps); | ||
816 | 824 | ||
817 | /* | 825 | /* |
818 | * Context-switcher for restoring suspended breakpoints. | 826 | * Context-switcher for restoring suspended breakpoints. |
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S index 8727f4490772..d3b5f75e652e 100644 --- a/arch/arm64/kernel/hyp-stub.S +++ b/arch/arm64/kernel/hyp-stub.S | |||
@@ -71,8 +71,16 @@ el1_sync: | |||
71 | msr vbar_el2, x1 | 71 | msr vbar_el2, x1 |
72 | b 9f | 72 | b 9f |
73 | 73 | ||
74 | 2: cmp x0, #HVC_SOFT_RESTART | ||
75 | b.ne 3f | ||
76 | mov x0, x2 | ||
77 | mov x2, x4 | ||
78 | mov x4, x1 | ||
79 | mov x1, x3 | ||
80 | br x4 // no return | ||
81 | |||
74 | /* Someone called kvm_call_hyp() against the hyp-stub... */ | 82 | /* Someone called kvm_call_hyp() against the hyp-stub... */ |
75 | 2: mov x0, #ARM_EXCEPTION_HYP_GONE | 83 | 3: mov x0, #ARM_EXCEPTION_HYP_GONE |
76 | 84 | ||
77 | 9: eret | 85 | 9: eret |
78 | ENDPROC(el1_sync) | 86 | ENDPROC(el1_sync) |
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index 368c08290dd8..63f9432d05e8 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/cacheflush.h> | 30 | #include <asm/cacheflush.h> |
31 | #include <asm/debug-monitors.h> | 31 | #include <asm/debug-monitors.h> |
32 | #include <asm/fixmap.h> | 32 | #include <asm/fixmap.h> |
33 | #include <asm/opcodes.h> | ||
33 | #include <asm/insn.h> | 34 | #include <asm/insn.h> |
34 | 35 | ||
35 | #define AARCH64_INSN_SF_BIT BIT(31) | 36 | #define AARCH64_INSN_SF_BIT BIT(31) |
@@ -162,6 +163,32 @@ static bool __kprobes __aarch64_insn_hotpatch_safe(u32 insn) | |||
162 | aarch64_insn_is_nop(insn); | 163 | aarch64_insn_is_nop(insn); |
163 | } | 164 | } |
164 | 165 | ||
166 | bool __kprobes aarch64_insn_uses_literal(u32 insn) | ||
167 | { | ||
168 | /* ldr/ldrsw (literal), prfm */ | ||
169 | |||
170 | return aarch64_insn_is_ldr_lit(insn) || | ||
171 | aarch64_insn_is_ldrsw_lit(insn) || | ||
172 | aarch64_insn_is_adr_adrp(insn) || | ||
173 | aarch64_insn_is_prfm_lit(insn); | ||
174 | } | ||
175 | |||
176 | bool __kprobes aarch64_insn_is_branch(u32 insn) | ||
177 | { | ||
178 | /* b, bl, cb*, tb*, b.cond, br, blr */ | ||
179 | |||
180 | return aarch64_insn_is_b(insn) || | ||
181 | aarch64_insn_is_bl(insn) || | ||
182 | aarch64_insn_is_cbz(insn) || | ||
183 | aarch64_insn_is_cbnz(insn) || | ||
184 | aarch64_insn_is_tbz(insn) || | ||
185 | aarch64_insn_is_tbnz(insn) || | ||
186 | aarch64_insn_is_ret(insn) || | ||
187 | aarch64_insn_is_br(insn) || | ||
188 | aarch64_insn_is_blr(insn) || | ||
189 | aarch64_insn_is_bcond(insn); | ||
190 | } | ||
191 | |||
165 | /* | 192 | /* |
166 | * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a | 193 | * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a |
167 | * Section B2.6.5 "Concurrent modification and execution of instructions": | 194 | * Section B2.6.5 "Concurrent modification and execution of instructions": |
@@ -1175,6 +1202,14 @@ u32 aarch64_set_branch_offset(u32 insn, s32 offset) | |||
1175 | BUG(); | 1202 | BUG(); |
1176 | } | 1203 | } |
1177 | 1204 | ||
1205 | /* | ||
1206 | * Extract the Op/CR data from a msr/mrs instruction. | ||
1207 | */ | ||
1208 | u32 aarch64_insn_extract_system_reg(u32 insn) | ||
1209 | { | ||
1210 | return (insn & 0x1FFFE0) >> 5; | ||
1211 | } | ||
1212 | |||
1178 | bool aarch32_insn_is_wide(u32 insn) | 1213 | bool aarch32_insn_is_wide(u32 insn) |
1179 | { | 1214 | { |
1180 | return insn >= 0xe800; | 1215 | return insn >= 0xe800; |
@@ -1200,3 +1235,101 @@ u32 aarch32_insn_mcr_extract_crm(u32 insn) | |||
1200 | { | 1235 | { |
1201 | return insn & CRM_MASK; | 1236 | return insn & CRM_MASK; |
1202 | } | 1237 | } |
1238 | |||
1239 | static bool __kprobes __check_eq(unsigned long pstate) | ||
1240 | { | ||
1241 | return (pstate & PSR_Z_BIT) != 0; | ||
1242 | } | ||
1243 | |||
1244 | static bool __kprobes __check_ne(unsigned long pstate) | ||
1245 | { | ||
1246 | return (pstate & PSR_Z_BIT) == 0; | ||
1247 | } | ||
1248 | |||
1249 | static bool __kprobes __check_cs(unsigned long pstate) | ||
1250 | { | ||
1251 | return (pstate & PSR_C_BIT) != 0; | ||
1252 | } | ||
1253 | |||
1254 | static bool __kprobes __check_cc(unsigned long pstate) | ||
1255 | { | ||
1256 | return (pstate & PSR_C_BIT) == 0; | ||
1257 | } | ||
1258 | |||
1259 | static bool __kprobes __check_mi(unsigned long pstate) | ||
1260 | { | ||
1261 | return (pstate & PSR_N_BIT) != 0; | ||
1262 | } | ||
1263 | |||
1264 | static bool __kprobes __check_pl(unsigned long pstate) | ||
1265 | { | ||
1266 | return (pstate & PSR_N_BIT) == 0; | ||
1267 | } | ||
1268 | |||
1269 | static bool __kprobes __check_vs(unsigned long pstate) | ||
1270 | { | ||
1271 | return (pstate & PSR_V_BIT) != 0; | ||
1272 | } | ||
1273 | |||
1274 | static bool __kprobes __check_vc(unsigned long pstate) | ||
1275 | { | ||
1276 | return (pstate & PSR_V_BIT) == 0; | ||
1277 | } | ||
1278 | |||
1279 | static bool __kprobes __check_hi(unsigned long pstate) | ||
1280 | { | ||
1281 | pstate &= ~(pstate >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ | ||
1282 | return (pstate & PSR_C_BIT) != 0; | ||
1283 | } | ||
1284 | |||
1285 | static bool __kprobes __check_ls(unsigned long pstate) | ||
1286 | { | ||
1287 | pstate &= ~(pstate >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ | ||
1288 | return (pstate & PSR_C_BIT) == 0; | ||
1289 | } | ||
1290 | |||
1291 | static bool __kprobes __check_ge(unsigned long pstate) | ||
1292 | { | ||
1293 | pstate ^= (pstate << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | ||
1294 | return (pstate & PSR_N_BIT) == 0; | ||
1295 | } | ||
1296 | |||
1297 | static bool __kprobes __check_lt(unsigned long pstate) | ||
1298 | { | ||
1299 | pstate ^= (pstate << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | ||
1300 | return (pstate & PSR_N_BIT) != 0; | ||
1301 | } | ||
1302 | |||
1303 | static bool __kprobes __check_gt(unsigned long pstate) | ||
1304 | { | ||
1305 | /*PSR_N_BIT ^= PSR_V_BIT */ | ||
1306 | unsigned long temp = pstate ^ (pstate << 3); | ||
1307 | |||
1308 | temp |= (pstate << 1); /*PSR_N_BIT |= PSR_Z_BIT */ | ||
1309 | return (temp & PSR_N_BIT) == 0; | ||
1310 | } | ||
1311 | |||
1312 | static bool __kprobes __check_le(unsigned long pstate) | ||
1313 | { | ||
1314 | /*PSR_N_BIT ^= PSR_V_BIT */ | ||
1315 | unsigned long temp = pstate ^ (pstate << 3); | ||
1316 | |||
1317 | temp |= (pstate << 1); /*PSR_N_BIT |= PSR_Z_BIT */ | ||
1318 | return (temp & PSR_N_BIT) != 0; | ||
1319 | } | ||
1320 | |||
1321 | static bool __kprobes __check_al(unsigned long pstate) | ||
1322 | { | ||
1323 | return true; | ||
1324 | } | ||
1325 | |||
1326 | /* | ||
1327 | * Note that the ARMv8 ARM calls condition code 0b1111 "nv", but states that | ||
1328 | * it behaves identically to 0b1110 ("al"). | ||
1329 | */ | ||
1330 | pstate_check_t * const aarch32_opcode_cond_checks[16] = { | ||
1331 | __check_eq, __check_ne, __check_cs, __check_cc, | ||
1332 | __check_mi, __check_pl, __check_vs, __check_vc, | ||
1333 | __check_hi, __check_ls, __check_ge, __check_lt, | ||
1334 | __check_gt, __check_le, __check_al, __check_al | ||
1335 | }; | ||
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c index b5f063e5eff7..8c57f6496e56 100644 --- a/arch/arm64/kernel/kgdb.c +++ b/arch/arm64/kernel/kgdb.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/kdebug.h> | 23 | #include <linux/kdebug.h> |
24 | #include <linux/kgdb.h> | 24 | #include <linux/kgdb.h> |
25 | #include <linux/kprobes.h> | ||
25 | #include <asm/traps.h> | 26 | #include <asm/traps.h> |
26 | 27 | ||
27 | struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { | 28 | struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { |
@@ -230,6 +231,7 @@ static int kgdb_brk_fn(struct pt_regs *regs, unsigned int esr) | |||
230 | kgdb_handle_exception(1, SIGTRAP, 0, regs); | 231 | kgdb_handle_exception(1, SIGTRAP, 0, regs); |
231 | return 0; | 232 | return 0; |
232 | } | 233 | } |
234 | NOKPROBE_SYMBOL(kgdb_brk_fn) | ||
233 | 235 | ||
234 | static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr) | 236 | static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr) |
235 | { | 237 | { |
@@ -238,12 +240,14 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr) | |||
238 | 240 | ||
239 | return 0; | 241 | return 0; |
240 | } | 242 | } |
243 | NOKPROBE_SYMBOL(kgdb_compiled_brk_fn); | ||
241 | 244 | ||
242 | static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr) | 245 | static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr) |
243 | { | 246 | { |
244 | kgdb_handle_exception(1, SIGTRAP, 0, regs); | 247 | kgdb_handle_exception(1, SIGTRAP, 0, regs); |
245 | return 0; | 248 | return 0; |
246 | } | 249 | } |
250 | NOKPROBE_SYMBOL(kgdb_step_brk_fn); | ||
247 | 251 | ||
248 | static struct break_hook kgdb_brkpt_hook = { | 252 | static struct break_hook kgdb_brkpt_hook = { |
249 | .esr_mask = 0xffffffff, | 253 | .esr_mask = 0xffffffff, |
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c new file mode 100644 index 000000000000..bc96c8a7fc79 --- /dev/null +++ b/arch/arm64/kernel/machine_kexec.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | * kexec for arm64 | ||
3 | * | ||
4 | * Copyright (C) Linaro. | ||
5 | * Copyright (C) Huawei Futurewei Technologies. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kexec.h> | ||
13 | #include <linux/smp.h> | ||
14 | |||
15 | #include <asm/cacheflush.h> | ||
16 | #include <asm/cpu_ops.h> | ||
17 | #include <asm/mmu_context.h> | ||
18 | |||
19 | #include "cpu-reset.h" | ||
20 | |||
21 | /* Global variables for the arm64_relocate_new_kernel routine. */ | ||
22 | extern const unsigned char arm64_relocate_new_kernel[]; | ||
23 | extern const unsigned long arm64_relocate_new_kernel_size; | ||
24 | |||
25 | static unsigned long kimage_start; | ||
26 | |||
27 | /** | ||
28 | * kexec_image_info - For debugging output. | ||
29 | */ | ||
30 | #define kexec_image_info(_i) _kexec_image_info(__func__, __LINE__, _i) | ||
31 | static void _kexec_image_info(const char *func, int line, | ||
32 | const struct kimage *kimage) | ||
33 | { | ||
34 | unsigned long i; | ||
35 | |||
36 | pr_debug("%s:%d:\n", func, line); | ||
37 | pr_debug(" kexec kimage info:\n"); | ||
38 | pr_debug(" type: %d\n", kimage->type); | ||
39 | pr_debug(" start: %lx\n", kimage->start); | ||
40 | pr_debug(" head: %lx\n", kimage->head); | ||
41 | pr_debug(" nr_segments: %lu\n", kimage->nr_segments); | ||
42 | |||
43 | for (i = 0; i < kimage->nr_segments; i++) { | ||
44 | pr_debug(" segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n", | ||
45 | i, | ||
46 | kimage->segment[i].mem, | ||
47 | kimage->segment[i].mem + kimage->segment[i].memsz, | ||
48 | kimage->segment[i].memsz, | ||
49 | kimage->segment[i].memsz / PAGE_SIZE); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | void machine_kexec_cleanup(struct kimage *kimage) | ||
54 | { | ||
55 | /* Empty routine needed to avoid build errors. */ | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * machine_kexec_prepare - Prepare for a kexec reboot. | ||
60 | * | ||
61 | * Called from the core kexec code when a kernel image is loaded. | ||
62 | * Forbid loading a kexec kernel if we have no way of hotplugging cpus or cpus | ||
63 | * are stuck in the kernel. This avoids a panic once we hit machine_kexec(). | ||
64 | */ | ||
65 | int machine_kexec_prepare(struct kimage *kimage) | ||
66 | { | ||
67 | kimage_start = kimage->start; | ||
68 | |||
69 | kexec_image_info(kimage); | ||
70 | |||
71 | if (kimage->type != KEXEC_TYPE_CRASH && cpus_are_stuck_in_kernel()) { | ||
72 | pr_err("Can't kexec: CPUs are stuck in the kernel.\n"); | ||
73 | return -EBUSY; | ||
74 | } | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | * kexec_list_flush - Helper to flush the kimage list and source pages to PoC. | ||
81 | */ | ||
82 | static void kexec_list_flush(struct kimage *kimage) | ||
83 | { | ||
84 | kimage_entry_t *entry; | ||
85 | |||
86 | for (entry = &kimage->head; ; entry++) { | ||
87 | unsigned int flag; | ||
88 | void *addr; | ||
89 | |||
90 | /* flush the list entries. */ | ||
91 | __flush_dcache_area(entry, sizeof(kimage_entry_t)); | ||
92 | |||
93 | flag = *entry & IND_FLAGS; | ||
94 | if (flag == IND_DONE) | ||
95 | break; | ||
96 | |||
97 | addr = phys_to_virt(*entry & PAGE_MASK); | ||
98 | |||
99 | switch (flag) { | ||
100 | case IND_INDIRECTION: | ||
101 | /* Set entry point just before the new list page. */ | ||
102 | entry = (kimage_entry_t *)addr - 1; | ||
103 | break; | ||
104 | case IND_SOURCE: | ||
105 | /* flush the source pages. */ | ||
106 | __flush_dcache_area(addr, PAGE_SIZE); | ||
107 | break; | ||
108 | case IND_DESTINATION: | ||
109 | break; | ||
110 | default: | ||
111 | BUG(); | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * kexec_segment_flush - Helper to flush the kimage segments to PoC. | ||
118 | */ | ||
119 | static void kexec_segment_flush(const struct kimage *kimage) | ||
120 | { | ||
121 | unsigned long i; | ||
122 | |||
123 | pr_debug("%s:\n", __func__); | ||
124 | |||
125 | for (i = 0; i < kimage->nr_segments; i++) { | ||
126 | pr_debug(" segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n", | ||
127 | i, | ||
128 | kimage->segment[i].mem, | ||
129 | kimage->segment[i].mem + kimage->segment[i].memsz, | ||
130 | kimage->segment[i].memsz, | ||
131 | kimage->segment[i].memsz / PAGE_SIZE); | ||
132 | |||
133 | __flush_dcache_area(phys_to_virt(kimage->segment[i].mem), | ||
134 | kimage->segment[i].memsz); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * machine_kexec - Do the kexec reboot. | ||
140 | * | ||
141 | * Called from the core kexec code for a sys_reboot with LINUX_REBOOT_CMD_KEXEC. | ||
142 | */ | ||
143 | void machine_kexec(struct kimage *kimage) | ||
144 | { | ||
145 | phys_addr_t reboot_code_buffer_phys; | ||
146 | void *reboot_code_buffer; | ||
147 | |||
148 | /* | ||
149 | * New cpus may have become stuck_in_kernel after we loaded the image. | ||
150 | */ | ||
151 | BUG_ON(cpus_are_stuck_in_kernel() || (num_online_cpus() > 1)); | ||
152 | |||
153 | reboot_code_buffer_phys = page_to_phys(kimage->control_code_page); | ||
154 | reboot_code_buffer = phys_to_virt(reboot_code_buffer_phys); | ||
155 | |||
156 | kexec_image_info(kimage); | ||
157 | |||
158 | pr_debug("%s:%d: control_code_page: %p\n", __func__, __LINE__, | ||
159 | kimage->control_code_page); | ||
160 | pr_debug("%s:%d: reboot_code_buffer_phys: %pa\n", __func__, __LINE__, | ||
161 | &reboot_code_buffer_phys); | ||
162 | pr_debug("%s:%d: reboot_code_buffer: %p\n", __func__, __LINE__, | ||
163 | reboot_code_buffer); | ||
164 | pr_debug("%s:%d: relocate_new_kernel: %p\n", __func__, __LINE__, | ||
165 | arm64_relocate_new_kernel); | ||
166 | pr_debug("%s:%d: relocate_new_kernel_size: 0x%lx(%lu) bytes\n", | ||
167 | __func__, __LINE__, arm64_relocate_new_kernel_size, | ||
168 | arm64_relocate_new_kernel_size); | ||
169 | |||
170 | /* | ||
171 | * Copy arm64_relocate_new_kernel to the reboot_code_buffer for use | ||
172 | * after the kernel is shut down. | ||
173 | */ | ||
174 | memcpy(reboot_code_buffer, arm64_relocate_new_kernel, | ||
175 | arm64_relocate_new_kernel_size); | ||
176 | |||
177 | /* Flush the reboot_code_buffer in preparation for its execution. */ | ||
178 | __flush_dcache_area(reboot_code_buffer, arm64_relocate_new_kernel_size); | ||
179 | flush_icache_range((uintptr_t)reboot_code_buffer, | ||
180 | arm64_relocate_new_kernel_size); | ||
181 | |||
182 | /* Flush the kimage list and its buffers. */ | ||
183 | kexec_list_flush(kimage); | ||
184 | |||
185 | /* Flush the new image if already in place. */ | ||
186 | if (kimage->head & IND_DONE) | ||
187 | kexec_segment_flush(kimage); | ||
188 | |||
189 | pr_info("Bye!\n"); | ||
190 | |||
191 | /* Disable all DAIF exceptions. */ | ||
192 | asm volatile ("msr daifset, #0xf" : : : "memory"); | ||
193 | |||
194 | /* | ||
195 | * cpu_soft_restart will shutdown the MMU, disable data caches, then | ||
196 | * transfer control to the reboot_code_buffer which contains a copy of | ||
197 | * the arm64_relocate_new_kernel routine. arm64_relocate_new_kernel | ||
198 | * uses physical addressing to relocate the new image to its final | ||
199 | * position and transfers control to the image entry point when the | ||
200 | * relocation is complete. | ||
201 | */ | ||
202 | |||
203 | cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head, | ||
204 | kimage_start, 0); | ||
205 | |||
206 | BUG(); /* Should never get here. */ | ||
207 | } | ||
208 | |||
209 | void machine_crash_shutdown(struct pt_regs *regs) | ||
210 | { | ||
211 | /* Empty routine needed to avoid build errors. */ | ||
212 | } | ||
diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile new file mode 100644 index 000000000000..ce06312e3d34 --- /dev/null +++ b/arch/arm64/kernel/probes/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o \ | ||
2 | kprobes_trampoline.o \ | ||
3 | simulate-insn.o | ||
diff --git a/arch/arm64/kernel/probes/decode-insn.c b/arch/arm64/kernel/probes/decode-insn.c new file mode 100644 index 000000000000..37e47a9d617e --- /dev/null +++ b/arch/arm64/kernel/probes/decode-insn.c | |||
@@ -0,0 +1,174 @@ | |||
1 | /* | ||
2 | * arch/arm64/kernel/probes/decode-insn.c | ||
3 | * | ||
4 | * Copyright (C) 2013 Linaro Limited. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/kprobes.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <asm/kprobes.h> | ||
20 | #include <asm/insn.h> | ||
21 | #include <asm/sections.h> | ||
22 | |||
23 | #include "decode-insn.h" | ||
24 | #include "simulate-insn.h" | ||
25 | |||
26 | static bool __kprobes aarch64_insn_is_steppable(u32 insn) | ||
27 | { | ||
28 | /* | ||
29 | * Branch instructions will write a new value into the PC which is | ||
30 | * likely to be relative to the XOL address and therefore invalid. | ||
31 | * Deliberate generation of an exception during stepping is also not | ||
32 | * currently safe. Lastly, MSR instructions can do any number of nasty | ||
33 | * things we can't handle during single-stepping. | ||
34 | */ | ||
35 | if (aarch64_get_insn_class(insn) == AARCH64_INSN_CLS_BR_SYS) { | ||
36 | if (aarch64_insn_is_branch(insn) || | ||
37 | aarch64_insn_is_msr_imm(insn) || | ||
38 | aarch64_insn_is_msr_reg(insn) || | ||
39 | aarch64_insn_is_exception(insn) || | ||
40 | aarch64_insn_is_eret(insn)) | ||
41 | return false; | ||
42 | |||
43 | /* | ||
44 | * The MRS instruction may not return a correct value when | ||
45 | * executing in the single-stepping environment. We do make one | ||
46 | * exception, for reading the DAIF bits. | ||
47 | */ | ||
48 | if (aarch64_insn_is_mrs(insn)) | ||
49 | return aarch64_insn_extract_system_reg(insn) | ||
50 | != AARCH64_INSN_SPCLREG_DAIF; | ||
51 | |||
52 | /* | ||
53 | * The HINT instruction is is problematic when single-stepping, | ||
54 | * except for the NOP case. | ||
55 | */ | ||
56 | if (aarch64_insn_is_hint(insn)) | ||
57 | return aarch64_insn_is_nop(insn); | ||
58 | |||
59 | return true; | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * Instructions which load PC relative literals are not going to work | ||
64 | * when executed from an XOL slot. Instructions doing an exclusive | ||
65 | * load/store are not going to complete successfully when single-step | ||
66 | * exception handling happens in the middle of the sequence. | ||
67 | */ | ||
68 | if (aarch64_insn_uses_literal(insn) || | ||
69 | aarch64_insn_is_exclusive(insn)) | ||
70 | return false; | ||
71 | |||
72 | return true; | ||
73 | } | ||
74 | |||
75 | /* Return: | ||
76 | * INSN_REJECTED If instruction is one not allowed to kprobe, | ||
77 | * INSN_GOOD If instruction is supported and uses instruction slot, | ||
78 | * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot. | ||
79 | */ | ||
80 | static enum kprobe_insn __kprobes | ||
81 | arm_probe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
82 | { | ||
83 | /* | ||
84 | * Instructions reading or modifying the PC won't work from the XOL | ||
85 | * slot. | ||
86 | */ | ||
87 | if (aarch64_insn_is_steppable(insn)) | ||
88 | return INSN_GOOD; | ||
89 | |||
90 | if (aarch64_insn_is_bcond(insn)) { | ||
91 | asi->handler = simulate_b_cond; | ||
92 | } else if (aarch64_insn_is_cbz(insn) || | ||
93 | aarch64_insn_is_cbnz(insn)) { | ||
94 | asi->handler = simulate_cbz_cbnz; | ||
95 | } else if (aarch64_insn_is_tbz(insn) || | ||
96 | aarch64_insn_is_tbnz(insn)) { | ||
97 | asi->handler = simulate_tbz_tbnz; | ||
98 | } else if (aarch64_insn_is_adr_adrp(insn)) { | ||
99 | asi->handler = simulate_adr_adrp; | ||
100 | } else if (aarch64_insn_is_b(insn) || | ||
101 | aarch64_insn_is_bl(insn)) { | ||
102 | asi->handler = simulate_b_bl; | ||
103 | } else if (aarch64_insn_is_br(insn) || | ||
104 | aarch64_insn_is_blr(insn) || | ||
105 | aarch64_insn_is_ret(insn)) { | ||
106 | asi->handler = simulate_br_blr_ret; | ||
107 | } else if (aarch64_insn_is_ldr_lit(insn)) { | ||
108 | asi->handler = simulate_ldr_literal; | ||
109 | } else if (aarch64_insn_is_ldrsw_lit(insn)) { | ||
110 | asi->handler = simulate_ldrsw_literal; | ||
111 | } else { | ||
112 | /* | ||
113 | * Instruction cannot be stepped out-of-line and we don't | ||
114 | * (yet) simulate it. | ||
115 | */ | ||
116 | return INSN_REJECTED; | ||
117 | } | ||
118 | |||
119 | return INSN_GOOD_NO_SLOT; | ||
120 | } | ||
121 | |||
122 | static bool __kprobes | ||
123 | is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t *scan_end) | ||
124 | { | ||
125 | while (scan_start > scan_end) { | ||
126 | /* | ||
127 | * atomic region starts from exclusive load and ends with | ||
128 | * exclusive store. | ||
129 | */ | ||
130 | if (aarch64_insn_is_store_ex(le32_to_cpu(*scan_start))) | ||
131 | return false; | ||
132 | else if (aarch64_insn_is_load_ex(le32_to_cpu(*scan_start))) | ||
133 | return true; | ||
134 | scan_start--; | ||
135 | } | ||
136 | |||
137 | return false; | ||
138 | } | ||
139 | |||
140 | enum kprobe_insn __kprobes | ||
141 | arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi) | ||
142 | { | ||
143 | enum kprobe_insn decoded; | ||
144 | kprobe_opcode_t insn = le32_to_cpu(*addr); | ||
145 | kprobe_opcode_t *scan_start = addr - 1; | ||
146 | kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE; | ||
147 | #if defined(CONFIG_MODULES) && defined(MODULES_VADDR) | ||
148 | struct module *mod; | ||
149 | #endif | ||
150 | |||
151 | if (addr >= (kprobe_opcode_t *)_text && | ||
152 | scan_end < (kprobe_opcode_t *)_text) | ||
153 | scan_end = (kprobe_opcode_t *)_text; | ||
154 | #if defined(CONFIG_MODULES) && defined(MODULES_VADDR) | ||
155 | else { | ||
156 | preempt_disable(); | ||
157 | mod = __module_address((unsigned long)addr); | ||
158 | if (mod && within_module_init((unsigned long)addr, mod) && | ||
159 | !within_module_init((unsigned long)scan_end, mod)) | ||
160 | scan_end = (kprobe_opcode_t *)mod->init_layout.base; | ||
161 | else if (mod && within_module_core((unsigned long)addr, mod) && | ||
162 | !within_module_core((unsigned long)scan_end, mod)) | ||
163 | scan_end = (kprobe_opcode_t *)mod->core_layout.base; | ||
164 | preempt_enable(); | ||
165 | } | ||
166 | #endif | ||
167 | decoded = arm_probe_decode_insn(insn, asi); | ||
168 | |||
169 | if (decoded == INSN_REJECTED || | ||
170 | is_probed_address_atomic(scan_start, scan_end)) | ||
171 | return INSN_REJECTED; | ||
172 | |||
173 | return decoded; | ||
174 | } | ||
diff --git a/arch/arm64/kernel/probes/decode-insn.h b/arch/arm64/kernel/probes/decode-insn.h new file mode 100644 index 000000000000..d438289646a6 --- /dev/null +++ b/arch/arm64/kernel/probes/decode-insn.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * arch/arm64/kernel/probes/decode-insn.h | ||
3 | * | ||
4 | * Copyright (C) 2013 Linaro Limited. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef _ARM_KERNEL_KPROBES_ARM64_H | ||
17 | #define _ARM_KERNEL_KPROBES_ARM64_H | ||
18 | |||
19 | /* | ||
20 | * ARM strongly recommends a limit of 128 bytes between LoadExcl and | ||
21 | * StoreExcl instructions in a single thread of execution. So keep the | ||
22 | * max atomic context size as 32. | ||
23 | */ | ||
24 | #define MAX_ATOMIC_CONTEXT_SIZE (128 / sizeof(kprobe_opcode_t)) | ||
25 | |||
26 | enum kprobe_insn { | ||
27 | INSN_REJECTED, | ||
28 | INSN_GOOD_NO_SLOT, | ||
29 | INSN_GOOD, | ||
30 | }; | ||
31 | |||
32 | enum kprobe_insn __kprobes | ||
33 | arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi); | ||
34 | |||
35 | #endif /* _ARM_KERNEL_KPROBES_ARM64_H */ | ||
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c new file mode 100644 index 000000000000..bf9768588288 --- /dev/null +++ b/arch/arm64/kernel/probes/kprobes.c | |||
@@ -0,0 +1,686 @@ | |||
1 | /* | ||
2 | * arch/arm64/kernel/probes/kprobes.c | ||
3 | * | ||
4 | * Kprobes support for ARM64 | ||
5 | * | ||
6 | * Copyright (C) 2013 Linaro Limited. | ||
7 | * Author: Sandeepa Prabhu <sandeepa.prabhu@linaro.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | #include <linux/kasan.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/kprobes.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/stop_machine.h> | ||
25 | #include <linux/stringify.h> | ||
26 | #include <asm/traps.h> | ||
27 | #include <asm/ptrace.h> | ||
28 | #include <asm/cacheflush.h> | ||
29 | #include <asm/debug-monitors.h> | ||
30 | #include <asm/system_misc.h> | ||
31 | #include <asm/insn.h> | ||
32 | #include <asm/uaccess.h> | ||
33 | #include <asm/irq.h> | ||
34 | #include <asm-generic/sections.h> | ||
35 | |||
36 | #include "decode-insn.h" | ||
37 | |||
38 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; | ||
39 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | ||
40 | |||
41 | static void __kprobes | ||
42 | post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *); | ||
43 | |||
44 | static inline unsigned long min_stack_size(unsigned long addr) | ||
45 | { | ||
46 | unsigned long size; | ||
47 | |||
48 | if (on_irq_stack(addr, raw_smp_processor_id())) | ||
49 | size = IRQ_STACK_PTR(raw_smp_processor_id()) - addr; | ||
50 | else | ||
51 | size = (unsigned long)current_thread_info() + THREAD_START_SP - addr; | ||
52 | |||
53 | return min(size, FIELD_SIZEOF(struct kprobe_ctlblk, jprobes_stack)); | ||
54 | } | ||
55 | |||
56 | static void __kprobes arch_prepare_ss_slot(struct kprobe *p) | ||
57 | { | ||
58 | /* prepare insn slot */ | ||
59 | p->ainsn.insn[0] = cpu_to_le32(p->opcode); | ||
60 | |||
61 | flush_icache_range((uintptr_t) (p->ainsn.insn), | ||
62 | (uintptr_t) (p->ainsn.insn) + | ||
63 | MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | ||
64 | |||
65 | /* | ||
66 | * Needs restoring of return address after stepping xol. | ||
67 | */ | ||
68 | p->ainsn.restore = (unsigned long) p->addr + | ||
69 | sizeof(kprobe_opcode_t); | ||
70 | } | ||
71 | |||
72 | static void __kprobes arch_prepare_simulate(struct kprobe *p) | ||
73 | { | ||
74 | /* This instructions is not executed xol. No need to adjust the PC */ | ||
75 | p->ainsn.restore = 0; | ||
76 | } | ||
77 | |||
78 | static void __kprobes arch_simulate_insn(struct kprobe *p, struct pt_regs *regs) | ||
79 | { | ||
80 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
81 | |||
82 | if (p->ainsn.handler) | ||
83 | p->ainsn.handler((u32)p->opcode, (long)p->addr, regs); | ||
84 | |||
85 | /* single step simulated, now go for post processing */ | ||
86 | post_kprobe_handler(kcb, regs); | ||
87 | } | ||
88 | |||
89 | int __kprobes arch_prepare_kprobe(struct kprobe *p) | ||
90 | { | ||
91 | unsigned long probe_addr = (unsigned long)p->addr; | ||
92 | extern char __start_rodata[]; | ||
93 | extern char __end_rodata[]; | ||
94 | |||
95 | if (probe_addr & 0x3) | ||
96 | return -EINVAL; | ||
97 | |||
98 | /* copy instruction */ | ||
99 | p->opcode = le32_to_cpu(*p->addr); | ||
100 | |||
101 | if (in_exception_text(probe_addr)) | ||
102 | return -EINVAL; | ||
103 | if (probe_addr >= (unsigned long) __start_rodata && | ||
104 | probe_addr <= (unsigned long) __end_rodata) | ||
105 | return -EINVAL; | ||
106 | |||
107 | /* decode instruction */ | ||
108 | switch (arm_kprobe_decode_insn(p->addr, &p->ainsn)) { | ||
109 | case INSN_REJECTED: /* insn not supported */ | ||
110 | return -EINVAL; | ||
111 | |||
112 | case INSN_GOOD_NO_SLOT: /* insn need simulation */ | ||
113 | p->ainsn.insn = NULL; | ||
114 | break; | ||
115 | |||
116 | case INSN_GOOD: /* instruction uses slot */ | ||
117 | p->ainsn.insn = get_insn_slot(); | ||
118 | if (!p->ainsn.insn) | ||
119 | return -ENOMEM; | ||
120 | break; | ||
121 | }; | ||
122 | |||
123 | /* prepare the instruction */ | ||
124 | if (p->ainsn.insn) | ||
125 | arch_prepare_ss_slot(p); | ||
126 | else | ||
127 | arch_prepare_simulate(p); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode) | ||
133 | { | ||
134 | void *addrs[1]; | ||
135 | u32 insns[1]; | ||
136 | |||
137 | addrs[0] = (void *)addr; | ||
138 | insns[0] = (u32)opcode; | ||
139 | |||
140 | return aarch64_insn_patch_text(addrs, insns, 1); | ||
141 | } | ||
142 | |||
143 | /* arm kprobe: install breakpoint in text */ | ||
144 | void __kprobes arch_arm_kprobe(struct kprobe *p) | ||
145 | { | ||
146 | patch_text(p->addr, BRK64_OPCODE_KPROBES); | ||
147 | } | ||
148 | |||
149 | /* disarm kprobe: remove breakpoint from text */ | ||
150 | void __kprobes arch_disarm_kprobe(struct kprobe *p) | ||
151 | { | ||
152 | patch_text(p->addr, p->opcode); | ||
153 | } | ||
154 | |||
155 | void __kprobes arch_remove_kprobe(struct kprobe *p) | ||
156 | { | ||
157 | if (p->ainsn.insn) { | ||
158 | free_insn_slot(p->ainsn.insn, 0); | ||
159 | p->ainsn.insn = NULL; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) | ||
164 | { | ||
165 | kcb->prev_kprobe.kp = kprobe_running(); | ||
166 | kcb->prev_kprobe.status = kcb->kprobe_status; | ||
167 | } | ||
168 | |||
169 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) | ||
170 | { | ||
171 | __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); | ||
172 | kcb->kprobe_status = kcb->prev_kprobe.status; | ||
173 | } | ||
174 | |||
175 | static void __kprobes set_current_kprobe(struct kprobe *p) | ||
176 | { | ||
177 | __this_cpu_write(current_kprobe, p); | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * The D-flag (Debug mask) is set (masked) upon debug exception entry. | ||
182 | * Kprobes needs to clear (unmask) D-flag -ONLY- in case of recursive | ||
183 | * probe i.e. when probe hit from kprobe handler context upon | ||
184 | * executing the pre/post handlers. In this case we return with | ||
185 | * D-flag clear so that single-stepping can be carried-out. | ||
186 | * | ||
187 | * Leave D-flag set in all other cases. | ||
188 | */ | ||
189 | static void __kprobes | ||
190 | spsr_set_debug_flag(struct pt_regs *regs, int mask) | ||
191 | { | ||
192 | unsigned long spsr = regs->pstate; | ||
193 | |||
194 | if (mask) | ||
195 | spsr |= PSR_D_BIT; | ||
196 | else | ||
197 | spsr &= ~PSR_D_BIT; | ||
198 | |||
199 | regs->pstate = spsr; | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * Interrupts need to be disabled before single-step mode is set, and not | ||
204 | * reenabled until after single-step mode ends. | ||
205 | * Without disabling interrupt on local CPU, there is a chance of | ||
206 | * interrupt occurrence in the period of exception return and start of | ||
207 | * out-of-line single-step, that result in wrongly single stepping | ||
208 | * into the interrupt handler. | ||
209 | */ | ||
210 | static void __kprobes kprobes_save_local_irqflag(struct kprobe_ctlblk *kcb, | ||
211 | struct pt_regs *regs) | ||
212 | { | ||
213 | kcb->saved_irqflag = regs->pstate; | ||
214 | regs->pstate |= PSR_I_BIT; | ||
215 | } | ||
216 | |||
217 | static void __kprobes kprobes_restore_local_irqflag(struct kprobe_ctlblk *kcb, | ||
218 | struct pt_regs *regs) | ||
219 | { | ||
220 | if (kcb->saved_irqflag & PSR_I_BIT) | ||
221 | regs->pstate |= PSR_I_BIT; | ||
222 | else | ||
223 | regs->pstate &= ~PSR_I_BIT; | ||
224 | } | ||
225 | |||
226 | static void __kprobes | ||
227 | set_ss_context(struct kprobe_ctlblk *kcb, unsigned long addr) | ||
228 | { | ||
229 | kcb->ss_ctx.ss_pending = true; | ||
230 | kcb->ss_ctx.match_addr = addr + sizeof(kprobe_opcode_t); | ||
231 | } | ||
232 | |||
233 | static void __kprobes clear_ss_context(struct kprobe_ctlblk *kcb) | ||
234 | { | ||
235 | kcb->ss_ctx.ss_pending = false; | ||
236 | kcb->ss_ctx.match_addr = 0; | ||
237 | } | ||
238 | |||
239 | static void __kprobes setup_singlestep(struct kprobe *p, | ||
240 | struct pt_regs *regs, | ||
241 | struct kprobe_ctlblk *kcb, int reenter) | ||
242 | { | ||
243 | unsigned long slot; | ||
244 | |||
245 | if (reenter) { | ||
246 | save_previous_kprobe(kcb); | ||
247 | set_current_kprobe(p); | ||
248 | kcb->kprobe_status = KPROBE_REENTER; | ||
249 | } else { | ||
250 | kcb->kprobe_status = KPROBE_HIT_SS; | ||
251 | } | ||
252 | |||
253 | |||
254 | if (p->ainsn.insn) { | ||
255 | /* prepare for single stepping */ | ||
256 | slot = (unsigned long)p->ainsn.insn; | ||
257 | |||
258 | set_ss_context(kcb, slot); /* mark pending ss */ | ||
259 | |||
260 | if (kcb->kprobe_status == KPROBE_REENTER) | ||
261 | spsr_set_debug_flag(regs, 0); | ||
262 | else | ||
263 | WARN_ON(regs->pstate & PSR_D_BIT); | ||
264 | |||
265 | /* IRQs and single stepping do not mix well. */ | ||
266 | kprobes_save_local_irqflag(kcb, regs); | ||
267 | kernel_enable_single_step(regs); | ||
268 | instruction_pointer_set(regs, slot); | ||
269 | } else { | ||
270 | /* insn simulation */ | ||
271 | arch_simulate_insn(p, regs); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | static int __kprobes reenter_kprobe(struct kprobe *p, | ||
276 | struct pt_regs *regs, | ||
277 | struct kprobe_ctlblk *kcb) | ||
278 | { | ||
279 | switch (kcb->kprobe_status) { | ||
280 | case KPROBE_HIT_SSDONE: | ||
281 | case KPROBE_HIT_ACTIVE: | ||
282 | kprobes_inc_nmissed_count(p); | ||
283 | setup_singlestep(p, regs, kcb, 1); | ||
284 | break; | ||
285 | case KPROBE_HIT_SS: | ||
286 | case KPROBE_REENTER: | ||
287 | pr_warn("Unrecoverable kprobe detected at %p.\n", p->addr); | ||
288 | dump_kprobe(p); | ||
289 | BUG(); | ||
290 | break; | ||
291 | default: | ||
292 | WARN_ON(1); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | return 1; | ||
297 | } | ||
298 | |||
299 | static void __kprobes | ||
300 | post_kprobe_handler(struct kprobe_ctlblk *kcb, struct pt_regs *regs) | ||
301 | { | ||
302 | struct kprobe *cur = kprobe_running(); | ||
303 | |||
304 | if (!cur) | ||
305 | return; | ||
306 | |||
307 | /* return addr restore if non-branching insn */ | ||
308 | if (cur->ainsn.restore != 0) | ||
309 | instruction_pointer_set(regs, cur->ainsn.restore); | ||
310 | |||
311 | /* restore back original saved kprobe variables and continue */ | ||
312 | if (kcb->kprobe_status == KPROBE_REENTER) { | ||
313 | restore_previous_kprobe(kcb); | ||
314 | return; | ||
315 | } | ||
316 | /* call post handler */ | ||
317 | kcb->kprobe_status = KPROBE_HIT_SSDONE; | ||
318 | if (cur->post_handler) { | ||
319 | /* post_handler can hit breakpoint and single step | ||
320 | * again, so we enable D-flag for recursive exception. | ||
321 | */ | ||
322 | cur->post_handler(cur, regs, 0); | ||
323 | } | ||
324 | |||
325 | reset_current_kprobe(); | ||
326 | } | ||
327 | |||
328 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr) | ||
329 | { | ||
330 | struct kprobe *cur = kprobe_running(); | ||
331 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
332 | |||
333 | switch (kcb->kprobe_status) { | ||
334 | case KPROBE_HIT_SS: | ||
335 | case KPROBE_REENTER: | ||
336 | /* | ||
337 | * We are here because the instruction being single | ||
338 | * stepped caused a page fault. We reset the current | ||
339 | * kprobe and the ip points back to the probe address | ||
340 | * and allow the page fault handler to continue as a | ||
341 | * normal page fault. | ||
342 | */ | ||
343 | instruction_pointer_set(regs, (unsigned long) cur->addr); | ||
344 | if (!instruction_pointer(regs)) | ||
345 | BUG(); | ||
346 | |||
347 | kernel_disable_single_step(); | ||
348 | if (kcb->kprobe_status == KPROBE_REENTER) | ||
349 | spsr_set_debug_flag(regs, 1); | ||
350 | |||
351 | if (kcb->kprobe_status == KPROBE_REENTER) | ||
352 | restore_previous_kprobe(kcb); | ||
353 | else | ||
354 | reset_current_kprobe(); | ||
355 | |||
356 | break; | ||
357 | case KPROBE_HIT_ACTIVE: | ||
358 | case KPROBE_HIT_SSDONE: | ||
359 | /* | ||
360 | * We increment the nmissed count for accounting, | ||
361 | * we can also use npre/npostfault count for accounting | ||
362 | * these specific fault cases. | ||
363 | */ | ||
364 | kprobes_inc_nmissed_count(cur); | ||
365 | |||
366 | /* | ||
367 | * We come here because instructions in the pre/post | ||
368 | * handler caused the page_fault, this could happen | ||
369 | * if handler tries to access user space by | ||
370 | * copy_from_user(), get_user() etc. Let the | ||
371 | * user-specified handler try to fix it first. | ||
372 | */ | ||
373 | if (cur->fault_handler && cur->fault_handler(cur, regs, fsr)) | ||
374 | return 1; | ||
375 | |||
376 | /* | ||
377 | * In case the user-specified fault handler returned | ||
378 | * zero, try to fix up. | ||
379 | */ | ||
380 | if (fixup_exception(regs)) | ||
381 | return 1; | ||
382 | } | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | ||
387 | unsigned long val, void *data) | ||
388 | { | ||
389 | return NOTIFY_DONE; | ||
390 | } | ||
391 | |||
392 | static void __kprobes kprobe_handler(struct pt_regs *regs) | ||
393 | { | ||
394 | struct kprobe *p, *cur_kprobe; | ||
395 | struct kprobe_ctlblk *kcb; | ||
396 | unsigned long addr = instruction_pointer(regs); | ||
397 | |||
398 | kcb = get_kprobe_ctlblk(); | ||
399 | cur_kprobe = kprobe_running(); | ||
400 | |||
401 | p = get_kprobe((kprobe_opcode_t *) addr); | ||
402 | |||
403 | if (p) { | ||
404 | if (cur_kprobe) { | ||
405 | if (reenter_kprobe(p, regs, kcb)) | ||
406 | return; | ||
407 | } else { | ||
408 | /* Probe hit */ | ||
409 | set_current_kprobe(p); | ||
410 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; | ||
411 | |||
412 | /* | ||
413 | * If we have no pre-handler or it returned 0, we | ||
414 | * continue with normal processing. If we have a | ||
415 | * pre-handler and it returned non-zero, it prepped | ||
416 | * for calling the break_handler below on re-entry, | ||
417 | * so get out doing nothing more here. | ||
418 | * | ||
419 | * pre_handler can hit a breakpoint and can step thru | ||
420 | * before return, keep PSTATE D-flag enabled until | ||
421 | * pre_handler return back. | ||
422 | */ | ||
423 | if (!p->pre_handler || !p->pre_handler(p, regs)) { | ||
424 | setup_singlestep(p, regs, kcb, 0); | ||
425 | return; | ||
426 | } | ||
427 | } | ||
428 | } else if ((le32_to_cpu(*(kprobe_opcode_t *) addr) == | ||
429 | BRK64_OPCODE_KPROBES) && cur_kprobe) { | ||
430 | /* We probably hit a jprobe. Call its break handler. */ | ||
431 | if (cur_kprobe->break_handler && | ||
432 | cur_kprobe->break_handler(cur_kprobe, regs)) { | ||
433 | setup_singlestep(cur_kprobe, regs, kcb, 0); | ||
434 | return; | ||
435 | } | ||
436 | } | ||
437 | /* | ||
438 | * The breakpoint instruction was removed right | ||
439 | * after we hit it. Another cpu has removed | ||
440 | * either a probepoint or a debugger breakpoint | ||
441 | * at this address. In either case, no further | ||
442 | * handling of this interrupt is appropriate. | ||
443 | * Return back to original instruction, and continue. | ||
444 | */ | ||
445 | } | ||
446 | |||
447 | static int __kprobes | ||
448 | kprobe_ss_hit(struct kprobe_ctlblk *kcb, unsigned long addr) | ||
449 | { | ||
450 | if ((kcb->ss_ctx.ss_pending) | ||
451 | && (kcb->ss_ctx.match_addr == addr)) { | ||
452 | clear_ss_context(kcb); /* clear pending ss */ | ||
453 | return DBG_HOOK_HANDLED; | ||
454 | } | ||
455 | /* not ours, kprobes should ignore it */ | ||
456 | return DBG_HOOK_ERROR; | ||
457 | } | ||
458 | |||
459 | int __kprobes | ||
460 | kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr) | ||
461 | { | ||
462 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
463 | int retval; | ||
464 | |||
465 | /* return error if this is not our step */ | ||
466 | retval = kprobe_ss_hit(kcb, instruction_pointer(regs)); | ||
467 | |||
468 | if (retval == DBG_HOOK_HANDLED) { | ||
469 | kprobes_restore_local_irqflag(kcb, regs); | ||
470 | kernel_disable_single_step(); | ||
471 | |||
472 | if (kcb->kprobe_status == KPROBE_REENTER) | ||
473 | spsr_set_debug_flag(regs, 1); | ||
474 | |||
475 | post_kprobe_handler(kcb, regs); | ||
476 | } | ||
477 | |||
478 | return retval; | ||
479 | } | ||
480 | |||
481 | int __kprobes | ||
482 | kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr) | ||
483 | { | ||
484 | kprobe_handler(regs); | ||
485 | return DBG_HOOK_HANDLED; | ||
486 | } | ||
487 | |||
488 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | ||
489 | { | ||
490 | struct jprobe *jp = container_of(p, struct jprobe, kp); | ||
491 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
492 | long stack_ptr = kernel_stack_pointer(regs); | ||
493 | |||
494 | kcb->jprobe_saved_regs = *regs; | ||
495 | /* | ||
496 | * As Linus pointed out, gcc assumes that the callee | ||
497 | * owns the argument space and could overwrite it, e.g. | ||
498 | * tailcall optimization. So, to be absolutely safe | ||
499 | * we also save and restore enough stack bytes to cover | ||
500 | * the argument area. | ||
501 | */ | ||
502 | kasan_disable_current(); | ||
503 | memcpy(kcb->jprobes_stack, (void *)stack_ptr, | ||
504 | min_stack_size(stack_ptr)); | ||
505 | kasan_enable_current(); | ||
506 | |||
507 | instruction_pointer_set(regs, (unsigned long) jp->entry); | ||
508 | preempt_disable(); | ||
509 | pause_graph_tracing(); | ||
510 | return 1; | ||
511 | } | ||
512 | |||
513 | void __kprobes jprobe_return(void) | ||
514 | { | ||
515 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
516 | |||
517 | /* | ||
518 | * Jprobe handler return by entering break exception, | ||
519 | * encoded same as kprobe, but with following conditions | ||
520 | * -a special PC to identify it from the other kprobes. | ||
521 | * -restore stack addr to original saved pt_regs | ||
522 | */ | ||
523 | asm volatile(" mov sp, %0 \n" | ||
524 | "jprobe_return_break: brk %1 \n" | ||
525 | : | ||
526 | : "r" (kcb->jprobe_saved_regs.sp), | ||
527 | "I" (BRK64_ESR_KPROBES) | ||
528 | : "memory"); | ||
529 | |||
530 | unreachable(); | ||
531 | } | ||
532 | |||
533 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | ||
534 | { | ||
535 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
536 | long stack_addr = kcb->jprobe_saved_regs.sp; | ||
537 | long orig_sp = kernel_stack_pointer(regs); | ||
538 | struct jprobe *jp = container_of(p, struct jprobe, kp); | ||
539 | extern const char jprobe_return_break[]; | ||
540 | |||
541 | if (instruction_pointer(regs) != (u64) jprobe_return_break) | ||
542 | return 0; | ||
543 | |||
544 | if (orig_sp != stack_addr) { | ||
545 | struct pt_regs *saved_regs = | ||
546 | (struct pt_regs *)kcb->jprobe_saved_regs.sp; | ||
547 | pr_err("current sp %lx does not match saved sp %lx\n", | ||
548 | orig_sp, stack_addr); | ||
549 | pr_err("Saved registers for jprobe %p\n", jp); | ||
550 | show_regs(saved_regs); | ||
551 | pr_err("Current registers\n"); | ||
552 | show_regs(regs); | ||
553 | BUG(); | ||
554 | } | ||
555 | unpause_graph_tracing(); | ||
556 | *regs = kcb->jprobe_saved_regs; | ||
557 | kasan_disable_current(); | ||
558 | memcpy((void *)stack_addr, kcb->jprobes_stack, | ||
559 | min_stack_size(stack_addr)); | ||
560 | kasan_enable_current(); | ||
561 | preempt_enable_no_resched(); | ||
562 | return 1; | ||
563 | } | ||
564 | |||
565 | bool arch_within_kprobe_blacklist(unsigned long addr) | ||
566 | { | ||
567 | extern char __idmap_text_start[], __idmap_text_end[]; | ||
568 | extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[]; | ||
569 | |||
570 | if ((addr >= (unsigned long)__kprobes_text_start && | ||
571 | addr < (unsigned long)__kprobes_text_end) || | ||
572 | (addr >= (unsigned long)__entry_text_start && | ||
573 | addr < (unsigned long)__entry_text_end) || | ||
574 | (addr >= (unsigned long)__idmap_text_start && | ||
575 | addr < (unsigned long)__idmap_text_end) || | ||
576 | !!search_exception_tables(addr)) | ||
577 | return true; | ||
578 | |||
579 | if (!is_kernel_in_hyp_mode()) { | ||
580 | if ((addr >= (unsigned long)__hyp_text_start && | ||
581 | addr < (unsigned long)__hyp_text_end) || | ||
582 | (addr >= (unsigned long)__hyp_idmap_text_start && | ||
583 | addr < (unsigned long)__hyp_idmap_text_end)) | ||
584 | return true; | ||
585 | } | ||
586 | |||
587 | return false; | ||
588 | } | ||
589 | |||
590 | void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) | ||
591 | { | ||
592 | struct kretprobe_instance *ri = NULL; | ||
593 | struct hlist_head *head, empty_rp; | ||
594 | struct hlist_node *tmp; | ||
595 | unsigned long flags, orig_ret_address = 0; | ||
596 | unsigned long trampoline_address = | ||
597 | (unsigned long)&kretprobe_trampoline; | ||
598 | kprobe_opcode_t *correct_ret_addr = NULL; | ||
599 | |||
600 | INIT_HLIST_HEAD(&empty_rp); | ||
601 | kretprobe_hash_lock(current, &head, &flags); | ||
602 | |||
603 | /* | ||
604 | * It is possible to have multiple instances associated with a given | ||
605 | * task either because multiple functions in the call path have | ||
606 | * return probes installed on them, and/or more than one | ||
607 | * return probe was registered for a target function. | ||
608 | * | ||
609 | * We can handle this because: | ||
610 | * - instances are always pushed into the head of the list | ||
611 | * - when multiple return probes are registered for the same | ||
612 | * function, the (chronologically) first instance's ret_addr | ||
613 | * will be the real return address, and all the rest will | ||
614 | * point to kretprobe_trampoline. | ||
615 | */ | ||
616 | hlist_for_each_entry_safe(ri, tmp, head, hlist) { | ||
617 | if (ri->task != current) | ||
618 | /* another task is sharing our hash bucket */ | ||
619 | continue; | ||
620 | |||
621 | orig_ret_address = (unsigned long)ri->ret_addr; | ||
622 | |||
623 | if (orig_ret_address != trampoline_address) | ||
624 | /* | ||
625 | * This is the real return address. Any other | ||
626 | * instances associated with this task are for | ||
627 | * other calls deeper on the call stack | ||
628 | */ | ||
629 | break; | ||
630 | } | ||
631 | |||
632 | kretprobe_assert(ri, orig_ret_address, trampoline_address); | ||
633 | |||
634 | correct_ret_addr = ri->ret_addr; | ||
635 | hlist_for_each_entry_safe(ri, tmp, head, hlist) { | ||
636 | if (ri->task != current) | ||
637 | /* another task is sharing our hash bucket */ | ||
638 | continue; | ||
639 | |||
640 | orig_ret_address = (unsigned long)ri->ret_addr; | ||
641 | if (ri->rp && ri->rp->handler) { | ||
642 | __this_cpu_write(current_kprobe, &ri->rp->kp); | ||
643 | get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; | ||
644 | ri->ret_addr = correct_ret_addr; | ||
645 | ri->rp->handler(ri, regs); | ||
646 | __this_cpu_write(current_kprobe, NULL); | ||
647 | } | ||
648 | |||
649 | recycle_rp_inst(ri, &empty_rp); | ||
650 | |||
651 | if (orig_ret_address != trampoline_address) | ||
652 | /* | ||
653 | * This is the real return address. Any other | ||
654 | * instances associated with this task are for | ||
655 | * other calls deeper on the call stack | ||
656 | */ | ||
657 | break; | ||
658 | } | ||
659 | |||
660 | kretprobe_hash_unlock(current, &flags); | ||
661 | |||
662 | hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { | ||
663 | hlist_del(&ri->hlist); | ||
664 | kfree(ri); | ||
665 | } | ||
666 | return (void *)orig_ret_address; | ||
667 | } | ||
668 | |||
669 | void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, | ||
670 | struct pt_regs *regs) | ||
671 | { | ||
672 | ri->ret_addr = (kprobe_opcode_t *)regs->regs[30]; | ||
673 | |||
674 | /* replace return addr (x30) with trampoline */ | ||
675 | regs->regs[30] = (long)&kretprobe_trampoline; | ||
676 | } | ||
677 | |||
678 | int __kprobes arch_trampoline_kprobe(struct kprobe *p) | ||
679 | { | ||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | int __init arch_init_kprobes(void) | ||
684 | { | ||
685 | return 0; | ||
686 | } | ||
diff --git a/arch/arm64/kernel/probes/kprobes_trampoline.S b/arch/arm64/kernel/probes/kprobes_trampoline.S new file mode 100644 index 000000000000..5d6e7f14638c --- /dev/null +++ b/arch/arm64/kernel/probes/kprobes_trampoline.S | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * trampoline entry and return code for kretprobes. | ||
3 | */ | ||
4 | |||
5 | #include <linux/linkage.h> | ||
6 | #include <asm/asm-offsets.h> | ||
7 | #include <asm/assembler.h> | ||
8 | |||
9 | .text | ||
10 | |||
11 | .macro save_all_base_regs | ||
12 | stp x0, x1, [sp, #S_X0] | ||
13 | stp x2, x3, [sp, #S_X2] | ||
14 | stp x4, x5, [sp, #S_X4] | ||
15 | stp x6, x7, [sp, #S_X6] | ||
16 | stp x8, x9, [sp, #S_X8] | ||
17 | stp x10, x11, [sp, #S_X10] | ||
18 | stp x12, x13, [sp, #S_X12] | ||
19 | stp x14, x15, [sp, #S_X14] | ||
20 | stp x16, x17, [sp, #S_X16] | ||
21 | stp x18, x19, [sp, #S_X18] | ||
22 | stp x20, x21, [sp, #S_X20] | ||
23 | stp x22, x23, [sp, #S_X22] | ||
24 | stp x24, x25, [sp, #S_X24] | ||
25 | stp x26, x27, [sp, #S_X26] | ||
26 | stp x28, x29, [sp, #S_X28] | ||
27 | add x0, sp, #S_FRAME_SIZE | ||
28 | stp lr, x0, [sp, #S_LR] | ||
29 | /* | ||
30 | * Construct a useful saved PSTATE | ||
31 | */ | ||
32 | mrs x0, nzcv | ||
33 | mrs x1, daif | ||
34 | orr x0, x0, x1 | ||
35 | mrs x1, CurrentEL | ||
36 | orr x0, x0, x1 | ||
37 | mrs x1, SPSel | ||
38 | orr x0, x0, x1 | ||
39 | stp xzr, x0, [sp, #S_PC] | ||
40 | .endm | ||
41 | |||
42 | .macro restore_all_base_regs | ||
43 | ldr x0, [sp, #S_PSTATE] | ||
44 | and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT) | ||
45 | msr nzcv, x0 | ||
46 | ldp x0, x1, [sp, #S_X0] | ||
47 | ldp x2, x3, [sp, #S_X2] | ||
48 | ldp x4, x5, [sp, #S_X4] | ||
49 | ldp x6, x7, [sp, #S_X6] | ||
50 | ldp x8, x9, [sp, #S_X8] | ||
51 | ldp x10, x11, [sp, #S_X10] | ||
52 | ldp x12, x13, [sp, #S_X12] | ||
53 | ldp x14, x15, [sp, #S_X14] | ||
54 | ldp x16, x17, [sp, #S_X16] | ||
55 | ldp x18, x19, [sp, #S_X18] | ||
56 | ldp x20, x21, [sp, #S_X20] | ||
57 | ldp x22, x23, [sp, #S_X22] | ||
58 | ldp x24, x25, [sp, #S_X24] | ||
59 | ldp x26, x27, [sp, #S_X26] | ||
60 | ldp x28, x29, [sp, #S_X28] | ||
61 | .endm | ||
62 | |||
63 | ENTRY(kretprobe_trampoline) | ||
64 | sub sp, sp, #S_FRAME_SIZE | ||
65 | |||
66 | save_all_base_regs | ||
67 | |||
68 | mov x0, sp | ||
69 | bl trampoline_probe_handler | ||
70 | /* | ||
71 | * Replace trampoline address in lr with actual orig_ret_addr return | ||
72 | * address. | ||
73 | */ | ||
74 | mov lr, x0 | ||
75 | |||
76 | restore_all_base_regs | ||
77 | |||
78 | add sp, sp, #S_FRAME_SIZE | ||
79 | ret | ||
80 | |||
81 | ENDPROC(kretprobe_trampoline) | ||
diff --git a/arch/arm64/kernel/probes/simulate-insn.c b/arch/arm64/kernel/probes/simulate-insn.c new file mode 100644 index 000000000000..8977ce9d009d --- /dev/null +++ b/arch/arm64/kernel/probes/simulate-insn.c | |||
@@ -0,0 +1,217 @@ | |||
1 | /* | ||
2 | * arch/arm64/kernel/probes/simulate-insn.c | ||
3 | * | ||
4 | * Copyright (C) 2013 Linaro Limited. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/kprobes.h> | ||
18 | |||
19 | #include "simulate-insn.h" | ||
20 | |||
21 | #define sign_extend(x, signbit) \ | ||
22 | ((x) | (0 - ((x) & (1 << (signbit))))) | ||
23 | |||
24 | #define bbl_displacement(insn) \ | ||
25 | sign_extend(((insn) & 0x3ffffff) << 2, 27) | ||
26 | |||
27 | #define bcond_displacement(insn) \ | ||
28 | sign_extend(((insn >> 5) & 0x7ffff) << 2, 20) | ||
29 | |||
30 | #define cbz_displacement(insn) \ | ||
31 | sign_extend(((insn >> 5) & 0x7ffff) << 2, 20) | ||
32 | |||
33 | #define tbz_displacement(insn) \ | ||
34 | sign_extend(((insn >> 5) & 0x3fff) << 2, 15) | ||
35 | |||
36 | #define ldr_displacement(insn) \ | ||
37 | sign_extend(((insn >> 5) & 0x7ffff) << 2, 20) | ||
38 | |||
39 | static inline void set_x_reg(struct pt_regs *regs, int reg, u64 val) | ||
40 | { | ||
41 | if (reg < 31) | ||
42 | regs->regs[reg] = val; | ||
43 | } | ||
44 | |||
45 | static inline void set_w_reg(struct pt_regs *regs, int reg, u64 val) | ||
46 | { | ||
47 | if (reg < 31) | ||
48 | regs->regs[reg] = lower_32_bits(val); | ||
49 | } | ||
50 | |||
51 | static inline u64 get_x_reg(struct pt_regs *regs, int reg) | ||
52 | { | ||
53 | if (reg < 31) | ||
54 | return regs->regs[reg]; | ||
55 | else | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static inline u32 get_w_reg(struct pt_regs *regs, int reg) | ||
60 | { | ||
61 | if (reg < 31) | ||
62 | return lower_32_bits(regs->regs[reg]); | ||
63 | else | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static bool __kprobes check_cbz(u32 opcode, struct pt_regs *regs) | ||
68 | { | ||
69 | int xn = opcode & 0x1f; | ||
70 | |||
71 | return (opcode & (1 << 31)) ? | ||
72 | (get_x_reg(regs, xn) == 0) : (get_w_reg(regs, xn) == 0); | ||
73 | } | ||
74 | |||
75 | static bool __kprobes check_cbnz(u32 opcode, struct pt_regs *regs) | ||
76 | { | ||
77 | int xn = opcode & 0x1f; | ||
78 | |||
79 | return (opcode & (1 << 31)) ? | ||
80 | (get_x_reg(regs, xn) != 0) : (get_w_reg(regs, xn) != 0); | ||
81 | } | ||
82 | |||
83 | static bool __kprobes check_tbz(u32 opcode, struct pt_regs *regs) | ||
84 | { | ||
85 | int xn = opcode & 0x1f; | ||
86 | int bit_pos = ((opcode & (1 << 31)) >> 26) | ((opcode >> 19) & 0x1f); | ||
87 | |||
88 | return ((get_x_reg(regs, xn) >> bit_pos) & 0x1) == 0; | ||
89 | } | ||
90 | |||
91 | static bool __kprobes check_tbnz(u32 opcode, struct pt_regs *regs) | ||
92 | { | ||
93 | int xn = opcode & 0x1f; | ||
94 | int bit_pos = ((opcode & (1 << 31)) >> 26) | ((opcode >> 19) & 0x1f); | ||
95 | |||
96 | return ((get_x_reg(regs, xn) >> bit_pos) & 0x1) != 0; | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * instruction simulation functions | ||
101 | */ | ||
102 | void __kprobes | ||
103 | simulate_adr_adrp(u32 opcode, long addr, struct pt_regs *regs) | ||
104 | { | ||
105 | long imm, xn, val; | ||
106 | |||
107 | xn = opcode & 0x1f; | ||
108 | imm = ((opcode >> 3) & 0x1ffffc) | ((opcode >> 29) & 0x3); | ||
109 | imm = sign_extend(imm, 20); | ||
110 | if (opcode & 0x80000000) | ||
111 | val = (imm<<12) + (addr & 0xfffffffffffff000); | ||
112 | else | ||
113 | val = imm + addr; | ||
114 | |||
115 | set_x_reg(regs, xn, val); | ||
116 | |||
117 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); | ||
118 | } | ||
119 | |||
120 | void __kprobes | ||
121 | simulate_b_bl(u32 opcode, long addr, struct pt_regs *regs) | ||
122 | { | ||
123 | int disp = bbl_displacement(opcode); | ||
124 | |||
125 | /* Link register is x30 */ | ||
126 | if (opcode & (1 << 31)) | ||
127 | set_x_reg(regs, 30, addr + 4); | ||
128 | |||
129 | instruction_pointer_set(regs, addr + disp); | ||
130 | } | ||
131 | |||
132 | void __kprobes | ||
133 | simulate_b_cond(u32 opcode, long addr, struct pt_regs *regs) | ||
134 | { | ||
135 | int disp = 4; | ||
136 | |||
137 | if (aarch32_opcode_cond_checks[opcode & 0xf](regs->pstate & 0xffffffff)) | ||
138 | disp = bcond_displacement(opcode); | ||
139 | |||
140 | instruction_pointer_set(regs, addr + disp); | ||
141 | } | ||
142 | |||
143 | void __kprobes | ||
144 | simulate_br_blr_ret(u32 opcode, long addr, struct pt_regs *regs) | ||
145 | { | ||
146 | int xn = (opcode >> 5) & 0x1f; | ||
147 | |||
148 | /* update pc first in case we're doing a "blr lr" */ | ||
149 | instruction_pointer_set(regs, get_x_reg(regs, xn)); | ||
150 | |||
151 | /* Link register is x30 */ | ||
152 | if (((opcode >> 21) & 0x3) == 1) | ||
153 | set_x_reg(regs, 30, addr + 4); | ||
154 | } | ||
155 | |||
156 | void __kprobes | ||
157 | simulate_cbz_cbnz(u32 opcode, long addr, struct pt_regs *regs) | ||
158 | { | ||
159 | int disp = 4; | ||
160 | |||
161 | if (opcode & (1 << 24)) { | ||
162 | if (check_cbnz(opcode, regs)) | ||
163 | disp = cbz_displacement(opcode); | ||
164 | } else { | ||
165 | if (check_cbz(opcode, regs)) | ||
166 | disp = cbz_displacement(opcode); | ||
167 | } | ||
168 | instruction_pointer_set(regs, addr + disp); | ||
169 | } | ||
170 | |||
171 | void __kprobes | ||
172 | simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs) | ||
173 | { | ||
174 | int disp = 4; | ||
175 | |||
176 | if (opcode & (1 << 24)) { | ||
177 | if (check_tbnz(opcode, regs)) | ||
178 | disp = tbz_displacement(opcode); | ||
179 | } else { | ||
180 | if (check_tbz(opcode, regs)) | ||
181 | disp = tbz_displacement(opcode); | ||
182 | } | ||
183 | instruction_pointer_set(regs, addr + disp); | ||
184 | } | ||
185 | |||
186 | void __kprobes | ||
187 | simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) | ||
188 | { | ||
189 | u64 *load_addr; | ||
190 | int xn = opcode & 0x1f; | ||
191 | int disp; | ||
192 | |||
193 | disp = ldr_displacement(opcode); | ||
194 | load_addr = (u64 *) (addr + disp); | ||
195 | |||
196 | if (opcode & (1 << 30)) /* x0-x30 */ | ||
197 | set_x_reg(regs, xn, *load_addr); | ||
198 | else /* w0-w30 */ | ||
199 | set_w_reg(regs, xn, *load_addr); | ||
200 | |||
201 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); | ||
202 | } | ||
203 | |||
204 | void __kprobes | ||
205 | simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs) | ||
206 | { | ||
207 | s32 *load_addr; | ||
208 | int xn = opcode & 0x1f; | ||
209 | int disp; | ||
210 | |||
211 | disp = ldr_displacement(opcode); | ||
212 | load_addr = (s32 *) (addr + disp); | ||
213 | |||
214 | set_x_reg(regs, xn, *load_addr); | ||
215 | |||
216 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); | ||
217 | } | ||
diff --git a/arch/arm64/kernel/probes/simulate-insn.h b/arch/arm64/kernel/probes/simulate-insn.h new file mode 100644 index 000000000000..050bde683c2d --- /dev/null +++ b/arch/arm64/kernel/probes/simulate-insn.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * arch/arm64/kernel/probes/simulate-insn.h | ||
3 | * | ||
4 | * Copyright (C) 2013 Linaro Limited | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef _ARM_KERNEL_KPROBES_SIMULATE_INSN_H | ||
17 | #define _ARM_KERNEL_KPROBES_SIMULATE_INSN_H | ||
18 | |||
19 | void simulate_adr_adrp(u32 opcode, long addr, struct pt_regs *regs); | ||
20 | void simulate_b_bl(u32 opcode, long addr, struct pt_regs *regs); | ||
21 | void simulate_b_cond(u32 opcode, long addr, struct pt_regs *regs); | ||
22 | void simulate_br_blr_ret(u32 opcode, long addr, struct pt_regs *regs); | ||
23 | void simulate_cbz_cbnz(u32 opcode, long addr, struct pt_regs *regs); | ||
24 | void simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs); | ||
25 | void simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs); | ||
26 | void simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs); | ||
27 | |||
28 | #endif /* _ARM_KERNEL_KPROBES_SIMULATE_INSN_H */ | ||
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 3f6cd5c5234f..030c1d5aa46d 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c | |||
@@ -48,6 +48,107 @@ | |||
48 | #define CREATE_TRACE_POINTS | 48 | #define CREATE_TRACE_POINTS |
49 | #include <trace/events/syscalls.h> | 49 | #include <trace/events/syscalls.h> |
50 | 50 | ||
51 | struct pt_regs_offset { | ||
52 | const char *name; | ||
53 | int offset; | ||
54 | }; | ||
55 | |||
56 | #define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)} | ||
57 | #define REG_OFFSET_END {.name = NULL, .offset = 0} | ||
58 | #define GPR_OFFSET_NAME(r) \ | ||
59 | {.name = "x" #r, .offset = offsetof(struct pt_regs, regs[r])} | ||
60 | |||
61 | static const struct pt_regs_offset regoffset_table[] = { | ||
62 | GPR_OFFSET_NAME(0), | ||
63 | GPR_OFFSET_NAME(1), | ||
64 | GPR_OFFSET_NAME(2), | ||
65 | GPR_OFFSET_NAME(3), | ||
66 | GPR_OFFSET_NAME(4), | ||
67 | GPR_OFFSET_NAME(5), | ||
68 | GPR_OFFSET_NAME(6), | ||
69 | GPR_OFFSET_NAME(7), | ||
70 | GPR_OFFSET_NAME(8), | ||
71 | GPR_OFFSET_NAME(9), | ||
72 | GPR_OFFSET_NAME(10), | ||
73 | GPR_OFFSET_NAME(11), | ||
74 | GPR_OFFSET_NAME(12), | ||
75 | GPR_OFFSET_NAME(13), | ||
76 | GPR_OFFSET_NAME(14), | ||
77 | GPR_OFFSET_NAME(15), | ||
78 | GPR_OFFSET_NAME(16), | ||
79 | GPR_OFFSET_NAME(17), | ||
80 | GPR_OFFSET_NAME(18), | ||
81 | GPR_OFFSET_NAME(19), | ||
82 | GPR_OFFSET_NAME(20), | ||
83 | GPR_OFFSET_NAME(21), | ||
84 | GPR_OFFSET_NAME(22), | ||
85 | GPR_OFFSET_NAME(23), | ||
86 | GPR_OFFSET_NAME(24), | ||
87 | GPR_OFFSET_NAME(25), | ||
88 | GPR_OFFSET_NAME(26), | ||
89 | GPR_OFFSET_NAME(27), | ||
90 | GPR_OFFSET_NAME(28), | ||
91 | GPR_OFFSET_NAME(29), | ||
92 | GPR_OFFSET_NAME(30), | ||
93 | {.name = "lr", .offset = offsetof(struct pt_regs, regs[30])}, | ||
94 | REG_OFFSET_NAME(sp), | ||
95 | REG_OFFSET_NAME(pc), | ||
96 | REG_OFFSET_NAME(pstate), | ||
97 | REG_OFFSET_END, | ||
98 | }; | ||
99 | |||
100 | /** | ||
101 | * regs_query_register_offset() - query register offset from its name | ||
102 | * @name: the name of a register | ||
103 | * | ||
104 | * regs_query_register_offset() returns the offset of a register in struct | ||
105 | * pt_regs from its name. If the name is invalid, this returns -EINVAL; | ||
106 | */ | ||
107 | int regs_query_register_offset(const char *name) | ||
108 | { | ||
109 | const struct pt_regs_offset *roff; | ||
110 | |||
111 | for (roff = regoffset_table; roff->name != NULL; roff++) | ||
112 | if (!strcmp(roff->name, name)) | ||
113 | return roff->offset; | ||
114 | return -EINVAL; | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * regs_within_kernel_stack() - check the address in the stack | ||
119 | * @regs: pt_regs which contains kernel stack pointer. | ||
120 | * @addr: address which is checked. | ||
121 | * | ||
122 | * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). | ||
123 | * If @addr is within the kernel stack, it returns true. If not, returns false. | ||
124 | */ | ||
125 | static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) | ||
126 | { | ||
127 | return ((addr & ~(THREAD_SIZE - 1)) == | ||
128 | (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))) || | ||
129 | on_irq_stack(addr, raw_smp_processor_id()); | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * regs_get_kernel_stack_nth() - get Nth entry of the stack | ||
134 | * @regs: pt_regs which contains kernel stack pointer. | ||
135 | * @n: stack entry number. | ||
136 | * | ||
137 | * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which | ||
138 | * is specified by @regs. If the @n th entry is NOT in the kernel stack, | ||
139 | * this returns 0. | ||
140 | */ | ||
141 | unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) | ||
142 | { | ||
143 | unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); | ||
144 | |||
145 | addr += n; | ||
146 | if (regs_within_kernel_stack(regs, (unsigned long)addr)) | ||
147 | return *addr; | ||
148 | else | ||
149 | return 0; | ||
150 | } | ||
151 | |||
51 | /* | 152 | /* |
52 | * TODO: does not yet catch signals sent when the child dies. | 153 | * TODO: does not yet catch signals sent when the child dies. |
53 | * in exit.c or in signal.c. | 154 | * in exit.c or in signal.c. |
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S new file mode 100644 index 000000000000..51b73cdde287 --- /dev/null +++ b/arch/arm64/kernel/relocate_kernel.S | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * kexec for arm64 | ||
3 | * | ||
4 | * Copyright (C) Linaro. | ||
5 | * Copyright (C) Huawei Futurewei Technologies. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kexec.h> | ||
13 | #include <linux/linkage.h> | ||
14 | |||
15 | #include <asm/assembler.h> | ||
16 | #include <asm/kexec.h> | ||
17 | #include <asm/page.h> | ||
18 | #include <asm/sysreg.h> | ||
19 | |||
20 | /* | ||
21 | * arm64_relocate_new_kernel - Put a 2nd stage image in place and boot it. | ||
22 | * | ||
23 | * The memory that the old kernel occupies may be overwritten when coping the | ||
24 | * new image to its final location. To assure that the | ||
25 | * arm64_relocate_new_kernel routine which does that copy is not overwritten, | ||
26 | * all code and data needed by arm64_relocate_new_kernel must be between the | ||
27 | * symbols arm64_relocate_new_kernel and arm64_relocate_new_kernel_end. The | ||
28 | * machine_kexec() routine will copy arm64_relocate_new_kernel to the kexec | ||
29 | * control_code_page, a special page which has been set up to be preserved | ||
30 | * during the copy operation. | ||
31 | */ | ||
32 | ENTRY(arm64_relocate_new_kernel) | ||
33 | |||
34 | /* Setup the list loop variables. */ | ||
35 | mov x17, x1 /* x17 = kimage_start */ | ||
36 | mov x16, x0 /* x16 = kimage_head */ | ||
37 | dcache_line_size x15, x0 /* x15 = dcache line size */ | ||
38 | mov x14, xzr /* x14 = entry ptr */ | ||
39 | mov x13, xzr /* x13 = copy dest */ | ||
40 | |||
41 | /* Clear the sctlr_el2 flags. */ | ||
42 | mrs x0, CurrentEL | ||
43 | cmp x0, #CurrentEL_EL2 | ||
44 | b.ne 1f | ||
45 | mrs x0, sctlr_el2 | ||
46 | ldr x1, =SCTLR_ELx_FLAGS | ||
47 | bic x0, x0, x1 | ||
48 | msr sctlr_el2, x0 | ||
49 | isb | ||
50 | 1: | ||
51 | |||
52 | /* Check if the new image needs relocation. */ | ||
53 | tbnz x16, IND_DONE_BIT, .Ldone | ||
54 | |||
55 | .Lloop: | ||
56 | and x12, x16, PAGE_MASK /* x12 = addr */ | ||
57 | |||
58 | /* Test the entry flags. */ | ||
59 | .Ltest_source: | ||
60 | tbz x16, IND_SOURCE_BIT, .Ltest_indirection | ||
61 | |||
62 | /* Invalidate dest page to PoC. */ | ||
63 | mov x0, x13 | ||
64 | add x20, x0, #PAGE_SIZE | ||
65 | sub x1, x15, #1 | ||
66 | bic x0, x0, x1 | ||
67 | 2: dc ivac, x0 | ||
68 | add x0, x0, x15 | ||
69 | cmp x0, x20 | ||
70 | b.lo 2b | ||
71 | dsb sy | ||
72 | |||
73 | mov x20, x13 | ||
74 | mov x21, x12 | ||
75 | copy_page x20, x21, x0, x1, x2, x3, x4, x5, x6, x7 | ||
76 | |||
77 | /* dest += PAGE_SIZE */ | ||
78 | add x13, x13, PAGE_SIZE | ||
79 | b .Lnext | ||
80 | |||
81 | .Ltest_indirection: | ||
82 | tbz x16, IND_INDIRECTION_BIT, .Ltest_destination | ||
83 | |||
84 | /* ptr = addr */ | ||
85 | mov x14, x12 | ||
86 | b .Lnext | ||
87 | |||
88 | .Ltest_destination: | ||
89 | tbz x16, IND_DESTINATION_BIT, .Lnext | ||
90 | |||
91 | /* dest = addr */ | ||
92 | mov x13, x12 | ||
93 | |||
94 | .Lnext: | ||
95 | /* entry = *ptr++ */ | ||
96 | ldr x16, [x14], #8 | ||
97 | |||
98 | /* while (!(entry & DONE)) */ | ||
99 | tbz x16, IND_DONE_BIT, .Lloop | ||
100 | |||
101 | .Ldone: | ||
102 | /* wait for writes from copy_page to finish */ | ||
103 | dsb nsh | ||
104 | ic iallu | ||
105 | dsb nsh | ||
106 | isb | ||
107 | |||
108 | /* Start new image. */ | ||
109 | mov x0, xzr | ||
110 | mov x1, xzr | ||
111 | mov x2, xzr | ||
112 | mov x3, xzr | ||
113 | br x17 | ||
114 | |||
115 | ENDPROC(arm64_relocate_new_kernel) | ||
116 | |||
117 | .ltorg | ||
118 | |||
119 | .align 3 /* To keep the 64-bit values below naturally aligned. */ | ||
120 | |||
121 | .Lcopy_end: | ||
122 | .org KEXEC_CONTROL_PAGE_SIZE | ||
123 | |||
124 | /* | ||
125 | * arm64_relocate_new_kernel_size - Number of bytes to copy to the | ||
126 | * control_code_page. | ||
127 | */ | ||
128 | .globl arm64_relocate_new_kernel_size | ||
129 | arm64_relocate_new_kernel_size: | ||
130 | .quad .Lcopy_end - arm64_relocate_new_kernel | ||
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 92f0e1e767cf..5b8256770e22 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c | |||
@@ -202,7 +202,7 @@ static void __init request_standard_resources(void) | |||
202 | struct resource *res; | 202 | struct resource *res; |
203 | 203 | ||
204 | kernel_code.start = virt_to_phys(_text); | 204 | kernel_code.start = virt_to_phys(_text); |
205 | kernel_code.end = virt_to_phys(_etext - 1); | 205 | kernel_code.end = virt_to_phys(__init_begin - 1); |
206 | kernel_data.start = virt_to_phys(_sdata); | 206 | kernel_data.start = virt_to_phys(_sdata); |
207 | kernel_data.end = virt_to_phys(_end - 1); | 207 | kernel_data.end = virt_to_phys(_end - 1); |
208 | 208 | ||
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index a68e0ccd9f4b..76a6d9263908 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c | |||
@@ -267,7 +267,6 @@ asmlinkage void secondary_start_kernel(void) | |||
267 | set_cpu_online(cpu, true); | 267 | set_cpu_online(cpu, true); |
268 | complete(&cpu_running); | 268 | complete(&cpu_running); |
269 | 269 | ||
270 | local_dbg_enable(); | ||
271 | local_irq_enable(); | 270 | local_irq_enable(); |
272 | local_async_enable(); | 271 | local_async_enable(); |
273 | 272 | ||
@@ -437,9 +436,9 @@ void __init smp_cpus_done(unsigned int max_cpus) | |||
437 | 436 | ||
438 | void __init smp_prepare_boot_cpu(void) | 437 | void __init smp_prepare_boot_cpu(void) |
439 | { | 438 | { |
439 | set_my_cpu_offset(per_cpu_offset(smp_processor_id())); | ||
440 | cpuinfo_store_boot_cpu(); | 440 | cpuinfo_store_boot_cpu(); |
441 | save_boot_cpu_run_el(); | 441 | save_boot_cpu_run_el(); |
442 | set_my_cpu_offset(per_cpu_offset(smp_processor_id())); | ||
443 | } | 442 | } |
444 | 443 | ||
445 | static u64 __init of_get_cpu_mpidr(struct device_node *dn) | 444 | static u64 __init of_get_cpu_mpidr(struct device_node *dn) |
@@ -696,6 +695,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
696 | smp_store_cpu_info(smp_processor_id()); | 695 | smp_store_cpu_info(smp_processor_id()); |
697 | 696 | ||
698 | /* | 697 | /* |
698 | * If UP is mandated by "nosmp" (which implies "maxcpus=0"), don't set | ||
699 | * secondary CPUs present. | ||
700 | */ | ||
701 | if (max_cpus == 0) | ||
702 | return; | ||
703 | |||
704 | /* | ||
699 | * Initialise the present map (which describes the set of CPUs | 705 | * Initialise the present map (which describes the set of CPUs |
700 | * actually populated at the present time) and release the | 706 | * actually populated at the present time) and release the |
701 | * secondaries from the bootloader. | 707 | * secondaries from the bootloader. |
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 2a43012616b7..e04f83873af7 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <asm/stacktrace.h> | 41 | #include <asm/stacktrace.h> |
42 | #include <asm/exception.h> | 42 | #include <asm/exception.h> |
43 | #include <asm/system_misc.h> | 43 | #include <asm/system_misc.h> |
44 | #include <asm/sysreg.h> | ||
44 | 45 | ||
45 | static const char *handler[]= { | 46 | static const char *handler[]= { |
46 | "Synchronous Abort", | 47 | "Synchronous Abort", |
@@ -52,15 +53,14 @@ static const char *handler[]= { | |||
52 | int show_unhandled_signals = 1; | 53 | int show_unhandled_signals = 1; |
53 | 54 | ||
54 | /* | 55 | /* |
55 | * Dump out the contents of some memory nicely... | 56 | * Dump out the contents of some kernel memory nicely... |
56 | */ | 57 | */ |
57 | static void dump_mem(const char *lvl, const char *str, unsigned long bottom, | 58 | static void dump_mem(const char *lvl, const char *str, unsigned long bottom, |
58 | unsigned long top, bool compat) | 59 | unsigned long top) |
59 | { | 60 | { |
60 | unsigned long first; | 61 | unsigned long first; |
61 | mm_segment_t fs; | 62 | mm_segment_t fs; |
62 | int i; | 63 | int i; |
63 | unsigned int width = compat ? 4 : 8; | ||
64 | 64 | ||
65 | /* | 65 | /* |
66 | * We need to switch to kernel mode so that we can use __get_user | 66 | * We need to switch to kernel mode so that we can use __get_user |
@@ -78,22 +78,15 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, | |||
78 | memset(str, ' ', sizeof(str)); | 78 | memset(str, ' ', sizeof(str)); |
79 | str[sizeof(str) - 1] = '\0'; | 79 | str[sizeof(str) - 1] = '\0'; |
80 | 80 | ||
81 | for (p = first, i = 0; i < (32 / width) | 81 | for (p = first, i = 0; i < (32 / 8) |
82 | && p < top; i++, p += width) { | 82 | && p < top; i++, p += 8) { |
83 | if (p >= bottom && p < top) { | 83 | if (p >= bottom && p < top) { |
84 | unsigned long val; | 84 | unsigned long val; |
85 | 85 | ||
86 | if (width == 8) { | 86 | if (__get_user(val, (unsigned long *)p) == 0) |
87 | if (__get_user(val, (unsigned long *)p) == 0) | 87 | sprintf(str + i * 17, " %016lx", val); |
88 | sprintf(str + i * 17, " %016lx", val); | 88 | else |
89 | else | 89 | sprintf(str + i * 17, " ????????????????"); |
90 | sprintf(str + i * 17, " ????????????????"); | ||
91 | } else { | ||
92 | if (__get_user(val, (unsigned int *)p) == 0) | ||
93 | sprintf(str + i * 9, " %08lx", val); | ||
94 | else | ||
95 | sprintf(str + i * 9, " ????????"); | ||
96 | } | ||
97 | } | 90 | } |
98 | } | 91 | } |
99 | printk("%s%04lx:%s\n", lvl, first & 0xffff, str); | 92 | printk("%s%04lx:%s\n", lvl, first & 0xffff, str); |
@@ -216,7 +209,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) | |||
216 | stack = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); | 209 | stack = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); |
217 | 210 | ||
218 | dump_mem("", "Exception stack", stack, | 211 | dump_mem("", "Exception stack", stack, |
219 | stack + sizeof(struct pt_regs), false); | 212 | stack + sizeof(struct pt_regs)); |
220 | } | 213 | } |
221 | } | 214 | } |
222 | } | 215 | } |
@@ -254,10 +247,9 @@ static int __die(const char *str, int err, struct thread_info *thread, | |||
254 | pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", | 247 | pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", |
255 | TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1); | 248 | TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1); |
256 | 249 | ||
257 | if (!user_mode(regs) || in_interrupt()) { | 250 | if (!user_mode(regs)) { |
258 | dump_mem(KERN_EMERG, "Stack: ", regs->sp, | 251 | dump_mem(KERN_EMERG, "Stack: ", regs->sp, |
259 | THREAD_SIZE + (unsigned long)task_stack_page(tsk), | 252 | THREAD_SIZE + (unsigned long)task_stack_page(tsk)); |
260 | compat_user_mode(regs)); | ||
261 | dump_backtrace(regs, tsk); | 253 | dump_backtrace(regs, tsk); |
262 | dump_instr(KERN_EMERG, regs); | 254 | dump_instr(KERN_EMERG, regs); |
263 | } | 255 | } |
@@ -373,11 +365,59 @@ exit: | |||
373 | return fn ? fn(regs, instr) : 1; | 365 | return fn ? fn(regs, instr) : 1; |
374 | } | 366 | } |
375 | 367 | ||
376 | asmlinkage void __exception do_undefinstr(struct pt_regs *regs) | 368 | static void force_signal_inject(int signal, int code, struct pt_regs *regs, |
369 | unsigned long address) | ||
377 | { | 370 | { |
378 | siginfo_t info; | 371 | siginfo_t info; |
379 | void __user *pc = (void __user *)instruction_pointer(regs); | 372 | void __user *pc = (void __user *)instruction_pointer(regs); |
373 | const char *desc; | ||
380 | 374 | ||
375 | switch (signal) { | ||
376 | case SIGILL: | ||
377 | desc = "undefined instruction"; | ||
378 | break; | ||
379 | case SIGSEGV: | ||
380 | desc = "illegal memory access"; | ||
381 | break; | ||
382 | default: | ||
383 | desc = "bad mode"; | ||
384 | break; | ||
385 | } | ||
386 | |||
387 | if (unhandled_signal(current, signal) && | ||
388 | show_unhandled_signals_ratelimited()) { | ||
389 | pr_info("%s[%d]: %s: pc=%p\n", | ||
390 | current->comm, task_pid_nr(current), desc, pc); | ||
391 | dump_instr(KERN_INFO, regs); | ||
392 | } | ||
393 | |||
394 | info.si_signo = signal; | ||
395 | info.si_errno = 0; | ||
396 | info.si_code = code; | ||
397 | info.si_addr = pc; | ||
398 | |||
399 | arm64_notify_die(desc, regs, &info, 0); | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * Set up process info to signal segmentation fault - called on access error. | ||
404 | */ | ||
405 | void arm64_notify_segfault(struct pt_regs *regs, unsigned long addr) | ||
406 | { | ||
407 | int code; | ||
408 | |||
409 | down_read(¤t->mm->mmap_sem); | ||
410 | if (find_vma(current->mm, addr) == NULL) | ||
411 | code = SEGV_MAPERR; | ||
412 | else | ||
413 | code = SEGV_ACCERR; | ||
414 | up_read(¤t->mm->mmap_sem); | ||
415 | |||
416 | force_signal_inject(SIGSEGV, code, regs, addr); | ||
417 | } | ||
418 | |||
419 | asmlinkage void __exception do_undefinstr(struct pt_regs *regs) | ||
420 | { | ||
381 | /* check for AArch32 breakpoint instructions */ | 421 | /* check for AArch32 breakpoint instructions */ |
382 | if (!aarch32_break_handler(regs)) | 422 | if (!aarch32_break_handler(regs)) |
383 | return; | 423 | return; |
@@ -385,18 +425,66 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) | |||
385 | if (call_undef_hook(regs) == 0) | 425 | if (call_undef_hook(regs) == 0) |
386 | return; | 426 | return; |
387 | 427 | ||
388 | if (unhandled_signal(current, SIGILL) && show_unhandled_signals_ratelimited()) { | 428 | force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0); |
389 | pr_info("%s[%d]: undefined instruction: pc=%p\n", | 429 | } |
390 | current->comm, task_pid_nr(current), pc); | ||
391 | dump_instr(KERN_INFO, regs); | ||
392 | } | ||
393 | 430 | ||
394 | info.si_signo = SIGILL; | 431 | void cpu_enable_cache_maint_trap(void *__unused) |
395 | info.si_errno = 0; | 432 | { |
396 | info.si_code = ILL_ILLOPC; | 433 | config_sctlr_el1(SCTLR_EL1_UCI, 0); |
397 | info.si_addr = pc; | 434 | } |
435 | |||
436 | #define __user_cache_maint(insn, address, res) \ | ||
437 | asm volatile ( \ | ||
438 | "1: " insn ", %1\n" \ | ||
439 | " mov %w0, #0\n" \ | ||
440 | "2:\n" \ | ||
441 | " .pushsection .fixup,\"ax\"\n" \ | ||
442 | " .align 2\n" \ | ||
443 | "3: mov %w0, %w2\n" \ | ||
444 | " b 2b\n" \ | ||
445 | " .popsection\n" \ | ||
446 | _ASM_EXTABLE(1b, 3b) \ | ||
447 | : "=r" (res) \ | ||
448 | : "r" (address), "i" (-EFAULT) ) | ||
449 | |||
450 | asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs) | ||
451 | { | ||
452 | unsigned long address; | ||
453 | int ret; | ||
398 | 454 | ||
399 | arm64_notify_die("Oops - undefined instruction", regs, &info, 0); | 455 | /* if this is a write with: Op0=1, Op2=1, Op1=3, CRn=7 */ |
456 | if ((esr & 0x01fffc01) == 0x0012dc00) { | ||
457 | int rt = (esr >> 5) & 0x1f; | ||
458 | int crm = (esr >> 1) & 0x0f; | ||
459 | |||
460 | address = (rt == 31) ? 0 : regs->regs[rt]; | ||
461 | |||
462 | switch (crm) { | ||
463 | case 11: /* DC CVAU, gets promoted */ | ||
464 | __user_cache_maint("dc civac", address, ret); | ||
465 | break; | ||
466 | case 10: /* DC CVAC, gets promoted */ | ||
467 | __user_cache_maint("dc civac", address, ret); | ||
468 | break; | ||
469 | case 14: /* DC CIVAC */ | ||
470 | __user_cache_maint("dc civac", address, ret); | ||
471 | break; | ||
472 | case 5: /* IC IVAU */ | ||
473 | __user_cache_maint("ic ivau", address, ret); | ||
474 | break; | ||
475 | default: | ||
476 | force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0); | ||
477 | return; | ||
478 | } | ||
479 | } else { | ||
480 | force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0); | ||
481 | return; | ||
482 | } | ||
483 | |||
484 | if (ret) | ||
485 | arm64_notify_segfault(regs, address); | ||
486 | else | ||
487 | regs->pc += 4; | ||
400 | } | 488 | } |
401 | 489 | ||
402 | long compat_arm_syscall(struct pt_regs *regs); | 490 | long compat_arm_syscall(struct pt_regs *regs); |
@@ -465,7 +553,7 @@ static const char *esr_class_str[] = { | |||
465 | 553 | ||
466 | const char *esr_get_class_string(u32 esr) | 554 | const char *esr_get_class_string(u32 esr) |
467 | { | 555 | { |
468 | return esr_class_str[esr >> ESR_ELx_EC_SHIFT]; | 556 | return esr_class_str[ESR_ELx_EC(esr)]; |
469 | } | 557 | } |
470 | 558 | ||
471 | /* | 559 | /* |
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 9fefb005812a..076312b17d4f 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c | |||
@@ -214,10 +214,16 @@ void update_vsyscall(struct timekeeper *tk) | |||
214 | vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; | 214 | vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; |
215 | 215 | ||
216 | if (!use_syscall) { | 216 | if (!use_syscall) { |
217 | /* tkr_mono.cycle_last == tkr_raw.cycle_last */ | ||
217 | vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; | 218 | vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; |
219 | vdso_data->raw_time_sec = tk->raw_time.tv_sec; | ||
220 | vdso_data->raw_time_nsec = tk->raw_time.tv_nsec; | ||
218 | vdso_data->xtime_clock_sec = tk->xtime_sec; | 221 | vdso_data->xtime_clock_sec = tk->xtime_sec; |
219 | vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; | 222 | vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; |
220 | vdso_data->cs_mult = tk->tkr_mono.mult; | 223 | /* tkr_raw.xtime_nsec == 0 */ |
224 | vdso_data->cs_mono_mult = tk->tkr_mono.mult; | ||
225 | vdso_data->cs_raw_mult = tk->tkr_raw.mult; | ||
226 | /* tkr_mono.shift == tkr_raw.shift */ | ||
221 | vdso_data->cs_shift = tk->tkr_mono.shift; | 227 | vdso_data->cs_shift = tk->tkr_mono.shift; |
222 | } | 228 | } |
223 | 229 | ||
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index b467fd0a384b..62c84f7cb01b 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile | |||
@@ -23,7 +23,7 @@ GCOV_PROFILE := n | |||
23 | ccflags-y += -Wl,-shared | 23 | ccflags-y += -Wl,-shared |
24 | 24 | ||
25 | obj-y += vdso.o | 25 | obj-y += vdso.o |
26 | extra-y += vdso.lds vdso-offsets.h | 26 | extra-y += vdso.lds |
27 | CPPFLAGS_vdso.lds += -P -C -U$(ARCH) | 27 | CPPFLAGS_vdso.lds += -P -C -U$(ARCH) |
28 | 28 | ||
29 | # Force dependency (incbin is bad) | 29 | # Force dependency (incbin is bad) |
@@ -42,11 +42,10 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE | |||
42 | gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh | 42 | gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh |
43 | quiet_cmd_vdsosym = VDSOSYM $@ | 43 | quiet_cmd_vdsosym = VDSOSYM $@ |
44 | define cmd_vdsosym | 44 | define cmd_vdsosym |
45 | $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ && \ | 45 | $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ |
46 | cp $@ include/generated/ | ||
47 | endef | 46 | endef |
48 | 47 | ||
49 | $(obj)/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE | 48 | include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE |
50 | $(call if_changed,vdsosym) | 49 | $(call if_changed,vdsosym) |
51 | 50 | ||
52 | # Assembly rules for the .S files | 51 | # Assembly rules for the .S files |
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S index efa79e8d4196..e00b4671bd7c 100644 --- a/arch/arm64/kernel/vdso/gettimeofday.S +++ b/arch/arm64/kernel/vdso/gettimeofday.S | |||
@@ -26,24 +26,109 @@ | |||
26 | #define NSEC_PER_SEC_HI16 0x3b9a | 26 | #define NSEC_PER_SEC_HI16 0x3b9a |
27 | 27 | ||
28 | vdso_data .req x6 | 28 | vdso_data .req x6 |
29 | use_syscall .req w7 | 29 | seqcnt .req w7 |
30 | seqcnt .req w8 | 30 | w_tmp .req w8 |
31 | x_tmp .req x8 | ||
32 | |||
33 | /* | ||
34 | * Conventions for macro arguments: | ||
35 | * - An argument is write-only if its name starts with "res". | ||
36 | * - All other arguments are read-only, unless otherwise specified. | ||
37 | */ | ||
31 | 38 | ||
32 | .macro seqcnt_acquire | 39 | .macro seqcnt_acquire |
33 | 9999: ldr seqcnt, [vdso_data, #VDSO_TB_SEQ_COUNT] | 40 | 9999: ldr seqcnt, [vdso_data, #VDSO_TB_SEQ_COUNT] |
34 | tbnz seqcnt, #0, 9999b | 41 | tbnz seqcnt, #0, 9999b |
35 | dmb ishld | 42 | dmb ishld |
36 | ldr use_syscall, [vdso_data, #VDSO_USE_SYSCALL] | ||
37 | .endm | 43 | .endm |
38 | 44 | ||
39 | .macro seqcnt_read, cnt | 45 | .macro seqcnt_check fail |
40 | dmb ishld | 46 | dmb ishld |
41 | ldr \cnt, [vdso_data, #VDSO_TB_SEQ_COUNT] | 47 | ldr w_tmp, [vdso_data, #VDSO_TB_SEQ_COUNT] |
48 | cmp w_tmp, seqcnt | ||
49 | b.ne \fail | ||
42 | .endm | 50 | .endm |
43 | 51 | ||
44 | .macro seqcnt_check, cnt, fail | 52 | .macro syscall_check fail |
45 | cmp \cnt, seqcnt | 53 | ldr w_tmp, [vdso_data, #VDSO_USE_SYSCALL] |
46 | b.ne \fail | 54 | cbnz w_tmp, \fail |
55 | .endm | ||
56 | |||
57 | .macro get_nsec_per_sec res | ||
58 | mov \res, #NSEC_PER_SEC_LO16 | ||
59 | movk \res, #NSEC_PER_SEC_HI16, lsl #16 | ||
60 | .endm | ||
61 | |||
62 | /* | ||
63 | * Returns the clock delta, in nanoseconds left-shifted by the clock | ||
64 | * shift. | ||
65 | */ | ||
66 | .macro get_clock_shifted_nsec res, cycle_last, mult | ||
67 | /* Read the virtual counter. */ | ||
68 | isb | ||
69 | mrs x_tmp, cntvct_el0 | ||
70 | /* Calculate cycle delta and convert to ns. */ | ||
71 | sub \res, x_tmp, \cycle_last | ||
72 | /* We can only guarantee 56 bits of precision. */ | ||
73 | movn x_tmp, #0xff00, lsl #48 | ||
74 | and \res, x_tmp, \res | ||
75 | mul \res, \res, \mult | ||
76 | .endm | ||
77 | |||
78 | /* | ||
79 | * Returns in res_{sec,nsec} the REALTIME timespec, based on the | ||
80 | * "wall time" (xtime) and the clock_mono delta. | ||
81 | */ | ||
82 | .macro get_ts_realtime res_sec, res_nsec, \ | ||
83 | clock_nsec, xtime_sec, xtime_nsec, nsec_to_sec | ||
84 | add \res_nsec, \clock_nsec, \xtime_nsec | ||
85 | udiv x_tmp, \res_nsec, \nsec_to_sec | ||
86 | add \res_sec, \xtime_sec, x_tmp | ||
87 | msub \res_nsec, x_tmp, \nsec_to_sec, \res_nsec | ||
88 | .endm | ||
89 | |||
90 | /* | ||
91 | * Returns in res_{sec,nsec} the timespec based on the clock_raw delta, | ||
92 | * used for CLOCK_MONOTONIC_RAW. | ||
93 | */ | ||
94 | .macro get_ts_clock_raw res_sec, res_nsec, clock_nsec, nsec_to_sec | ||
95 | udiv \res_sec, \clock_nsec, \nsec_to_sec | ||
96 | msub \res_nsec, \res_sec, \nsec_to_sec, \clock_nsec | ||
97 | .endm | ||
98 | |||
99 | /* sec and nsec are modified in place. */ | ||
100 | .macro add_ts sec, nsec, ts_sec, ts_nsec, nsec_to_sec | ||
101 | /* Add timespec. */ | ||
102 | add \sec, \sec, \ts_sec | ||
103 | add \nsec, \nsec, \ts_nsec | ||
104 | |||
105 | /* Normalise the new timespec. */ | ||
106 | cmp \nsec, \nsec_to_sec | ||
107 | b.lt 9999f | ||
108 | sub \nsec, \nsec, \nsec_to_sec | ||
109 | add \sec, \sec, #1 | ||
110 | 9999: | ||
111 | cmp \nsec, #0 | ||
112 | b.ge 9998f | ||
113 | add \nsec, \nsec, \nsec_to_sec | ||
114 | sub \sec, \sec, #1 | ||
115 | 9998: | ||
116 | .endm | ||
117 | |||
118 | .macro clock_gettime_return, shift=0 | ||
119 | .if \shift == 1 | ||
120 | lsr x11, x11, x12 | ||
121 | .endif | ||
122 | stp x10, x11, [x1, #TSPEC_TV_SEC] | ||
123 | mov x0, xzr | ||
124 | ret | ||
125 | .endm | ||
126 | |||
127 | .macro jump_slot jumptable, index, label | ||
128 | .if (. - \jumptable) != 4 * (\index) | ||
129 | .error "Jump slot index mismatch" | ||
130 | .endif | ||
131 | b \label | ||
47 | .endm | 132 | .endm |
48 | 133 | ||
49 | .text | 134 | .text |
@@ -51,18 +136,25 @@ seqcnt .req w8 | |||
51 | /* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */ | 136 | /* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */ |
52 | ENTRY(__kernel_gettimeofday) | 137 | ENTRY(__kernel_gettimeofday) |
53 | .cfi_startproc | 138 | .cfi_startproc |
54 | mov x2, x30 | ||
55 | .cfi_register x30, x2 | ||
56 | |||
57 | /* Acquire the sequence counter and get the timespec. */ | ||
58 | adr vdso_data, _vdso_data | 139 | adr vdso_data, _vdso_data |
59 | 1: seqcnt_acquire | ||
60 | cbnz use_syscall, 4f | ||
61 | |||
62 | /* If tv is NULL, skip to the timezone code. */ | 140 | /* If tv is NULL, skip to the timezone code. */ |
63 | cbz x0, 2f | 141 | cbz x0, 2f |
64 | bl __do_get_tspec | 142 | |
65 | seqcnt_check w9, 1b | 143 | /* Compute the time of day. */ |
144 | 1: seqcnt_acquire | ||
145 | syscall_check fail=4f | ||
146 | ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST] | ||
147 | /* w11 = cs_mono_mult, w12 = cs_shift */ | ||
148 | ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT] | ||
149 | ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC] | ||
150 | seqcnt_check fail=1b | ||
151 | |||
152 | get_nsec_per_sec res=x9 | ||
153 | lsl x9, x9, x12 | ||
154 | |||
155 | get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11 | ||
156 | get_ts_realtime res_sec=x10, res_nsec=x11, \ | ||
157 | clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9 | ||
66 | 158 | ||
67 | /* Convert ns to us. */ | 159 | /* Convert ns to us. */ |
68 | mov x13, #1000 | 160 | mov x13, #1000 |
@@ -76,95 +168,126 @@ ENTRY(__kernel_gettimeofday) | |||
76 | stp w4, w5, [x1, #TZ_MINWEST] | 168 | stp w4, w5, [x1, #TZ_MINWEST] |
77 | 3: | 169 | 3: |
78 | mov x0, xzr | 170 | mov x0, xzr |
79 | ret x2 | 171 | ret |
80 | 4: | 172 | 4: |
81 | /* Syscall fallback. */ | 173 | /* Syscall fallback. */ |
82 | mov x8, #__NR_gettimeofday | 174 | mov x8, #__NR_gettimeofday |
83 | svc #0 | 175 | svc #0 |
84 | ret x2 | 176 | ret |
85 | .cfi_endproc | 177 | .cfi_endproc |
86 | ENDPROC(__kernel_gettimeofday) | 178 | ENDPROC(__kernel_gettimeofday) |
87 | 179 | ||
180 | #define JUMPSLOT_MAX CLOCK_MONOTONIC_COARSE | ||
181 | |||
88 | /* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */ | 182 | /* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */ |
89 | ENTRY(__kernel_clock_gettime) | 183 | ENTRY(__kernel_clock_gettime) |
90 | .cfi_startproc | 184 | .cfi_startproc |
91 | cmp w0, #CLOCK_REALTIME | 185 | cmp w0, #JUMPSLOT_MAX |
92 | ccmp w0, #CLOCK_MONOTONIC, #0x4, ne | 186 | b.hi syscall |
93 | b.ne 2f | 187 | adr vdso_data, _vdso_data |
188 | adr x_tmp, jumptable | ||
189 | add x_tmp, x_tmp, w0, uxtw #2 | ||
190 | br x_tmp | ||
191 | |||
192 | ALIGN | ||
193 | jumptable: | ||
194 | jump_slot jumptable, CLOCK_REALTIME, realtime | ||
195 | jump_slot jumptable, CLOCK_MONOTONIC, monotonic | ||
196 | b syscall | ||
197 | b syscall | ||
198 | jump_slot jumptable, CLOCK_MONOTONIC_RAW, monotonic_raw | ||
199 | jump_slot jumptable, CLOCK_REALTIME_COARSE, realtime_coarse | ||
200 | jump_slot jumptable, CLOCK_MONOTONIC_COARSE, monotonic_coarse | ||
201 | |||
202 | .if (. - jumptable) != 4 * (JUMPSLOT_MAX + 1) | ||
203 | .error "Wrong jumptable size" | ||
204 | .endif | ||
205 | |||
206 | ALIGN | ||
207 | realtime: | ||
208 | seqcnt_acquire | ||
209 | syscall_check fail=syscall | ||
210 | ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST] | ||
211 | /* w11 = cs_mono_mult, w12 = cs_shift */ | ||
212 | ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT] | ||
213 | ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC] | ||
214 | seqcnt_check fail=realtime | ||
94 | 215 | ||
95 | mov x2, x30 | 216 | /* All computations are done with left-shifted nsecs. */ |
96 | .cfi_register x30, x2 | 217 | get_nsec_per_sec res=x9 |
218 | lsl x9, x9, x12 | ||
97 | 219 | ||
98 | /* Get kernel timespec. */ | 220 | get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11 |
99 | adr vdso_data, _vdso_data | 221 | get_ts_realtime res_sec=x10, res_nsec=x11, \ |
100 | 1: seqcnt_acquire | 222 | clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9 |
101 | cbnz use_syscall, 7f | 223 | clock_gettime_return, shift=1 |
102 | 224 | ||
103 | bl __do_get_tspec | 225 | ALIGN |
104 | seqcnt_check w9, 1b | 226 | monotonic: |
227 | seqcnt_acquire | ||
228 | syscall_check fail=syscall | ||
229 | ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST] | ||
230 | /* w11 = cs_mono_mult, w12 = cs_shift */ | ||
231 | ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT] | ||
232 | ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC] | ||
233 | ldp x3, x4, [vdso_data, #VDSO_WTM_CLK_SEC] | ||
234 | seqcnt_check fail=monotonic | ||
105 | 235 | ||
106 | mov x30, x2 | 236 | /* All computations are done with left-shifted nsecs. */ |
237 | lsl x4, x4, x12 | ||
238 | get_nsec_per_sec res=x9 | ||
239 | lsl x9, x9, x12 | ||
107 | 240 | ||
108 | cmp w0, #CLOCK_MONOTONIC | 241 | get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11 |
109 | b.ne 6f | 242 | get_ts_realtime res_sec=x10, res_nsec=x11, \ |
243 | clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9 | ||
110 | 244 | ||
111 | /* Get wtm timespec. */ | 245 | add_ts sec=x10, nsec=x11, ts_sec=x3, ts_nsec=x4, nsec_to_sec=x9 |
112 | ldp x13, x14, [vdso_data, #VDSO_WTM_CLK_SEC] | 246 | clock_gettime_return, shift=1 |
113 | 247 | ||
114 | /* Check the sequence counter. */ | 248 | ALIGN |
115 | seqcnt_read w9 | 249 | monotonic_raw: |
116 | seqcnt_check w9, 1b | 250 | seqcnt_acquire |
117 | b 4f | 251 | syscall_check fail=syscall |
118 | 2: | 252 | ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST] |
119 | cmp w0, #CLOCK_REALTIME_COARSE | 253 | /* w11 = cs_raw_mult, w12 = cs_shift */ |
120 | ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne | 254 | ldp w12, w11, [vdso_data, #VDSO_CS_SHIFT] |
121 | b.ne 8f | 255 | ldp x13, x14, [vdso_data, #VDSO_RAW_TIME_SEC] |
256 | seqcnt_check fail=monotonic_raw | ||
122 | 257 | ||
123 | /* xtime_coarse_nsec is already right-shifted */ | 258 | /* All computations are done with left-shifted nsecs. */ |
124 | mov x12, #0 | 259 | lsl x14, x14, x12 |
260 | get_nsec_per_sec res=x9 | ||
261 | lsl x9, x9, x12 | ||
125 | 262 | ||
126 | /* Get coarse timespec. */ | 263 | get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11 |
127 | adr vdso_data, _vdso_data | 264 | get_ts_clock_raw res_sec=x10, res_nsec=x11, \ |
128 | 3: seqcnt_acquire | 265 | clock_nsec=x15, nsec_to_sec=x9 |
266 | |||
267 | add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9 | ||
268 | clock_gettime_return, shift=1 | ||
269 | |||
270 | ALIGN | ||
271 | realtime_coarse: | ||
272 | seqcnt_acquire | ||
129 | ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC] | 273 | ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC] |
274 | seqcnt_check fail=realtime_coarse | ||
275 | clock_gettime_return | ||
130 | 276 | ||
131 | /* Get wtm timespec. */ | 277 | ALIGN |
278 | monotonic_coarse: | ||
279 | seqcnt_acquire | ||
280 | ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC] | ||
132 | ldp x13, x14, [vdso_data, #VDSO_WTM_CLK_SEC] | 281 | ldp x13, x14, [vdso_data, #VDSO_WTM_CLK_SEC] |
282 | seqcnt_check fail=monotonic_coarse | ||
133 | 283 | ||
134 | /* Check the sequence counter. */ | 284 | /* Computations are done in (non-shifted) nsecs. */ |
135 | seqcnt_read w9 | 285 | get_nsec_per_sec res=x9 |
136 | seqcnt_check w9, 3b | 286 | add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9 |
287 | clock_gettime_return | ||
137 | 288 | ||
138 | cmp w0, #CLOCK_MONOTONIC_COARSE | 289 | ALIGN |
139 | b.ne 6f | 290 | syscall: /* Syscall fallback. */ |
140 | 4: | ||
141 | /* Add on wtm timespec. */ | ||
142 | add x10, x10, x13 | ||
143 | lsl x14, x14, x12 | ||
144 | add x11, x11, x14 | ||
145 | |||
146 | /* Normalise the new timespec. */ | ||
147 | mov x15, #NSEC_PER_SEC_LO16 | ||
148 | movk x15, #NSEC_PER_SEC_HI16, lsl #16 | ||
149 | lsl x15, x15, x12 | ||
150 | cmp x11, x15 | ||
151 | b.lt 5f | ||
152 | sub x11, x11, x15 | ||
153 | add x10, x10, #1 | ||
154 | 5: | ||
155 | cmp x11, #0 | ||
156 | b.ge 6f | ||
157 | add x11, x11, x15 | ||
158 | sub x10, x10, #1 | ||
159 | |||
160 | 6: /* Store to the user timespec. */ | ||
161 | lsr x11, x11, x12 | ||
162 | stp x10, x11, [x1, #TSPEC_TV_SEC] | ||
163 | mov x0, xzr | ||
164 | ret | ||
165 | 7: | ||
166 | mov x30, x2 | ||
167 | 8: /* Syscall fallback. */ | ||
168 | mov x8, #__NR_clock_gettime | 291 | mov x8, #__NR_clock_gettime |
169 | svc #0 | 292 | svc #0 |
170 | ret | 293 | ret |
@@ -176,6 +299,7 @@ ENTRY(__kernel_clock_getres) | |||
176 | .cfi_startproc | 299 | .cfi_startproc |
177 | cmp w0, #CLOCK_REALTIME | 300 | cmp w0, #CLOCK_REALTIME |
178 | ccmp w0, #CLOCK_MONOTONIC, #0x4, ne | 301 | ccmp w0, #CLOCK_MONOTONIC, #0x4, ne |
302 | ccmp w0, #CLOCK_MONOTONIC_RAW, #0x4, ne | ||
179 | b.ne 1f | 303 | b.ne 1f |
180 | 304 | ||
181 | ldr x2, 5f | 305 | ldr x2, 5f |
@@ -203,46 +327,3 @@ ENTRY(__kernel_clock_getres) | |||
203 | .quad CLOCK_COARSE_RES | 327 | .quad CLOCK_COARSE_RES |
204 | .cfi_endproc | 328 | .cfi_endproc |
205 | ENDPROC(__kernel_clock_getres) | 329 | ENDPROC(__kernel_clock_getres) |
206 | |||
207 | /* | ||
208 | * Read the current time from the architected counter. | ||
209 | * Expects vdso_data to be initialised. | ||
210 | * Clobbers the temporary registers (x9 - x15). | ||
211 | * Returns: | ||
212 | * - w9 = vDSO sequence counter | ||
213 | * - (x10, x11) = (ts->tv_sec, shifted ts->tv_nsec) | ||
214 | * - w12 = cs_shift | ||
215 | */ | ||
216 | ENTRY(__do_get_tspec) | ||
217 | .cfi_startproc | ||
218 | |||
219 | /* Read from the vDSO data page. */ | ||
220 | ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST] | ||
221 | ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC] | ||
222 | ldp w11, w12, [vdso_data, #VDSO_CS_MULT] | ||
223 | seqcnt_read w9 | ||
224 | |||
225 | /* Read the virtual counter. */ | ||
226 | isb | ||
227 | mrs x15, cntvct_el0 | ||
228 | |||
229 | /* Calculate cycle delta and convert to ns. */ | ||
230 | sub x10, x15, x10 | ||
231 | /* We can only guarantee 56 bits of precision. */ | ||
232 | movn x15, #0xff00, lsl #48 | ||
233 | and x10, x15, x10 | ||
234 | mul x10, x10, x11 | ||
235 | |||
236 | /* Use the kernel time to calculate the new timespec. */ | ||
237 | mov x11, #NSEC_PER_SEC_LO16 | ||
238 | movk x11, #NSEC_PER_SEC_HI16, lsl #16 | ||
239 | lsl x11, x11, x12 | ||
240 | add x15, x10, x14 | ||
241 | udiv x14, x15, x11 | ||
242 | add x10, x13, x14 | ||
243 | mul x13, x14, x11 | ||
244 | sub x11, x15, x13 | ||
245 | |||
246 | ret | ||
247 | .cfi_endproc | ||
248 | ENDPROC(__do_get_tspec) | ||
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 435e820e898d..89d6e177ecbd 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S | |||
@@ -118,9 +118,11 @@ SECTIONS | |||
118 | __exception_text_end = .; | 118 | __exception_text_end = .; |
119 | IRQENTRY_TEXT | 119 | IRQENTRY_TEXT |
120 | SOFTIRQENTRY_TEXT | 120 | SOFTIRQENTRY_TEXT |
121 | ENTRY_TEXT | ||
121 | TEXT_TEXT | 122 | TEXT_TEXT |
122 | SCHED_TEXT | 123 | SCHED_TEXT |
123 | LOCK_TEXT | 124 | LOCK_TEXT |
125 | KPROBES_TEXT | ||
124 | HYPERVISOR_TEXT | 126 | HYPERVISOR_TEXT |
125 | IDMAP_TEXT | 127 | IDMAP_TEXT |
126 | HIBERNATE_TEXT | 128 | HIBERNATE_TEXT |
@@ -131,12 +133,13 @@ SECTIONS | |||
131 | } | 133 | } |
132 | 134 | ||
133 | . = ALIGN(SEGMENT_ALIGN); | 135 | . = ALIGN(SEGMENT_ALIGN); |
134 | RO_DATA(PAGE_SIZE) /* everything from this point to */ | 136 | _etext = .; /* End of text section */ |
135 | EXCEPTION_TABLE(8) /* _etext will be marked RO NX */ | 137 | |
138 | RO_DATA(PAGE_SIZE) /* everything from this point to */ | ||
139 | EXCEPTION_TABLE(8) /* __init_begin will be marked RO NX */ | ||
136 | NOTES | 140 | NOTES |
137 | 141 | ||
138 | . = ALIGN(SEGMENT_ALIGN); | 142 | . = ALIGN(SEGMENT_ALIGN); |
139 | _etext = .; /* End of text and rodata section */ | ||
140 | __init_begin = .; | 143 | __init_begin = .; |
141 | 144 | ||
142 | INIT_TEXT_SECTION(8) | 145 | INIT_TEXT_SECTION(8) |
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 3246c4aba5b1..fa96fe2bd469 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c | |||
@@ -106,7 +106,7 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
106 | run->exit_reason = KVM_EXIT_DEBUG; | 106 | run->exit_reason = KVM_EXIT_DEBUG; |
107 | run->debug.arch.hsr = hsr; | 107 | run->debug.arch.hsr = hsr; |
108 | 108 | ||
109 | switch (hsr >> ESR_ELx_EC_SHIFT) { | 109 | switch (ESR_ELx_EC(hsr)) { |
110 | case ESR_ELx_EC_WATCHPT_LOW: | 110 | case ESR_ELx_EC_WATCHPT_LOW: |
111 | run->debug.arch.far = vcpu->arch.fault.far_el2; | 111 | run->debug.arch.far = vcpu->arch.fault.far_el2; |
112 | /* fall through */ | 112 | /* fall through */ |
@@ -149,7 +149,7 @@ static exit_handle_fn arm_exit_handlers[] = { | |||
149 | static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu) | 149 | static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu) |
150 | { | 150 | { |
151 | u32 hsr = kvm_vcpu_get_hsr(vcpu); | 151 | u32 hsr = kvm_vcpu_get_hsr(vcpu); |
152 | u8 hsr_ec = hsr >> ESR_ELx_EC_SHIFT; | 152 | u8 hsr_ec = ESR_ELx_EC(hsr); |
153 | 153 | ||
154 | if (hsr_ec >= ARRAY_SIZE(arm_exit_handlers) || | 154 | if (hsr_ec >= ARRAY_SIZE(arm_exit_handlers) || |
155 | !arm_exit_handlers[hsr_ec]) { | 155 | !arm_exit_handlers[hsr_ec]) { |
diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile index 778d0effa2af..0c85febcc1eb 100644 --- a/arch/arm64/kvm/hyp/Makefile +++ b/arch/arm64/kvm/hyp/Makefile | |||
@@ -17,6 +17,10 @@ obj-$(CONFIG_KVM_ARM_HOST) += tlb.o | |||
17 | obj-$(CONFIG_KVM_ARM_HOST) += hyp-entry.o | 17 | obj-$(CONFIG_KVM_ARM_HOST) += hyp-entry.o |
18 | obj-$(CONFIG_KVM_ARM_HOST) += s2-setup.o | 18 | obj-$(CONFIG_KVM_ARM_HOST) += s2-setup.o |
19 | 19 | ||
20 | # KVM code is run at a different exception code with a different map, so | ||
21 | # compiler instrumentation that inserts callbacks or checks into the code may | ||
22 | # cause crashes. Just disable it. | ||
20 | GCOV_PROFILE := n | 23 | GCOV_PROFILE := n |
21 | KASAN_SANITIZE := n | 24 | KASAN_SANITIZE := n |
22 | UBSAN_SANITIZE := n | 25 | UBSAN_SANITIZE := n |
26 | KCOV_INSTRUMENT := n | ||
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index 437cfad5e3d8..4373997d1a70 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c | |||
@@ -198,7 +198,7 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar) | |||
198 | static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu) | 198 | static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu) |
199 | { | 199 | { |
200 | u64 esr = read_sysreg_el2(esr); | 200 | u64 esr = read_sysreg_el2(esr); |
201 | u8 ec = esr >> ESR_ELx_EC_SHIFT; | 201 | u8 ec = ESR_ELx_EC(esr); |
202 | u64 hpfar, far; | 202 | u64 hpfar, far; |
203 | 203 | ||
204 | vcpu->arch.fault.esr_el2 = esr; | 204 | vcpu->arch.fault.esr_el2 = esr; |
diff --git a/arch/arm64/lib/copy_from_user.S b/arch/arm64/lib/copy_from_user.S index 17e8306dca29..0b90497d4424 100644 --- a/arch/arm64/lib/copy_from_user.S +++ b/arch/arm64/lib/copy_from_user.S | |||
@@ -66,7 +66,7 @@ | |||
66 | .endm | 66 | .endm |
67 | 67 | ||
68 | end .req x5 | 68 | end .req x5 |
69 | ENTRY(__copy_from_user) | 69 | ENTRY(__arch_copy_from_user) |
70 | ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \ | 70 | ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \ |
71 | CONFIG_ARM64_PAN) | 71 | CONFIG_ARM64_PAN) |
72 | add end, x0, x2 | 72 | add end, x0, x2 |
@@ -75,7 +75,7 @@ ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \ | |||
75 | CONFIG_ARM64_PAN) | 75 | CONFIG_ARM64_PAN) |
76 | mov x0, #0 // Nothing to copy | 76 | mov x0, #0 // Nothing to copy |
77 | ret | 77 | ret |
78 | ENDPROC(__copy_from_user) | 78 | ENDPROC(__arch_copy_from_user) |
79 | 79 | ||
80 | .section .fixup,"ax" | 80 | .section .fixup,"ax" |
81 | .align 2 | 81 | .align 2 |
diff --git a/arch/arm64/lib/copy_to_user.S b/arch/arm64/lib/copy_to_user.S index 21faae60f988..7a7efe255034 100644 --- a/arch/arm64/lib/copy_to_user.S +++ b/arch/arm64/lib/copy_to_user.S | |||
@@ -65,7 +65,7 @@ | |||
65 | .endm | 65 | .endm |
66 | 66 | ||
67 | end .req x5 | 67 | end .req x5 |
68 | ENTRY(__copy_to_user) | 68 | ENTRY(__arch_copy_to_user) |
69 | ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \ | 69 | ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \ |
70 | CONFIG_ARM64_PAN) | 70 | CONFIG_ARM64_PAN) |
71 | add end, x0, x2 | 71 | add end, x0, x2 |
@@ -74,7 +74,7 @@ ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \ | |||
74 | CONFIG_ARM64_PAN) | 74 | CONFIG_ARM64_PAN) |
75 | mov x0, #0 | 75 | mov x0, #0 |
76 | ret | 76 | ret |
77 | ENDPROC(__copy_to_user) | 77 | ENDPROC(__arch_copy_to_user) |
78 | 78 | ||
79 | .section .fixup,"ax" | 79 | .section .fixup,"ax" |
80 | .align 2 | 80 | .align 2 |
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S index 50ff9ba3a236..07d7352d7c38 100644 --- a/arch/arm64/mm/cache.S +++ b/arch/arm64/mm/cache.S | |||
@@ -52,7 +52,7 @@ ENTRY(__flush_cache_user_range) | |||
52 | sub x3, x2, #1 | 52 | sub x3, x2, #1 |
53 | bic x4, x0, x3 | 53 | bic x4, x0, x3 |
54 | 1: | 54 | 1: |
55 | USER(9f, dc cvau, x4 ) // clean D line to PoU | 55 | user_alt 9f, "dc cvau, x4", "dc civac, x4", ARM64_WORKAROUND_CLEAN_CACHE |
56 | add x4, x4, x2 | 56 | add x4, x4, x2 |
57 | cmp x4, x1 | 57 | cmp x4, x1 |
58 | b.lo 1b | 58 | b.lo 1b |
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index c566ec83719f..f6c55afab3e2 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/gfp.h> | 20 | #include <linux/gfp.h> |
21 | #include <linux/acpi.h> | 21 | #include <linux/acpi.h> |
22 | #include <linux/bootmem.h> | ||
22 | #include <linux/export.h> | 23 | #include <linux/export.h> |
23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
24 | #include <linux/genalloc.h> | 25 | #include <linux/genalloc.h> |
@@ -29,6 +30,8 @@ | |||
29 | 30 | ||
30 | #include <asm/cacheflush.h> | 31 | #include <asm/cacheflush.h> |
31 | 32 | ||
33 | static int swiotlb __read_mostly; | ||
34 | |||
32 | static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot, | 35 | static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot, |
33 | bool coherent) | 36 | bool coherent) |
34 | { | 37 | { |
@@ -341,6 +344,13 @@ static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt, | |||
341 | return ret; | 344 | return ret; |
342 | } | 345 | } |
343 | 346 | ||
347 | static int __swiotlb_dma_supported(struct device *hwdev, u64 mask) | ||
348 | { | ||
349 | if (swiotlb) | ||
350 | return swiotlb_dma_supported(hwdev, mask); | ||
351 | return 1; | ||
352 | } | ||
353 | |||
344 | static struct dma_map_ops swiotlb_dma_ops = { | 354 | static struct dma_map_ops swiotlb_dma_ops = { |
345 | .alloc = __dma_alloc, | 355 | .alloc = __dma_alloc, |
346 | .free = __dma_free, | 356 | .free = __dma_free, |
@@ -354,7 +364,7 @@ static struct dma_map_ops swiotlb_dma_ops = { | |||
354 | .sync_single_for_device = __swiotlb_sync_single_for_device, | 364 | .sync_single_for_device = __swiotlb_sync_single_for_device, |
355 | .sync_sg_for_cpu = __swiotlb_sync_sg_for_cpu, | 365 | .sync_sg_for_cpu = __swiotlb_sync_sg_for_cpu, |
356 | .sync_sg_for_device = __swiotlb_sync_sg_for_device, | 366 | .sync_sg_for_device = __swiotlb_sync_sg_for_device, |
357 | .dma_supported = swiotlb_dma_supported, | 367 | .dma_supported = __swiotlb_dma_supported, |
358 | .mapping_error = swiotlb_dma_mapping_error, | 368 | .mapping_error = swiotlb_dma_mapping_error, |
359 | }; | 369 | }; |
360 | 370 | ||
@@ -513,6 +523,9 @@ EXPORT_SYMBOL(dummy_dma_ops); | |||
513 | 523 | ||
514 | static int __init arm64_dma_init(void) | 524 | static int __init arm64_dma_init(void) |
515 | { | 525 | { |
526 | if (swiotlb_force || max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) | ||
527 | swiotlb = 1; | ||
528 | |||
516 | return atomic_pool_init(); | 529 | return atomic_pool_init(); |
517 | } | 530 | } |
518 | arch_initcall(arm64_dma_init); | 531 | arch_initcall(arm64_dma_init); |
@@ -848,15 +861,16 @@ static int __iommu_attach_notifier(struct notifier_block *nb, | |||
848 | { | 861 | { |
849 | struct iommu_dma_notifier_data *master, *tmp; | 862 | struct iommu_dma_notifier_data *master, *tmp; |
850 | 863 | ||
851 | if (action != BUS_NOTIFY_ADD_DEVICE) | 864 | if (action != BUS_NOTIFY_BIND_DRIVER) |
852 | return 0; | 865 | return 0; |
853 | 866 | ||
854 | mutex_lock(&iommu_dma_notifier_lock); | 867 | mutex_lock(&iommu_dma_notifier_lock); |
855 | list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) { | 868 | list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) { |
856 | if (do_iommu_attach(master->dev, master->ops, | 869 | if (data == master->dev && do_iommu_attach(master->dev, |
857 | master->dma_base, master->size)) { | 870 | master->ops, master->dma_base, master->size)) { |
858 | list_del(&master->list); | 871 | list_del(&master->list); |
859 | kfree(master); | 872 | kfree(master); |
873 | break; | ||
860 | } | 874 | } |
861 | } | 875 | } |
862 | mutex_unlock(&iommu_dma_notifier_lock); | 876 | mutex_unlock(&iommu_dma_notifier_lock); |
@@ -870,17 +884,8 @@ static int __init register_iommu_dma_ops_notifier(struct bus_type *bus) | |||
870 | 884 | ||
871 | if (!nb) | 885 | if (!nb) |
872 | return -ENOMEM; | 886 | return -ENOMEM; |
873 | /* | 887 | |
874 | * The device must be attached to a domain before the driver probe | ||
875 | * routine gets a chance to start allocating DMA buffers. However, | ||
876 | * the IOMMU driver also needs a chance to configure the iommu_group | ||
877 | * via its add_device callback first, so we need to make the attach | ||
878 | * happen between those two points. Since the IOMMU core uses a bus | ||
879 | * notifier with default priority for add_device, do the same but | ||
880 | * with a lower priority to ensure the appropriate ordering. | ||
881 | */ | ||
882 | nb->notifier_call = __iommu_attach_notifier; | 888 | nb->notifier_call = __iommu_attach_notifier; |
883 | nb->priority = -100; | ||
884 | 889 | ||
885 | ret = bus_register_notifier(bus, nb); | 890 | ret = bus_register_notifier(bus, nb); |
886 | if (ret) { | 891 | if (ret) { |
@@ -904,10 +909,6 @@ static int __init __iommu_dma_init(void) | |||
904 | if (!ret) | 909 | if (!ret) |
905 | ret = register_iommu_dma_ops_notifier(&pci_bus_type); | 910 | ret = register_iommu_dma_ops_notifier(&pci_bus_type); |
906 | #endif | 911 | #endif |
907 | |||
908 | /* handle devices queued before this arch_initcall */ | ||
909 | if (!ret) | ||
910 | __iommu_attach_notifier(NULL, BUS_NOTIFY_ADD_DEVICE, NULL); | ||
911 | return ret; | 912 | return ret; |
912 | } | 913 | } |
913 | arch_initcall(__iommu_dma_init); | 914 | arch_initcall(__iommu_dma_init); |
diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c index ccfde237d6e6..f94b80eb295d 100644 --- a/arch/arm64/mm/dump.c +++ b/arch/arm64/mm/dump.c | |||
@@ -27,11 +27,7 @@ | |||
27 | #include <asm/memory.h> | 27 | #include <asm/memory.h> |
28 | #include <asm/pgtable.h> | 28 | #include <asm/pgtable.h> |
29 | #include <asm/pgtable-hwdef.h> | 29 | #include <asm/pgtable-hwdef.h> |
30 | 30 | #include <asm/ptdump.h> | |
31 | struct addr_marker { | ||
32 | unsigned long start_address; | ||
33 | const char *name; | ||
34 | }; | ||
35 | 31 | ||
36 | static const struct addr_marker address_markers[] = { | 32 | static const struct addr_marker address_markers[] = { |
37 | #ifdef CONFIG_KASAN | 33 | #ifdef CONFIG_KASAN |
@@ -290,7 +286,8 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start) | |||
290 | } | 286 | } |
291 | } | 287 | } |
292 | 288 | ||
293 | static void walk_pgd(struct pg_state *st, struct mm_struct *mm, unsigned long start) | 289 | static void walk_pgd(struct pg_state *st, struct mm_struct *mm, |
290 | unsigned long start) | ||
294 | { | 291 | { |
295 | pgd_t *pgd = pgd_offset(mm, 0UL); | 292 | pgd_t *pgd = pgd_offset(mm, 0UL); |
296 | unsigned i; | 293 | unsigned i; |
@@ -309,12 +306,13 @@ static void walk_pgd(struct pg_state *st, struct mm_struct *mm, unsigned long st | |||
309 | 306 | ||
310 | static int ptdump_show(struct seq_file *m, void *v) | 307 | static int ptdump_show(struct seq_file *m, void *v) |
311 | { | 308 | { |
309 | struct ptdump_info *info = m->private; | ||
312 | struct pg_state st = { | 310 | struct pg_state st = { |
313 | .seq = m, | 311 | .seq = m, |
314 | .marker = address_markers, | 312 | .marker = info->markers, |
315 | }; | 313 | }; |
316 | 314 | ||
317 | walk_pgd(&st, &init_mm, VA_START); | 315 | walk_pgd(&st, info->mm, info->base_addr); |
318 | 316 | ||
319 | note_page(&st, 0, 0, 0); | 317 | note_page(&st, 0, 0, 0); |
320 | return 0; | 318 | return 0; |
@@ -322,7 +320,7 @@ static int ptdump_show(struct seq_file *m, void *v) | |||
322 | 320 | ||
323 | static int ptdump_open(struct inode *inode, struct file *file) | 321 | static int ptdump_open(struct inode *inode, struct file *file) |
324 | { | 322 | { |
325 | return single_open(file, ptdump_show, NULL); | 323 | return single_open(file, ptdump_show, inode->i_private); |
326 | } | 324 | } |
327 | 325 | ||
328 | static const struct file_operations ptdump_fops = { | 326 | static const struct file_operations ptdump_fops = { |
@@ -332,7 +330,7 @@ static const struct file_operations ptdump_fops = { | |||
332 | .release = single_release, | 330 | .release = single_release, |
333 | }; | 331 | }; |
334 | 332 | ||
335 | static int ptdump_init(void) | 333 | int ptdump_register(struct ptdump_info *info, const char *name) |
336 | { | 334 | { |
337 | struct dentry *pe; | 335 | struct dentry *pe; |
338 | unsigned i, j; | 336 | unsigned i, j; |
@@ -342,8 +340,18 @@ static int ptdump_init(void) | |||
342 | for (j = 0; j < pg_level[i].num; j++) | 340 | for (j = 0; j < pg_level[i].num; j++) |
343 | pg_level[i].mask |= pg_level[i].bits[j].mask; | 341 | pg_level[i].mask |= pg_level[i].bits[j].mask; |
344 | 342 | ||
345 | pe = debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, | 343 | pe = debugfs_create_file(name, 0400, NULL, info, &ptdump_fops); |
346 | &ptdump_fops); | ||
347 | return pe ? 0 : -ENOMEM; | 344 | return pe ? 0 : -ENOMEM; |
348 | } | 345 | } |
346 | |||
347 | static struct ptdump_info kernel_ptdump_info = { | ||
348 | .mm = &init_mm, | ||
349 | .markers = address_markers, | ||
350 | .base_addr = VA_START, | ||
351 | }; | ||
352 | |||
353 | static int ptdump_init(void) | ||
354 | { | ||
355 | return ptdump_register(&kernel_ptdump_info, "kernel_page_tables"); | ||
356 | } | ||
349 | device_initcall(ptdump_init); | 357 | device_initcall(ptdump_init); |
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 031820d989a8..c8beaa0da7df 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c | |||
@@ -41,6 +41,28 @@ | |||
41 | 41 | ||
42 | static const char *fault_name(unsigned int esr); | 42 | static const char *fault_name(unsigned int esr); |
43 | 43 | ||
44 | #ifdef CONFIG_KPROBES | ||
45 | static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr) | ||
46 | { | ||
47 | int ret = 0; | ||
48 | |||
49 | /* kprobe_running() needs smp_processor_id() */ | ||
50 | if (!user_mode(regs)) { | ||
51 | preempt_disable(); | ||
52 | if (kprobe_running() && kprobe_fault_handler(regs, esr)) | ||
53 | ret = 1; | ||
54 | preempt_enable(); | ||
55 | } | ||
56 | |||
57 | return ret; | ||
58 | } | ||
59 | #else | ||
60 | static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr) | ||
61 | { | ||
62 | return 0; | ||
63 | } | ||
64 | #endif | ||
65 | |||
44 | /* | 66 | /* |
45 | * Dump out the page tables associated with 'addr' in mm 'mm'. | 67 | * Dump out the page tables associated with 'addr' in mm 'mm'. |
46 | */ | 68 | */ |
@@ -202,8 +224,6 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re | |||
202 | #define VM_FAULT_BADMAP 0x010000 | 224 | #define VM_FAULT_BADMAP 0x010000 |
203 | #define VM_FAULT_BADACCESS 0x020000 | 225 | #define VM_FAULT_BADACCESS 0x020000 |
204 | 226 | ||
205 | #define ESR_LNX_EXEC (1 << 24) | ||
206 | |||
207 | static int __do_page_fault(struct mm_struct *mm, unsigned long addr, | 227 | static int __do_page_fault(struct mm_struct *mm, unsigned long addr, |
208 | unsigned int mm_flags, unsigned long vm_flags, | 228 | unsigned int mm_flags, unsigned long vm_flags, |
209 | struct task_struct *tsk) | 229 | struct task_struct *tsk) |
@@ -242,14 +262,19 @@ out: | |||
242 | return fault; | 262 | return fault; |
243 | } | 263 | } |
244 | 264 | ||
245 | static inline int permission_fault(unsigned int esr) | 265 | static inline bool is_permission_fault(unsigned int esr) |
246 | { | 266 | { |
247 | unsigned int ec = (esr & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT; | 267 | unsigned int ec = ESR_ELx_EC(esr); |
248 | unsigned int fsc_type = esr & ESR_ELx_FSC_TYPE; | 268 | unsigned int fsc_type = esr & ESR_ELx_FSC_TYPE; |
249 | 269 | ||
250 | return (ec == ESR_ELx_EC_DABT_CUR && fsc_type == ESR_ELx_FSC_PERM); | 270 | return (ec == ESR_ELx_EC_DABT_CUR && fsc_type == ESR_ELx_FSC_PERM); |
251 | } | 271 | } |
252 | 272 | ||
273 | static bool is_el0_instruction_abort(unsigned int esr) | ||
274 | { | ||
275 | return ESR_ELx_EC(esr) == ESR_ELx_EC_IABT_LOW; | ||
276 | } | ||
277 | |||
253 | static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, | 278 | static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, |
254 | struct pt_regs *regs) | 279 | struct pt_regs *regs) |
255 | { | 280 | { |
@@ -259,6 +284,9 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, | |||
259 | unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC; | 284 | unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC; |
260 | unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | 285 | unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
261 | 286 | ||
287 | if (notify_page_fault(regs, esr)) | ||
288 | return 0; | ||
289 | |||
262 | tsk = current; | 290 | tsk = current; |
263 | mm = tsk->mm; | 291 | mm = tsk->mm; |
264 | 292 | ||
@@ -272,14 +300,14 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, | |||
272 | if (user_mode(regs)) | 300 | if (user_mode(regs)) |
273 | mm_flags |= FAULT_FLAG_USER; | 301 | mm_flags |= FAULT_FLAG_USER; |
274 | 302 | ||
275 | if (esr & ESR_LNX_EXEC) { | 303 | if (is_el0_instruction_abort(esr)) { |
276 | vm_flags = VM_EXEC; | 304 | vm_flags = VM_EXEC; |
277 | } else if ((esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM)) { | 305 | } else if ((esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM)) { |
278 | vm_flags = VM_WRITE; | 306 | vm_flags = VM_WRITE; |
279 | mm_flags |= FAULT_FLAG_WRITE; | 307 | mm_flags |= FAULT_FLAG_WRITE; |
280 | } | 308 | } |
281 | 309 | ||
282 | if (permission_fault(esr) && (addr < USER_DS)) { | 310 | if (is_permission_fault(esr) && (addr < USER_DS)) { |
283 | /* regs->orig_addr_limit may be 0 if we entered from EL0 */ | 311 | /* regs->orig_addr_limit may be 0 if we entered from EL0 */ |
284 | if (regs->orig_addr_limit == KERNEL_DS) | 312 | if (regs->orig_addr_limit == KERNEL_DS) |
285 | die("Accessing user space memory with fs=KERNEL_DS", regs, esr); | 313 | die("Accessing user space memory with fs=KERNEL_DS", regs, esr); |
@@ -630,6 +658,7 @@ asmlinkage int __exception do_debug_exception(unsigned long addr, | |||
630 | 658 | ||
631 | return rv; | 659 | return rv; |
632 | } | 660 | } |
661 | NOKPROBE_SYMBOL(do_debug_exception); | ||
633 | 662 | ||
634 | #ifdef CONFIG_ARM64_PAN | 663 | #ifdef CONFIG_ARM64_PAN |
635 | void cpu_enable_pan(void *__unused) | 664 | void cpu_enable_pan(void *__unused) |
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index d45f8627012c..2ade7a6a10a7 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c | |||
@@ -160,12 +160,10 @@ static void __init arm64_memory_present(void) | |||
160 | static void __init arm64_memory_present(void) | 160 | static void __init arm64_memory_present(void) |
161 | { | 161 | { |
162 | struct memblock_region *reg; | 162 | struct memblock_region *reg; |
163 | int nid = 0; | ||
164 | 163 | ||
165 | for_each_memblock(memory, reg) { | 164 | for_each_memblock(memory, reg) { |
166 | #ifdef CONFIG_NUMA | 165 | int nid = memblock_get_region_node(reg); |
167 | nid = reg->nid; | 166 | |
168 | #endif | ||
169 | memory_present(nid, memblock_region_memory_base_pfn(reg), | 167 | memory_present(nid, memblock_region_memory_base_pfn(reg), |
170 | memblock_region_memory_end_pfn(reg)); | 168 | memblock_region_memory_end_pfn(reg)); |
171 | } | 169 | } |
@@ -403,7 +401,8 @@ static void __init free_unused_memmap(void) | |||
403 | */ | 401 | */ |
404 | void __init mem_init(void) | 402 | void __init mem_init(void) |
405 | { | 403 | { |
406 | swiotlb_init(1); | 404 | if (swiotlb_force || max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) |
405 | swiotlb_init(1); | ||
407 | 406 | ||
408 | set_max_mapnr(pfn_to_page(max_pfn) - mem_map); | 407 | set_max_mapnr(pfn_to_page(max_pfn) - mem_map); |
409 | 408 | ||
@@ -430,9 +429,9 @@ void __init mem_init(void) | |||
430 | pr_cont(" vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n", | 429 | pr_cont(" vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n", |
431 | MLG(VMALLOC_START, VMALLOC_END)); | 430 | MLG(VMALLOC_START, VMALLOC_END)); |
432 | pr_cont(" .text : 0x%p" " - 0x%p" " (%6ld KB)\n", | 431 | pr_cont(" .text : 0x%p" " - 0x%p" " (%6ld KB)\n", |
433 | MLK_ROUNDUP(_text, __start_rodata)); | 432 | MLK_ROUNDUP(_text, _etext)); |
434 | pr_cont(" .rodata : 0x%p" " - 0x%p" " (%6ld KB)\n", | 433 | pr_cont(" .rodata : 0x%p" " - 0x%p" " (%6ld KB)\n", |
435 | MLK_ROUNDUP(__start_rodata, _etext)); | 434 | MLK_ROUNDUP(__start_rodata, __init_begin)); |
436 | pr_cont(" .init : 0x%p" " - 0x%p" " (%6ld KB)\n", | 435 | pr_cont(" .init : 0x%p" " - 0x%p" " (%6ld KB)\n", |
437 | MLK_ROUNDUP(__init_begin, __init_end)); | 436 | MLK_ROUNDUP(__init_begin, __init_end)); |
438 | pr_cont(" .data : 0x%p" " - 0x%p" " (%6ld KB)\n", | 437 | pr_cont(" .data : 0x%p" " - 0x%p" " (%6ld KB)\n", |
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 0f85a46c3e18..51a558195bb9 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
@@ -77,7 +77,6 @@ static phys_addr_t __init early_pgtable_alloc(void) | |||
77 | void *ptr; | 77 | void *ptr; |
78 | 78 | ||
79 | phys = memblock_alloc(PAGE_SIZE, PAGE_SIZE); | 79 | phys = memblock_alloc(PAGE_SIZE, PAGE_SIZE); |
80 | BUG_ON(!phys); | ||
81 | 80 | ||
82 | /* | 81 | /* |
83 | * The FIX_{PGD,PUD,PMD} slots may be in active use, but the FIX_PTE | 82 | * The FIX_{PGD,PUD,PMD} slots may be in active use, but the FIX_PTE |
@@ -97,24 +96,6 @@ static phys_addr_t __init early_pgtable_alloc(void) | |||
97 | return phys; | 96 | return phys; |
98 | } | 97 | } |
99 | 98 | ||
100 | /* | ||
101 | * remap a PMD into pages | ||
102 | */ | ||
103 | static void split_pmd(pmd_t *pmd, pte_t *pte) | ||
104 | { | ||
105 | unsigned long pfn = pmd_pfn(*pmd); | ||
106 | int i = 0; | ||
107 | |||
108 | do { | ||
109 | /* | ||
110 | * Need to have the least restrictive permissions available | ||
111 | * permissions will be fixed up later | ||
112 | */ | ||
113 | set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); | ||
114 | pfn++; | ||
115 | } while (pte++, i++, i < PTRS_PER_PTE); | ||
116 | } | ||
117 | |||
118 | static void alloc_init_pte(pmd_t *pmd, unsigned long addr, | 99 | static void alloc_init_pte(pmd_t *pmd, unsigned long addr, |
119 | unsigned long end, unsigned long pfn, | 100 | unsigned long end, unsigned long pfn, |
120 | pgprot_t prot, | 101 | pgprot_t prot, |
@@ -122,15 +103,13 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr, | |||
122 | { | 103 | { |
123 | pte_t *pte; | 104 | pte_t *pte; |
124 | 105 | ||
125 | if (pmd_none(*pmd) || pmd_sect(*pmd)) { | 106 | BUG_ON(pmd_sect(*pmd)); |
107 | if (pmd_none(*pmd)) { | ||
126 | phys_addr_t pte_phys; | 108 | phys_addr_t pte_phys; |
127 | BUG_ON(!pgtable_alloc); | 109 | BUG_ON(!pgtable_alloc); |
128 | pte_phys = pgtable_alloc(); | 110 | pte_phys = pgtable_alloc(); |
129 | pte = pte_set_fixmap(pte_phys); | 111 | pte = pte_set_fixmap(pte_phys); |
130 | if (pmd_sect(*pmd)) | ||
131 | split_pmd(pmd, pte); | ||
132 | __pmd_populate(pmd, pte_phys, PMD_TYPE_TABLE); | 112 | __pmd_populate(pmd, pte_phys, PMD_TYPE_TABLE); |
133 | flush_tlb_all(); | ||
134 | pte_clear_fixmap(); | 113 | pte_clear_fixmap(); |
135 | } | 114 | } |
136 | BUG_ON(pmd_bad(*pmd)); | 115 | BUG_ON(pmd_bad(*pmd)); |
@@ -144,41 +123,10 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr, | |||
144 | pte_clear_fixmap(); | 123 | pte_clear_fixmap(); |
145 | } | 124 | } |
146 | 125 | ||
147 | static void split_pud(pud_t *old_pud, pmd_t *pmd) | ||
148 | { | ||
149 | unsigned long addr = pud_pfn(*old_pud) << PAGE_SHIFT; | ||
150 | pgprot_t prot = __pgprot(pud_val(*old_pud) ^ addr); | ||
151 | int i = 0; | ||
152 | |||
153 | do { | ||
154 | set_pmd(pmd, __pmd(addr | pgprot_val(prot))); | ||
155 | addr += PMD_SIZE; | ||
156 | } while (pmd++, i++, i < PTRS_PER_PMD); | ||
157 | } | ||
158 | |||
159 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
160 | static bool block_mappings_allowed(phys_addr_t (*pgtable_alloc)(void)) | ||
161 | { | ||
162 | |||
163 | /* | ||
164 | * If debug_page_alloc is enabled we must map the linear map | ||
165 | * using pages. However, other mappings created by | ||
166 | * create_mapping_noalloc must use sections in some cases. Allow | ||
167 | * sections to be used in those cases, where no pgtable_alloc | ||
168 | * function is provided. | ||
169 | */ | ||
170 | return !pgtable_alloc || !debug_pagealloc_enabled(); | ||
171 | } | ||
172 | #else | ||
173 | static bool block_mappings_allowed(phys_addr_t (*pgtable_alloc)(void)) | ||
174 | { | ||
175 | return true; | ||
176 | } | ||
177 | #endif | ||
178 | |||
179 | static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end, | 126 | static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end, |
180 | phys_addr_t phys, pgprot_t prot, | 127 | phys_addr_t phys, pgprot_t prot, |
181 | phys_addr_t (*pgtable_alloc)(void)) | 128 | phys_addr_t (*pgtable_alloc)(void), |
129 | bool allow_block_mappings) | ||
182 | { | 130 | { |
183 | pmd_t *pmd; | 131 | pmd_t *pmd; |
184 | unsigned long next; | 132 | unsigned long next; |
@@ -186,20 +134,13 @@ static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end, | |||
186 | /* | 134 | /* |
187 | * Check for initial section mappings in the pgd/pud and remove them. | 135 | * Check for initial section mappings in the pgd/pud and remove them. |
188 | */ | 136 | */ |
189 | if (pud_none(*pud) || pud_sect(*pud)) { | 137 | BUG_ON(pud_sect(*pud)); |
138 | if (pud_none(*pud)) { | ||
190 | phys_addr_t pmd_phys; | 139 | phys_addr_t pmd_phys; |
191 | BUG_ON(!pgtable_alloc); | 140 | BUG_ON(!pgtable_alloc); |
192 | pmd_phys = pgtable_alloc(); | 141 | pmd_phys = pgtable_alloc(); |
193 | pmd = pmd_set_fixmap(pmd_phys); | 142 | pmd = pmd_set_fixmap(pmd_phys); |
194 | if (pud_sect(*pud)) { | ||
195 | /* | ||
196 | * need to have the 1G of mappings continue to be | ||
197 | * present | ||
198 | */ | ||
199 | split_pud(pud, pmd); | ||
200 | } | ||
201 | __pud_populate(pud, pmd_phys, PUD_TYPE_TABLE); | 143 | __pud_populate(pud, pmd_phys, PUD_TYPE_TABLE); |
202 | flush_tlb_all(); | ||
203 | pmd_clear_fixmap(); | 144 | pmd_clear_fixmap(); |
204 | } | 145 | } |
205 | BUG_ON(pud_bad(*pud)); | 146 | BUG_ON(pud_bad(*pud)); |
@@ -209,7 +150,7 @@ static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end, | |||
209 | next = pmd_addr_end(addr, end); | 150 | next = pmd_addr_end(addr, end); |
210 | /* try section mapping first */ | 151 | /* try section mapping first */ |
211 | if (((addr | next | phys) & ~SECTION_MASK) == 0 && | 152 | if (((addr | next | phys) & ~SECTION_MASK) == 0 && |
212 | block_mappings_allowed(pgtable_alloc)) { | 153 | allow_block_mappings) { |
213 | pmd_t old_pmd =*pmd; | 154 | pmd_t old_pmd =*pmd; |
214 | pmd_set_huge(pmd, phys, prot); | 155 | pmd_set_huge(pmd, phys, prot); |
215 | /* | 156 | /* |
@@ -248,7 +189,8 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next, | |||
248 | 189 | ||
249 | static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, | 190 | static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, |
250 | phys_addr_t phys, pgprot_t prot, | 191 | phys_addr_t phys, pgprot_t prot, |
251 | phys_addr_t (*pgtable_alloc)(void)) | 192 | phys_addr_t (*pgtable_alloc)(void), |
193 | bool allow_block_mappings) | ||
252 | { | 194 | { |
253 | pud_t *pud; | 195 | pud_t *pud; |
254 | unsigned long next; | 196 | unsigned long next; |
@@ -268,8 +210,7 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, | |||
268 | /* | 210 | /* |
269 | * For 4K granule only, attempt to put down a 1GB block | 211 | * For 4K granule only, attempt to put down a 1GB block |
270 | */ | 212 | */ |
271 | if (use_1G_block(addr, next, phys) && | 213 | if (use_1G_block(addr, next, phys) && allow_block_mappings) { |
272 | block_mappings_allowed(pgtable_alloc)) { | ||
273 | pud_t old_pud = *pud; | 214 | pud_t old_pud = *pud; |
274 | pud_set_huge(pud, phys, prot); | 215 | pud_set_huge(pud, phys, prot); |
275 | 216 | ||
@@ -290,7 +231,7 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, | |||
290 | } | 231 | } |
291 | } else { | 232 | } else { |
292 | alloc_init_pmd(pud, addr, next, phys, prot, | 233 | alloc_init_pmd(pud, addr, next, phys, prot, |
293 | pgtable_alloc); | 234 | pgtable_alloc, allow_block_mappings); |
294 | } | 235 | } |
295 | phys += next - addr; | 236 | phys += next - addr; |
296 | } while (pud++, addr = next, addr != end); | 237 | } while (pud++, addr = next, addr != end); |
@@ -298,15 +239,14 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, | |||
298 | pud_clear_fixmap(); | 239 | pud_clear_fixmap(); |
299 | } | 240 | } |
300 | 241 | ||
301 | /* | 242 | static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, |
302 | * Create the page directory entries and any necessary page tables for the | 243 | unsigned long virt, phys_addr_t size, |
303 | * mapping specified by 'md'. | 244 | pgprot_t prot, |
304 | */ | 245 | phys_addr_t (*pgtable_alloc)(void), |
305 | static void init_pgd(pgd_t *pgd, phys_addr_t phys, unsigned long virt, | 246 | bool allow_block_mappings) |
306 | phys_addr_t size, pgprot_t prot, | ||
307 | phys_addr_t (*pgtable_alloc)(void)) | ||
308 | { | 247 | { |
309 | unsigned long addr, length, end, next; | 248 | unsigned long addr, length, end, next; |
249 | pgd_t *pgd = pgd_offset_raw(pgdir, virt); | ||
310 | 250 | ||
311 | /* | 251 | /* |
312 | * If the virtual and physical address don't have the same offset | 252 | * If the virtual and physical address don't have the same offset |
@@ -322,29 +262,23 @@ static void init_pgd(pgd_t *pgd, phys_addr_t phys, unsigned long virt, | |||
322 | end = addr + length; | 262 | end = addr + length; |
323 | do { | 263 | do { |
324 | next = pgd_addr_end(addr, end); | 264 | next = pgd_addr_end(addr, end); |
325 | alloc_init_pud(pgd, addr, next, phys, prot, pgtable_alloc); | 265 | alloc_init_pud(pgd, addr, next, phys, prot, pgtable_alloc, |
266 | allow_block_mappings); | ||
326 | phys += next - addr; | 267 | phys += next - addr; |
327 | } while (pgd++, addr = next, addr != end); | 268 | } while (pgd++, addr = next, addr != end); |
328 | } | 269 | } |
329 | 270 | ||
330 | static phys_addr_t late_pgtable_alloc(void) | 271 | static phys_addr_t pgd_pgtable_alloc(void) |
331 | { | 272 | { |
332 | void *ptr = (void *)__get_free_page(PGALLOC_GFP); | 273 | void *ptr = (void *)__get_free_page(PGALLOC_GFP); |
333 | BUG_ON(!ptr); | 274 | if (!ptr || !pgtable_page_ctor(virt_to_page(ptr))) |
275 | BUG(); | ||
334 | 276 | ||
335 | /* Ensure the zeroed page is visible to the page table walker */ | 277 | /* Ensure the zeroed page is visible to the page table walker */ |
336 | dsb(ishst); | 278 | dsb(ishst); |
337 | return __pa(ptr); | 279 | return __pa(ptr); |
338 | } | 280 | } |
339 | 281 | ||
340 | static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, | ||
341 | unsigned long virt, phys_addr_t size, | ||
342 | pgprot_t prot, | ||
343 | phys_addr_t (*alloc)(void)) | ||
344 | { | ||
345 | init_pgd(pgd_offset_raw(pgdir, virt), phys, virt, size, prot, alloc); | ||
346 | } | ||
347 | |||
348 | /* | 282 | /* |
349 | * This function can only be used to modify existing table entries, | 283 | * This function can only be used to modify existing table entries, |
350 | * without allocating new levels of table. Note that this permits the | 284 | * without allocating new levels of table. Note that this permits the |
@@ -358,16 +292,17 @@ static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, | |||
358 | &phys, virt); | 292 | &phys, virt); |
359 | return; | 293 | return; |
360 | } | 294 | } |
361 | __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, | 295 | __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, true); |
362 | NULL); | ||
363 | } | 296 | } |
364 | 297 | ||
365 | void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, | 298 | void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, |
366 | unsigned long virt, phys_addr_t size, | 299 | unsigned long virt, phys_addr_t size, |
367 | pgprot_t prot) | 300 | pgprot_t prot, bool allow_block_mappings) |
368 | { | 301 | { |
302 | BUG_ON(mm == &init_mm); | ||
303 | |||
369 | __create_pgd_mapping(mm->pgd, phys, virt, size, prot, | 304 | __create_pgd_mapping(mm->pgd, phys, virt, size, prot, |
370 | late_pgtable_alloc); | 305 | pgd_pgtable_alloc, allow_block_mappings); |
371 | } | 306 | } |
372 | 307 | ||
373 | static void create_mapping_late(phys_addr_t phys, unsigned long virt, | 308 | static void create_mapping_late(phys_addr_t phys, unsigned long virt, |
@@ -380,51 +315,54 @@ static void create_mapping_late(phys_addr_t phys, unsigned long virt, | |||
380 | } | 315 | } |
381 | 316 | ||
382 | __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, | 317 | __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, |
383 | late_pgtable_alloc); | 318 | NULL, !debug_pagealloc_enabled()); |
384 | } | 319 | } |
385 | 320 | ||
386 | static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end) | 321 | static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end) |
387 | { | 322 | { |
388 | unsigned long kernel_start = __pa(_text); | 323 | unsigned long kernel_start = __pa(_text); |
389 | unsigned long kernel_end = __pa(_etext); | 324 | unsigned long kernel_end = __pa(__init_begin); |
390 | 325 | ||
391 | /* | 326 | /* |
392 | * Take care not to create a writable alias for the | 327 | * Take care not to create a writable alias for the |
393 | * read-only text and rodata sections of the kernel image. | 328 | * read-only text and rodata sections of the kernel image. |
394 | */ | 329 | */ |
395 | 330 | ||
396 | /* No overlap with the kernel text */ | 331 | /* No overlap with the kernel text/rodata */ |
397 | if (end < kernel_start || start >= kernel_end) { | 332 | if (end < kernel_start || start >= kernel_end) { |
398 | __create_pgd_mapping(pgd, start, __phys_to_virt(start), | 333 | __create_pgd_mapping(pgd, start, __phys_to_virt(start), |
399 | end - start, PAGE_KERNEL, | 334 | end - start, PAGE_KERNEL, |
400 | early_pgtable_alloc); | 335 | early_pgtable_alloc, |
336 | !debug_pagealloc_enabled()); | ||
401 | return; | 337 | return; |
402 | } | 338 | } |
403 | 339 | ||
404 | /* | 340 | /* |
405 | * This block overlaps the kernel text mapping. | 341 | * This block overlaps the kernel text/rodata mappings. |
406 | * Map the portion(s) which don't overlap. | 342 | * Map the portion(s) which don't overlap. |
407 | */ | 343 | */ |
408 | if (start < kernel_start) | 344 | if (start < kernel_start) |
409 | __create_pgd_mapping(pgd, start, | 345 | __create_pgd_mapping(pgd, start, |
410 | __phys_to_virt(start), | 346 | __phys_to_virt(start), |
411 | kernel_start - start, PAGE_KERNEL, | 347 | kernel_start - start, PAGE_KERNEL, |
412 | early_pgtable_alloc); | 348 | early_pgtable_alloc, |
349 | !debug_pagealloc_enabled()); | ||
413 | if (kernel_end < end) | 350 | if (kernel_end < end) |
414 | __create_pgd_mapping(pgd, kernel_end, | 351 | __create_pgd_mapping(pgd, kernel_end, |
415 | __phys_to_virt(kernel_end), | 352 | __phys_to_virt(kernel_end), |
416 | end - kernel_end, PAGE_KERNEL, | 353 | end - kernel_end, PAGE_KERNEL, |
417 | early_pgtable_alloc); | 354 | early_pgtable_alloc, |
355 | !debug_pagealloc_enabled()); | ||
418 | 356 | ||
419 | /* | 357 | /* |
420 | * Map the linear alias of the [_text, _etext) interval as | 358 | * Map the linear alias of the [_text, __init_begin) interval as |
421 | * read-only/non-executable. This makes the contents of the | 359 | * read-only/non-executable. This makes the contents of the |
422 | * region accessible to subsystems such as hibernate, but | 360 | * region accessible to subsystems such as hibernate, but |
423 | * protects it from inadvertent modification or execution. | 361 | * protects it from inadvertent modification or execution. |
424 | */ | 362 | */ |
425 | __create_pgd_mapping(pgd, kernel_start, __phys_to_virt(kernel_start), | 363 | __create_pgd_mapping(pgd, kernel_start, __phys_to_virt(kernel_start), |
426 | kernel_end - kernel_start, PAGE_KERNEL_RO, | 364 | kernel_end - kernel_start, PAGE_KERNEL_RO, |
427 | early_pgtable_alloc); | 365 | early_pgtable_alloc, !debug_pagealloc_enabled()); |
428 | } | 366 | } |
429 | 367 | ||
430 | static void __init map_mem(pgd_t *pgd) | 368 | static void __init map_mem(pgd_t *pgd) |
@@ -449,14 +387,14 @@ void mark_rodata_ro(void) | |||
449 | { | 387 | { |
450 | unsigned long section_size; | 388 | unsigned long section_size; |
451 | 389 | ||
452 | section_size = (unsigned long)__start_rodata - (unsigned long)_text; | 390 | section_size = (unsigned long)_etext - (unsigned long)_text; |
453 | create_mapping_late(__pa(_text), (unsigned long)_text, | 391 | create_mapping_late(__pa(_text), (unsigned long)_text, |
454 | section_size, PAGE_KERNEL_ROX); | 392 | section_size, PAGE_KERNEL_ROX); |
455 | /* | 393 | /* |
456 | * mark .rodata as read only. Use _etext rather than __end_rodata to | 394 | * mark .rodata as read only. Use __init_begin rather than __end_rodata |
457 | * cover NOTES and EXCEPTION_TABLE. | 395 | * to cover NOTES and EXCEPTION_TABLE. |
458 | */ | 396 | */ |
459 | section_size = (unsigned long)_etext - (unsigned long)__start_rodata; | 397 | section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata; |
460 | create_mapping_late(__pa(__start_rodata), (unsigned long)__start_rodata, | 398 | create_mapping_late(__pa(__start_rodata), (unsigned long)__start_rodata, |
461 | section_size, PAGE_KERNEL_RO); | 399 | section_size, PAGE_KERNEL_RO); |
462 | } | 400 | } |
@@ -481,7 +419,7 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end, | |||
481 | BUG_ON(!PAGE_ALIGNED(size)); | 419 | BUG_ON(!PAGE_ALIGNED(size)); |
482 | 420 | ||
483 | __create_pgd_mapping(pgd, pa_start, (unsigned long)va_start, size, prot, | 421 | __create_pgd_mapping(pgd, pa_start, (unsigned long)va_start, size, prot, |
484 | early_pgtable_alloc); | 422 | early_pgtable_alloc, !debug_pagealloc_enabled()); |
485 | 423 | ||
486 | vma->addr = va_start; | 424 | vma->addr = va_start; |
487 | vma->phys_addr = pa_start; | 425 | vma->phys_addr = pa_start; |
@@ -499,8 +437,8 @@ static void __init map_kernel(pgd_t *pgd) | |||
499 | { | 437 | { |
500 | static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init, vmlinux_data; | 438 | static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init, vmlinux_data; |
501 | 439 | ||
502 | map_kernel_segment(pgd, _text, __start_rodata, PAGE_KERNEL_EXEC, &vmlinux_text); | 440 | map_kernel_segment(pgd, _text, _etext, PAGE_KERNEL_EXEC, &vmlinux_text); |
503 | map_kernel_segment(pgd, __start_rodata, _etext, PAGE_KERNEL, &vmlinux_rodata); | 441 | map_kernel_segment(pgd, __start_rodata, __init_begin, PAGE_KERNEL, &vmlinux_rodata); |
504 | map_kernel_segment(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC, | 442 | map_kernel_segment(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC, |
505 | &vmlinux_init); | 443 | &vmlinux_init); |
506 | map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data); | 444 | map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data); |
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index c4317879b938..5bb61de23201 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S | |||
@@ -180,6 +180,8 @@ ENTRY(__cpu_setup) | |||
180 | msr cpacr_el1, x0 // Enable FP/ASIMD | 180 | msr cpacr_el1, x0 // Enable FP/ASIMD |
181 | mov x0, #1 << 12 // Reset mdscr_el1 and disable | 181 | mov x0, #1 << 12 // Reset mdscr_el1 and disable |
182 | msr mdscr_el1, x0 // access to the DCC from EL0 | 182 | msr mdscr_el1, x0 // access to the DCC from EL0 |
183 | isb // Unmask debug exceptions now, | ||
184 | enable_dbg // since this is per-cpu | ||
183 | reset_pmuserenr_el0 x0 // Disable PMU access from EL0 | 185 | reset_pmuserenr_el0 x0 // Disable PMU access from EL0 |
184 | /* | 186 | /* |
185 | * Memory region attributes for LPAE: | 187 | * Memory region attributes for LPAE: |
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 140436a046c0..8e4d7f590b06 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c | |||
@@ -603,7 +603,8 @@ static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu) | |||
603 | 603 | ||
604 | irq = platform_get_irq(pmu_device, 0); | 604 | irq = platform_get_irq(pmu_device, 0); |
605 | if (irq >= 0 && irq_is_percpu(irq)) { | 605 | if (irq >= 0 && irq_is_percpu(irq)) { |
606 | on_each_cpu(cpu_pmu_disable_percpu_irq, &irq, 1); | 606 | on_each_cpu_mask(&cpu_pmu->supported_cpus, |
607 | cpu_pmu_disable_percpu_irq, &irq, 1); | ||
607 | free_percpu_irq(irq, &hw_events->percpu_pmu); | 608 | free_percpu_irq(irq, &hw_events->percpu_pmu); |
608 | } else { | 609 | } else { |
609 | for (i = 0; i < irqs; ++i) { | 610 | for (i = 0; i < irqs; ++i) { |
@@ -645,7 +646,9 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler) | |||
645 | irq); | 646 | irq); |
646 | return err; | 647 | return err; |
647 | } | 648 | } |
648 | on_each_cpu(cpu_pmu_enable_percpu_irq, &irq, 1); | 649 | |
650 | on_each_cpu_mask(&cpu_pmu->supported_cpus, | ||
651 | cpu_pmu_enable_percpu_irq, &irq, 1); | ||
649 | } else { | 652 | } else { |
650 | for (i = 0; i < irqs; ++i) { | 653 | for (i = 0; i < irqs; ++i) { |
651 | int cpu = i; | 654 | int cpu = i; |
@@ -961,9 +964,23 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu) | |||
961 | i++; | 964 | i++; |
962 | } while (1); | 965 | } while (1); |
963 | 966 | ||
964 | /* If we didn't manage to parse anything, claim to support all CPUs */ | 967 | /* If we didn't manage to parse anything, try the interrupt affinity */ |
965 | if (cpumask_weight(&pmu->supported_cpus) == 0) | 968 | if (cpumask_weight(&pmu->supported_cpus) == 0) { |
966 | cpumask_setall(&pmu->supported_cpus); | 969 | if (!using_spi) { |
970 | /* If using PPIs, check the affinity of the partition */ | ||
971 | int ret, irq; | ||
972 | |||
973 | irq = platform_get_irq(pdev, 0); | ||
974 | ret = irq_get_percpu_devid_partition(irq, &pmu->supported_cpus); | ||
975 | if (ret) { | ||
976 | kfree(irqs); | ||
977 | return ret; | ||
978 | } | ||
979 | } else { | ||
980 | /* Otherwise default to all CPUs */ | ||
981 | cpumask_setall(&pmu->supported_cpus); | ||
982 | } | ||
983 | } | ||
967 | 984 | ||
968 | /* If we matched up the IRQ affinities, use them to route the SPIs */ | 985 | /* If we matched up the IRQ affinities, use them to route the SPIs */ |
969 | if (using_spi && i == pdev->num_resources) | 986 | if (using_spi && i == pdev->num_resources) |
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h index 99048e501b88..aae5ebf2022b 100644 --- a/include/uapi/linux/kexec.h +++ b/include/uapi/linux/kexec.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #define KEXEC_ARCH_SH (42 << 16) | 39 | #define KEXEC_ARCH_SH (42 << 16) |
40 | #define KEXEC_ARCH_MIPS_LE (10 << 16) | 40 | #define KEXEC_ARCH_MIPS_LE (10 << 16) |
41 | #define KEXEC_ARCH_MIPS ( 8 << 16) | 41 | #define KEXEC_ARCH_MIPS ( 8 << 16) |
42 | #define KEXEC_ARCH_AARCH64 (183 << 16) | ||
42 | 43 | ||
43 | /* The artificial cap on the number of segments passed to kexec_load. */ | 44 | /* The artificial cap on the number of segments passed to kexec_load. */ |
44 | #define KEXEC_SEGMENT_MAX 16 | 45 | #define KEXEC_SEGMENT_MAX 16 |
diff --git a/samples/kprobes/kprobe_example.c b/samples/kprobes/kprobe_example.c index ed0ca0c07242..f3b61b4ee09c 100644 --- a/samples/kprobes/kprobe_example.c +++ b/samples/kprobes/kprobe_example.c | |||
@@ -46,6 +46,11 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs) | |||
46 | " ex1 = 0x%lx\n", | 46 | " ex1 = 0x%lx\n", |
47 | p->symbol_name, p->addr, regs->pc, regs->ex1); | 47 | p->symbol_name, p->addr, regs->pc, regs->ex1); |
48 | #endif | 48 | #endif |
49 | #ifdef CONFIG_ARM64 | ||
50 | pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx," | ||
51 | " pstate = 0x%lx\n", | ||
52 | p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate); | ||
53 | #endif | ||
49 | 54 | ||
50 | /* A dump_stack() here will give a stack backtrace */ | 55 | /* A dump_stack() here will give a stack backtrace */ |
51 | return 0; | 56 | return 0; |
@@ -71,6 +76,10 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs, | |||
71 | printk(KERN_INFO "<%s> post_handler: p->addr = 0x%p, ex1 = 0x%lx\n", | 76 | printk(KERN_INFO "<%s> post_handler: p->addr = 0x%p, ex1 = 0x%lx\n", |
72 | p->symbol_name, p->addr, regs->ex1); | 77 | p->symbol_name, p->addr, regs->ex1); |
73 | #endif | 78 | #endif |
79 | #ifdef CONFIG_ARM64 | ||
80 | pr_info("<%s> post_handler: p->addr = 0x%p, pstate = 0x%lx\n", | ||
81 | p->symbol_name, p->addr, (long)regs->pstate); | ||
82 | #endif | ||
74 | } | 83 | } |
75 | 84 | ||
76 | /* | 85 | /* |